Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save icedream/b38953b1031985b091ad8dd475c946f3 to your computer and use it in GitHub Desktop.
Save icedream/b38953b1031985b091ad8dd475c946f3 to your computer and use it in GitHub Desktop.
Patches for verdaccio-gitlab to use CI job authentication

This is a quick and dirty patch I wrote to allow CI job tokens to be used for authentication on Verdaccio.

To use this, patch using git am or git apply, build the code (yarn code:build) and then, when running, use username ci and the job token as password to log in.

The first patch is only there to make the linter stop complaining about bad value coercing. The patches afterwards are the important ones.

From 121203f9e34b62721ff95b5eedfdfb54e532d4b8 Mon Sep 17 00:00:00 2001
From: Carl Kittelberger <icedream@icedream.pw>
Date: Tue, 19 Feb 2019 17:41:10 +0100
Subject: [PATCH 1/3] fix: bad value coercing
---
src/gitlab.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/gitlab.js b/src/gitlab.js
index 2e10da5..4691711 100644
--- a/src/gitlab.js
+++ b/src/gitlab.js
@@ -140,7 +140,7 @@ export default class VerdaccioGitLab implements IPluginAuth {
});
}).catch(error => {
- this.logger.error(`[gitlab] user: ${user} error querying gitlab user data: ${error.message || {}}`);
+ this.logger.error(`[gitlab] user: ${user} error querying gitlab user data: ${error.message || ""}`);
return cb(httperror[401]('error authenticating user'));
});
}
--
2.22.0
From e7fb4f3198678f377d58dba662f1179db3af879d Mon Sep 17 00:00:00 2001
From: Carl Kittelberger <icedream@icedream.pw>
Date: Tue, 19 Feb 2019 17:41:47 +0100
Subject: [PATCH 2/3] feat: implement CI token authentication with username
'ci'
---
src/gitlab.js | 25 +++++++++++++++++++++----
1 file changed, 21 insertions(+), 4 deletions(-)
diff --git a/src/gitlab.js b/src/gitlab.js
index 4691711..0577bee 100644
--- a/src/gitlab.js
+++ b/src/gitlab.js
@@ -101,10 +101,27 @@ export default class VerdaccioGitLab implements IPluginAuth {
token: password
});
- GitlabAPI.Users.current().then(response => {
- if (user !== response.username) {
- return cb(httperror[401]('wrong gitlab username'));
- }
+ let task: Promise<boolean>;
+ // If user is GitLab-reserved username 'ci', assume job token instead of PAT
+ if (user === 'ci') {
+ // Set job-token and unset private-token for all services
+ Object.keys(GitlabAPI).forEach(service => {
+ GitlabAPI[service].headers['job-token'] = password;
+ delete GitlabAPI[service].headers['private-token'];
+ });
+ task = Promise.resolve(true);
+ } else {
+ task = (GitlabAPI.Users.current(): Promise<any>).then(response => {
+ if (user !== response.username) {
+ cb(httperror[401]('wrong gitlab username'));
+ return false;
+ }
+ return true;
+ });
+ }
+
+ task.then(ok => {
+ if (!ok) return null;
const publishLevelId = ACCESS_LEVEL_MAPPING[this.publishLevel];
--
2.22.0
From 4c21fdc5042eb0c2c5dad94ea68f2758131b94a8 Mon Sep 17 00:00:00 2001
From: Carl Kittelberger <icedream@icedream.pw>
Date: Thu, 18 Jul 2019 16:03:12 +0200
Subject: [PATCH 3/3] feat: consider configured `publish` groups/users in
allow_publish
---
src/gitlab.js | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/src/gitlab.js b/src/gitlab.js
index 0577bee..0b36e06 100644
--- a/src/gitlab.js
+++ b/src/gitlab.js
@@ -45,6 +45,8 @@ const BUILTIN_ACCESS_LEVEL_ANONYMOUS = [ '$anonymous', '$all' ];
// Level to apply on 'allow_access' calls when a package definition does not define one
const DEFAULT_ALLOW_ACCESS_LEVEL = [ '$all' ];
+// Level to apply on 'allow_publish' calls when a package definition does not define one
+const DEFAULT_ALLOW_PUBLISH_LEVEL = [ ];
export default class VerdaccioGitLab implements IPluginAuth {
options: PluginOptions;
@@ -197,8 +199,26 @@ export default class VerdaccioGitLab implements IPluginAuth {
let packageScopePermit = false;
let packagePermit = false;
// Only allow to publish packages when:
+ // - the given internal group matches one of the configured allowed users/group, or
+ // - the user name matches one of the configured allowed users/groups, or
// - the package has exactly the same name as one of the user groups, or
// - the package scope is the same as one of the user groups
+ const packagePublish = (_package.publish && _package.publish.length > 0) ? _package.publish : DEFAULT_ALLOW_PUBLISH_LEVEL;
+ if (packagePublish.includes('$all') || packagePublish.includes('$anonymous')) {
+ this.logger.debug(`[gitlab] user: ${user.name || ''} allowed to publish package: ${_package.name} based on $anonymous/$all access`);
+ return cb(null, true);
+ }
+
+ if (!user.name) {
+ this.logger.debug(`[gitlab] unauthenticated user denied from publishing package: ${_package.name}`);
+ return cb(httperror[403](`must be authenticated`));
+ }
+
+ if (packagePublish.includes(user.name) || packagePublish.includes('$authenticated')) {
+ this.logger.debug(`[gitlab] user: ${user.name || ''} allowed to publish package: ${_package.name} based on authenticated username/$authenticated`);
+ return cb(null, true);
+ }
+
for (let real_group of user.real_groups) { // jscs:ignore requireCamelCaseOrUpperCaseIdentifiers
this.logger.trace(`[gitlab] publish: checking group: ${real_group} for user: ${user.name || ''} and package: ${_package.name}`);
--
2.22.0
From 48863caae0d8410f7b441f05fa2d78bb37b65216 Mon Sep 17 00:00:00 2001
From: Carl Kittelberger <icedream@icedream.pw>
Date: Fri, 19 Jul 2019 09:47:16 +0200
Subject: [PATCH 4/4] feat: check GitLab groups against configuration in
allow_publish
---
src/gitlab.js | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/src/gitlab.js b/src/gitlab.js
index 0b36e06..793d7b8 100644
--- a/src/gitlab.js
+++ b/src/gitlab.js
@@ -48,6 +48,13 @@ const DEFAULT_ALLOW_ACCESS_LEVEL = [ '$all' ];
// Level to apply on 'allow_publish' calls when a package definition does not define one
const DEFAULT_ALLOW_PUBLISH_LEVEL = [ ];
+// Prefixes for Verdaccio groups
+const groupPrefixes = [
+ '$',
+ '@',
+ '', // Verdaccio only supports this for legacy reasons
+];
+
export default class VerdaccioGitLab implements IPluginAuth {
options: PluginOptions;
config: VerdaccioGitlabConfig;
@@ -222,7 +229,8 @@ export default class VerdaccioGitLab implements IPluginAuth {
for (let real_group of user.real_groups) { // jscs:ignore requireCamelCaseOrUpperCaseIdentifiers
this.logger.trace(`[gitlab] publish: checking group: ${real_group} for user: ${user.name || ''} and package: ${_package.name}`);
- if (this._matchGroupWithPackage(real_group, _package.name)) {
+ if (groupPrefixes.some(prefix => packagePublish.includes(`${prefix}${real_group}`)) /* GitLab group in configured allowed groups? */
+ || this._matchGroupWithPackage(real_group, _package.name)) {
packagePermit = true;
break;
}
--
2.22.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment