screwdriver-api 6.0.8 → 6.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -31,9 +31,16 @@ auth:
31
31
  whitelist:
32
32
  __name: SECRET_WHITELIST
33
33
  __format: json
34
+ allowList:
35
+ __name: SECRET_ALLOW_LIST
36
+ __format: json
34
37
  admins:
35
38
  __name: SECRET_ADMINS
36
39
  __format: json
40
+ sdAdmins:
41
+ __name: SECRET_SD_ADMINS
42
+ __format: json
43
+ authCheckById: AUTH_CHECK_BY_ID
37
44
  # Default session timeout (in minutes)
38
45
  sessionTimeout: SESSION_TIMEOUT
39
46
  # Oauth redirect uri, configure this if your app is not running at root under the host
@@ -32,10 +32,33 @@ auth:
32
32
  https: false
33
33
  # A flag to set if you want guests to browse your pipelines
34
34
  allowGuestAccess: false
35
- # Whitelist of users able to authenticate against the system
35
+ # Deprecated. Instead, use allowList which is more secure.
36
+ # List of users able to authenticate against the system
36
37
  # if empty, it allows everyone
38
+ # Values should follow '{scmDisplayName:scmUsername}' format
39
+ # Ex: ['github:john', 'bitbucket:john']
37
40
  whitelist: []
41
+ # list of users able to authenticate against the system
42
+ # if empty, it allows everyone
43
+ # Values should follow '{scmDisplayName:scmUsername:scmUserId}' format
44
+ # Ex: ['github:john:12345', 'bitbucket:john:{98fsa1ba-0b91-4e3c-95ee-55899e933b0}']
45
+ allowList: []
46
+ # Deprecated. Instead, use sdAdmins which is more secure.
47
+ # List of users who should be given screwdriver admin privileges
48
+ # Values should follow '{scmDisplayName:scmUsername}' format
49
+ # Ex: ['github:john', 'bitbucket:john']
38
50
  admins: []
51
+ # List of users who should be given screwdriver admin privileges
52
+ # Values should follow '{scmDisplayName:scmUsername:scmUserId}' format
53
+ # Ex: ['github:john:12345', 'bitbucket:john:{98fsa1ba-0b91-4e3c-95ee-55899e933b0}']
54
+ sdAdmins: []
55
+ # When set to true
56
+ # - grant admin privileges to the users listed in 'sdAdmins'
57
+ # - only authenticate the users listed in 'allowList'
58
+ # When set to false, performs
59
+ # - grant admin privileges to the users listed in 'admins'
60
+ # - only authenticate the users listed in 'whitelist'
61
+ authCheckById: true
39
62
  # Default session timeout (in minutes)
40
63
  sessionTimeout: 120
41
64
  # SameSite Cookie Option
package/lib/server.js CHANGED
@@ -201,7 +201,7 @@ module.exports = async config => {
201
201
  server.app.buildFactory.apiUri = server.info.uri;
202
202
  server.app.buildFactory.tokenGen = (buildId, metadata, scmContext, expiresIn, scope = ['temporal']) =>
203
203
  server.plugins.auth.generateToken(
204
- server.plugins.auth.generateProfile(buildId, scmContext, scope, metadata),
204
+ server.plugins.auth.generateProfile(buildId, null, scmContext, scope, metadata),
205
205
  expiresIn
206
206
  );
207
207
  server.app.buildFactory.executor.tokenGen = server.app.buildFactory.tokenGen;
@@ -209,7 +209,7 @@ module.exports = async config => {
209
209
  server.app.jobFactory.apiUri = server.info.uri;
210
210
  server.app.jobFactory.tokenGen = (username, metadata, scmContext, scope = ['user']) =>
211
211
  server.plugins.auth.generateToken(
212
- server.plugins.auth.generateProfile(username, scmContext, scope, metadata)
212
+ server.plugins.auth.generateProfile(username, null, scmContext, scope, metadata)
213
213
  );
214
214
  server.app.jobFactory.executor.userTokenGen = server.app.jobFactory.tokenGen;
215
215
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "screwdriver-api",
3
- "version": "6.0.8",
3
+ "version": "6.0.10",
4
4
  "description": "API server for the Screwdriver.cd service",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -60,8 +60,11 @@ const AUTH_PLUGIN_SCHEMA = joi.object().keys({
60
60
  jwtPrivateKey: joi.string().required(),
61
61
  jwtPublicKey: joi.string().required(),
62
62
  jwtQueueServicePublicKey: joi.string().required(),
63
+ authCheckById: JOI_BOOLEAN.default(true),
63
64
  whitelist: joi.array().default([]),
65
+ allowList: joi.array().default([]),
64
66
  admins: joi.array().default([]),
67
+ sdAdmins: joi.array().default([]),
65
68
  bell: joi.object().required(),
66
69
  scm: joi.object().required(),
67
70
  sessionTimeout: joi.number().integer().positive().default(120),
@@ -95,12 +98,13 @@ const authPlugin = {
95
98
  * Generates a profile for storage in cookie and jwt
96
99
  * @method generateProfile
97
100
  * @param {String} username Username of the person
101
+ * @param {String} scmUserId User ID in the SCM
98
102
  * @param {String} scmContext Scm to which the person logged in belongs
99
103
  * @param {Array} scope Scope for this profile (usually build or user)
100
104
  * @param {Object} metadata Additonal information to tag along with the login
101
105
  * @return {Object} The profile to be stored in jwt and/or cookie
102
106
  */
103
- server.expose('generateProfile', (username, scmContext, scope, metadata) => {
107
+ server.expose('generateProfile', (username, scmUserId, scmContext, scope, metadata) => {
104
108
  const profile = { username, scmContext, scope, ...(metadata || {}) };
105
109
 
106
110
  if (pluginOptions.jwtEnvironment) {
@@ -110,10 +114,13 @@ const authPlugin = {
110
114
  if (scmContext) {
111
115
  const { scm } = pluginOptions;
112
116
  const scmDisplayName = scm.getDisplayName({ scmContext });
113
- const userDisplayName = `${scmDisplayName}:${username}`;
117
+ const userDisplayName = pluginOptions.authCheckById
118
+ ? `${scmDisplayName}:${username}:${scmUserId}`
119
+ : `${scmDisplayName}:${username}`;
120
+ const admins = pluginOptions.authCheckById ? pluginOptions.sdAdmins : pluginOptions.admins;
114
121
 
115
122
  // Check admin
116
- if (pluginOptions.admins.length > 0 && pluginOptions.admins.includes(userDisplayName)) {
123
+ if (admins.length > 0 && admins.includes(userDisplayName)) {
117
124
  profile.scope.push('admin');
118
125
  }
119
126
  }
@@ -32,7 +32,13 @@ function addGuestRoute(config) {
32
32
  }
33
33
 
34
34
  const username = `guest/${uuidv4()}`;
35
- const profile = request.server.plugins.auth.generateProfile(username, null, ['user', 'guest'], {});
35
+ const profile = request.server.plugins.auth.generateProfile(
36
+ username,
37
+ null,
38
+ null,
39
+ ['user', 'guest'],
40
+ {}
41
+ );
36
42
 
37
43
  // Log that the user has authenticated
38
44
  request.log(['auth'], `${username} has logged in`);
@@ -81,14 +87,23 @@ function addOAuthRoutes(config) {
81
87
  const { userFactory } = request.server.app;
82
88
  const { collectionFactory } = request.server.app;
83
89
  const accessToken = request.auth.credentials.token;
84
- const { username } = request.auth.credentials.profile;
85
-
86
- const profile = request.server.plugins.auth.generateProfile(username, scmContext, ['user'], {});
90
+ const { username, id: scmUserId } = request.auth.credentials.profile;
91
+
92
+ const profile = request.server.plugins.auth.generateProfile(
93
+ username,
94
+ scmUserId,
95
+ scmContext,
96
+ ['user'],
97
+ {}
98
+ );
87
99
  const scmDisplayName = await userFactory.scm.getDisplayName({ scmContext });
88
- const userDisplayName = `${scmDisplayName}:${username}`;
100
+ const userDisplayName = config.authCheckById
101
+ ? `${scmDisplayName}:${username}:${scmUserId}`
102
+ : `${scmDisplayName}:${username}`;
103
+ const allowList = config.authCheckById ? config.allowList : config.whitelist;
89
104
 
90
105
  // Check whitelist
91
- if (config.whitelist.length > 0 && !config.whitelist.includes(userDisplayName)) {
106
+ if (allowList.length > 0 && !allowList.includes(userDisplayName)) {
92
107
  return boom.forbidden(`User ${userDisplayName} is not allowed access`);
93
108
  }
94
109
 
@@ -39,10 +39,12 @@ module.exports = () => ({
39
39
  const job = await jobFactory.get(build.jobId);
40
40
  const pipeline = pipelineFactory.get(job.pipelineId);
41
41
 
42
- profile = request.server.plugins.auth.generateProfile(request.params.buildId, pipeline.scmContext, [
43
- 'build',
44
- 'impersonated'
45
- ]);
42
+ profile = request.server.plugins.auth.generateProfile(
43
+ request.params.buildId,
44
+ null,
45
+ pipeline.scmContext,
46
+ ['build', 'impersonated']
47
+ );
46
48
  profile.token = request.server.plugins.auth.generateToken(profile);
47
49
 
48
50
  request.cookieAuth.set(profile);
@@ -56,6 +56,7 @@ module.exports = () => ({
56
56
  const token = request.server.plugins.auth.generateToken(
57
57
  request.server.plugins.auth.generateProfile(
58
58
  profile.username,
59
+ null,
59
60
  profile.scmContext,
60
61
  ['build'],
61
62
  jwtInfo
@@ -36,7 +36,7 @@ async function invoke(request) {
36
36
  const { username, scmContext } = auth.credentials;
37
37
 
38
38
  const token = request.server.plugins.auth.generateToken(
39
- request.server.plugins.auth.generateProfile(username, scmContext, ['sdapi'], { pipelineId })
39
+ request.server.plugins.auth.generateProfile(username, null, scmContext, ['sdapi'], { pipelineId })
40
40
  );
41
41
 
42
42
  const options = {