Skip to content

Commit c2e7ce2

Browse files
authored
Improvement to credentials handling (#1310)
- Handle setting `index-url` instead of `url` for `python_index` registries in the server version/component. - Handle setting both `host` and `url` for `composer_repository` registries. - Better logic around building extra credentials. > This is likely the last modification before we try to move to the proxy used by `dependabot-cli`.
1 parent 4364738 commit c2e7ce2

File tree

5 files changed

+77
-40
lines changed

5 files changed

+77
-40
lines changed

extension/task/IDependabotConfig.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ export interface IDependabotRegistry {
115115
* It should not have the scheme.
116116
*/
117117
'registry'?: string | null | undefined;
118-
/** The hostname for 'terraform_registry' types */
118+
/** The hostname for `terraform_registry` and `composer_repository` types */
119119
'host'?: string | null | undefined;
120120

121121
/** The username to access the registry */

extension/task/utils/parseConfigFile.ts

+30-12
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { getVariable } from 'azure-pipelines-task-lib/task';
44
import * as fs from 'fs';
55
import { load } from 'js-yaml';
66
import * as path from 'path';
7+
import { URL } from 'url';
78
import { IDependabotConfig, IDependabotRegistry, IDependabotUpdate } from '../IDependabotConfig';
89
import { convertPlaceholder } from './convertPlaceholder';
910
import { ISharedVariables } from './getSharedVariables';
@@ -266,19 +267,36 @@ function parseRegistries(config: any): Record<string, IDependabotRegistry> {
266267
throw new Error(`The value 'url' in dependency registry config '${registryConfigKey}' is missing`);
267268
}
268269
if (url) {
269-
// Some credentials do not use the 'url' property in the Ruby updater.
270-
// npm_registry and docker_registry use 'registry' which should be stripped off the scheme.
271-
// terraform_registry uses 'host' which is the hostname from the given URL.
272-
273-
if (type === 'docker_registry' || type === 'npm_registry') {
274-
parsed.registry = url.replace('https://', '').replace('http://', '');
275-
} else if (type === 'terraform_registry') {
276-
parsed.host = new URL(url).hostname;
277-
} else if (type === 'python_index') {
278-
parsed['index-url'] = url;
279-
} else {
280-
parsed.url = url;
270+
/*
271+
* Some credentials do not use the 'url' property in the Ruby updater.
272+
* The 'host' and 'registry' properties are derived from the given URL.
273+
* The 'registry' property is derived from the 'url' by stripping off the scheme.
274+
* The 'host' property is derived from the hostname of the 'url'.
275+
*
276+
* 'npm_registry' and 'docker_registry' use 'registry' only.
277+
* 'terraform_registry' uses 'host' only.
278+
* 'composer_repository' uses both 'url' and 'host'.
279+
* 'python_index' uses 'index-url' instead of 'url'.
280+
*/
281+
282+
if (URL.canParse(url)) {
283+
const parsedUrl = new URL(url);
284+
285+
const addRegistry = type === 'docker_registry' || type === 'npm_registry';
286+
if (addRegistry) parsed.registry = url.replace('https://', '').replace('http://', '');
287+
288+
const addHost = type === 'terraform_registry' || type === 'composer_repository';
289+
if (addHost) parsed.host = parsedUrl.hostname;
281290
}
291+
292+
if (type === 'python_index') parsed['index-url'] = url;
293+
294+
const skipUrl =
295+
type === 'docker_registry' ||
296+
type === 'npm_registry' ||
297+
type === 'terraform_registry' ||
298+
type === 'python_index';
299+
if (!skipUrl) parsed.url = url;
282300
}
283301
});
284302
return registries;

extension/tests/utils/parseConfigFile.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ describe('Parse registries', () => {
4646
expect(registry.url).toBe('https://repo.packagist.com/example-company/');
4747
expect(registry['index-url']).toBe(undefined);
4848
expect(registry.registry).toBe(undefined);
49-
expect(registry.host).toBe(undefined);
49+
expect(registry.host).toBe('repo.packagist.com');
5050
expect(registry.key).toBe(undefined);
5151
expect(registry.token).toBe(undefined);
5252
expect(registry.organization).toBe(undefined);

server/Tingle.Dependabot.Tests/Workflow/UpdateRunnerTests.cs

+14-2
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ public void MakeExtraCredentials_Works()
101101
Assert.Equal("composer_repository", Assert.Contains("type", credential));
102102
Assert.Equal("https://repo.packagist.com/example-company/", Assert.Contains("url", credential));
103103
Assert.DoesNotContain("registry", credential);
104-
Assert.DoesNotContain("host", credential);
104+
Assert.DoesNotContain("index-url", credential);
105+
Assert.Equal("repo.packagist.com", Assert.Contains("host", credential));
105106
Assert.DoesNotContain("key", credential);
106107
Assert.DoesNotContain("token", credential);
107108
Assert.DoesNotContain("organization", credential);
@@ -117,6 +118,7 @@ public void MakeExtraCredentials_Works()
117118
Assert.Equal("docker_registry", Assert.Contains("type", credential));
118119
Assert.DoesNotContain("url", credential);
119120
Assert.Equal("registry.hub.docker.com", Assert.Contains("registry", credential));
121+
Assert.DoesNotContain("index-url", credential);
120122
Assert.DoesNotContain("host", credential);
121123
Assert.DoesNotContain("key", credential);
122124
Assert.DoesNotContain("token", credential);
@@ -133,6 +135,7 @@ public void MakeExtraCredentials_Works()
133135
Assert.Equal("git", Assert.Contains("type", credential));
134136
Assert.Equal("https://github.com", Assert.Contains("url", credential));
135137
Assert.DoesNotContain("registry", credential);
138+
Assert.DoesNotContain("index-url", credential);
136139
Assert.DoesNotContain("host", credential);
137140
Assert.DoesNotContain("key", credential);
138141
Assert.DoesNotContain("token", credential);
@@ -149,6 +152,7 @@ public void MakeExtraCredentials_Works()
149152
Assert.Equal("hex_organization", Assert.Contains("type", credential));
150153
Assert.DoesNotContain("url", credential);
151154
Assert.DoesNotContain("registry", credential);
155+
Assert.DoesNotContain("index-url", credential);
152156
Assert.DoesNotContain("host", credential);
153157
Assert.Equal("key_1234567890", Assert.Contains("key", credential));
154158
Assert.DoesNotContain("token", credential);
@@ -165,6 +169,7 @@ public void MakeExtraCredentials_Works()
165169
Assert.Equal("hex_repository", Assert.Contains("type", credential));
166170
Assert.Equal("https://private-repo.example.com", Assert.Contains("url", credential));
167171
Assert.DoesNotContain("registry", credential);
172+
Assert.DoesNotContain("index-url", credential);
168173
Assert.DoesNotContain("host", credential);
169174
Assert.DoesNotContain("key", credential);
170175
Assert.DoesNotContain("token", credential);
@@ -181,6 +186,7 @@ public void MakeExtraCredentials_Works()
181186
Assert.Equal("maven_repository", Assert.Contains("type", credential));
182187
Assert.Equal("https://artifactory.example.com", Assert.Contains("url", credential));
183188
Assert.DoesNotContain("registry", credential);
189+
Assert.DoesNotContain("index-url", credential);
184190
Assert.DoesNotContain("host", credential);
185191
Assert.DoesNotContain("key", credential);
186192
Assert.DoesNotContain("token", credential);
@@ -197,6 +203,7 @@ public void MakeExtraCredentials_Works()
197203
Assert.Equal("npm_registry", Assert.Contains("type", credential));
198204
Assert.DoesNotContain("url", credential);
199205
Assert.Equal("npm.pkg.github.com", Assert.Contains("registry", credential));
206+
Assert.DoesNotContain("index-url", credential);
200207
Assert.DoesNotContain("host", credential);
201208
Assert.DoesNotContain("key", credential);
202209
Assert.Equal("tkn_1234567890", Assert.Contains("token", credential));
@@ -213,6 +220,7 @@ public void MakeExtraCredentials_Works()
213220
Assert.Equal("nuget_feed", Assert.Contains("type", credential));
214221
Assert.Equal("https://pkgs.dev.azure.com/contoso/_packaging/My_Feed/nuget/v3/index.json", Assert.Contains("url", credential));
215222
Assert.DoesNotContain("registry", credential);
223+
Assert.DoesNotContain("index-url", credential);
216224
Assert.DoesNotContain("host", credential);
217225
Assert.DoesNotContain("key", credential);
218226
Assert.DoesNotContain("token", credential);
@@ -227,15 +235,17 @@ public void MakeExtraCredentials_Works()
227235
// python-index
228236
credential = credentials[8];
229237
Assert.Equal("python_index", Assert.Contains("type", credential));
230-
Assert.Equal("https://pkgs.dev.azure.com/octocat/_packaging/my-feed/pypi/example", Assert.Contains("url", credential));
238+
Assert.DoesNotContain("url", credential);
231239
Assert.DoesNotContain("registry", credential);
240+
Assert.Equal("https://pkgs.dev.azure.com/octocat/_packaging/my-feed/pypi/example", Assert.Contains("index-url", credential));
232241
Assert.DoesNotContain("host", credential);
233242
Assert.DoesNotContain("key", credential);
234243
Assert.DoesNotContain("token", credential);
235244
Assert.DoesNotContain("organization", credential);
236245
Assert.DoesNotContain("repo", credential);
237246
Assert.DoesNotContain("auth-key", credential);
238247
Assert.DoesNotContain("public-key-fingerprint", credential);
248+
Assert.Equal("https://pkgs.dev.azure.com/octocat/_packaging/my-feed/pypi/example", Assert.Contains("index-url", credential));
239249
Assert.Equal("[email protected]", Assert.Contains("username", credential));
240250
Assert.Equal("pwd_1234567890", Assert.Contains("password", credential));
241251
Assert.Equal("true", Assert.Contains("replaces-base", credential));
@@ -245,6 +255,7 @@ public void MakeExtraCredentials_Works()
245255
Assert.Equal("rubygems_server", Assert.Contains("type", credential));
246256
Assert.Equal("https://rubygems.pkg.github.com/octocat/github_api", Assert.Contains("url", credential));
247257
Assert.DoesNotContain("registry", credential);
258+
Assert.DoesNotContain("index-url", credential);
248259
Assert.DoesNotContain("host", credential);
249260
Assert.DoesNotContain("key", credential);
250261
Assert.Equal("tkn_1234567890", Assert.Contains("token", credential));
@@ -261,6 +272,7 @@ public void MakeExtraCredentials_Works()
261272
Assert.Equal("terraform_registry", Assert.Contains("type", credential));
262273
Assert.DoesNotContain("url", credential);
263274
Assert.DoesNotContain("registry", credential);
275+
Assert.DoesNotContain("index-url", credential);
264276
Assert.Equal("terraform.example.com", Assert.Contains("host", credential));
265277
Assert.DoesNotContain("key", credential);
266278
Assert.Equal("tkn_1234567890", Assert.Contains("token", credential));

server/Tingle.Dependabot/Workflow/UpdateRunner.cs

+31-24
Original file line numberDiff line numberDiff line change
@@ -384,18 +384,17 @@ internal static IList<Dictionary<string, string>> MakeCredentialsMetadata(IList<
384384
return credentials.Select(cred =>
385385
{
386386
var values = new Dictionary<string, string> { ["type"] = cred["type"], };
387-
cred.TryGetValue("host", out var host);
388387

389-
// pull host from registry if available
390-
if (string.IsNullOrWhiteSpace(host))
388+
// if no host, pull host from url, index-url, or registry if available
389+
if (!cred.TryGetValue("host", out var host) || string.IsNullOrWhiteSpace(host))
391390
{
392-
host = cred.TryGetValue("registry", out var registry) && Uri.TryCreate($"https://{registry}", UriKind.Absolute, out var u) ? u.Host : host;
393-
}
391+
if (cred.TryGetValue("url", out var url) || cred.TryGetValue("index-url", out url)) { }
392+
else if (cred.TryGetValue("registry", out var registry)) url = $"https://{registry}";
394393

395-
// pull host from registry if url
396-
if (string.IsNullOrWhiteSpace(host))
397-
{
398-
host = cred.TryGetValue("url", out var url) && Uri.TryCreate(url, UriKind.Absolute, out var u) ? u.Host : host;
394+
if (url is not null && Uri.TryCreate(url, UriKind.Absolute, out var u))
395+
{
396+
host = u.Host;
397+
}
399398
}
400399

401400
values.AddIfNotDefault("host", host);
@@ -427,23 +426,31 @@ internal static IList<Dictionary<string, string>> MakeExtraCredentials(ICollecti
427426
values.AddIfNotDefault("token", ConvertPlaceholder(v.Token, secrets));
428427
values.AddIfNotDefault("replaces-base", v.ReplacesBase is true ? "true" : null);
429428

430-
// Some credentials do not use the 'url' property in the Ruby updater.
431-
// npm_registry and docker_registry use 'registry' which should be stripped off the scheme.
432-
// terraform_registry uses 'host' which is the hostname from the given URL.
433-
434-
if (type == "docker_registry" || type == "npm_registry")
435-
{
436-
values.Add("registry", v.Url!.Replace("https://", "").Replace("http://", ""));
437-
}
438-
else if (type == "terraform_registry")
429+
/*
430+
* Some credentials do not use the 'url' property in the Ruby updater.
431+
* The 'host' and 'registry' properties are derived from the given URL.
432+
* The 'registry' property is derived from the 'url' by stripping off the scheme.
433+
* The 'host' property is derived from the hostname of the 'url'.
434+
*
435+
* 'npm_registry' and 'docker_registry' use 'registry' only.
436+
* 'terraform_registry' uses 'host' only.
437+
* 'composer_repository' uses both 'url' and 'host'.
438+
* 'python_index' uses 'index-url' instead of 'url'.
439+
*/
440+
441+
if (Uri.TryCreate(v.Url, UriKind.Absolute, out var url))
439442
{
440-
values.Add("host", new Uri(v.Url!).Host);
441-
}
442-
else
443-
{
444-
values.AddIfNotDefault("url", v.Url!);
443+
var addRegistry = type is "docker_registry" or "npm_registry";
444+
if (addRegistry) values.Add("registry", $"{url.Host}{url.PathAndQuery}".TrimEnd('/'));
445+
446+
var addHost = type is "terraform_registry" or "composer_repository";
447+
if (addHost) values.Add("host", url.Host);
445448
}
446-
var useRegistryProperty = type.Contains("npm") || type.Contains("docker");
449+
450+
if (type is "python_index") values.AddIfNotDefault("index-url", v.Url);
451+
452+
var skipUrl = type is "docker_registry" or "npm_registry" or "terraform_registry" or "python_index";
453+
if (!skipUrl) values.AddIfNotDefault("url", v.Url);
447454

448455
return values;
449456
}).ToList();

0 commit comments

Comments
 (0)