screwdriver-api 8.0.35 → 8.0.36

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "screwdriver-api",
3
- "version": "8.0.35",
3
+ "version": "8.0.36",
4
4
  "description": "API server for the Screwdriver.cd service",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -44,6 +44,7 @@ const removeTemplateTagRoute = require('./templates/removeTag');
44
44
  const removeTemplateVersionRoute = require('./templates/removeVersion');
45
45
  const updateTrustedRoute = require('./templates/updateTrusted');
46
46
  const updateBuildCluster = require('./updateBuildCluster');
47
+ const updateAdminsRoute = require('./updateAdmins');
47
48
 
48
49
  /**
49
50
  * Pipeline API Plugin
@@ -278,7 +279,8 @@ const pipelinesPlugin = {
278
279
  removeTemplateTagRoute(),
279
280
  removeTemplateVersionRoute(),
280
281
  updateTrustedRoute(),
281
- updateBuildCluster()
282
+ updateBuildCluster(),
283
+ updateAdminsRoute()
282
284
  ]);
283
285
  }
284
286
  };
@@ -4,6 +4,7 @@ const joi = require('joi');
4
4
  const schema = require('screwdriver-data-schema');
5
5
  const idSchema = schema.models.pipeline.base.extract('id');
6
6
  const scmUriSchema = schema.models.pipeline.base.extract('scmUri');
7
+ const scmContextSchema = schema.models.pipeline.base.extract('scmContext');
7
8
  const listSchema = joi.array().items(schema.models.pipeline.get).label('List of Pipelines');
8
9
  const pipelineIdsSchema = joi.alternatives().try(joi.array().items(idSchema), idSchema).required();
9
10
  const IDS_KEY = 'ids[]';
@@ -23,12 +24,14 @@ module.exports = () => ({
23
24
  handler: async (request, h) => {
24
25
  const { pipelineFactory } = request.server.app;
25
26
  const { sort, configPipelineId, sortBy, search, scmUri, page, count } = request.query;
26
- const scmContexts = pipelineFactory.scm.getScmContexts();
27
+ const scmContexts = request.query.scmContext
28
+ ? [request.query.scmContext]
29
+ : pipelineFactory.scm.getScmContexts();
27
30
  let pipelineArray = [];
28
31
 
29
- scmContexts.forEach(scmContext => {
32
+ scmContexts.forEach(sc => {
30
33
  const config = {
31
- params: { scmContext },
34
+ params: { scmContext: sc },
32
35
  sort
33
36
  };
34
37
 
@@ -129,7 +132,8 @@ module.exports = () => ({
129
132
  joi.object({
130
133
  configPipelineId: idSchema,
131
134
  'ids[]': pipelineIdsSchema.optional(),
132
- scmUri: scmUriSchema
135
+ scmUri: scmUriSchema,
136
+ scmContext: scmContextSchema.optional()
133
137
  })
134
138
  )
135
139
  }
@@ -0,0 +1,106 @@
1
+ 'use strict';
2
+
3
+ const boom = require('@hapi/boom');
4
+ const joi = require('joi');
5
+ const schema = require('screwdriver-data-schema');
6
+ const logger = require('screwdriver-logger');
7
+ const idSchema = schema.models.pipeline.base.extract('id');
8
+
9
+ module.exports = () => ({
10
+ method: 'PUT',
11
+ path: '/pipelines/{id}/updateAdmins',
12
+ options: {
13
+ description: 'Update admins of a pipeline',
14
+ notes: 'Update the admins of a specific pipeline',
15
+ tags: ['api', 'pipelines'],
16
+ auth: {
17
+ strategies: ['token'],
18
+ scope: ['user', '!guest', 'pipeline']
19
+ },
20
+ handler: async (request, h) => {
21
+ const { id } = request.params;
22
+ const { scmContext, username, scmUserId, scope } = request.auth.credentials;
23
+ const isPipeline = scope.includes('pipeline');
24
+
25
+ const { usernames } = request.payload;
26
+ const payloadScmContext = request.payload.scmContext;
27
+
28
+ if (!Array.isArray(usernames) || usernames.length === 0) {
29
+ throw boom.badRequest(`Payload must contain admin usernames`);
30
+ } else if (!payloadScmContext) {
31
+ throw boom.badRequest(`Payload must contain scmContext`);
32
+ }
33
+
34
+ const { pipelineFactory, bannerFactory, userFactory } = request.server.app;
35
+
36
+ // Check token permissions
37
+ if (isPipeline) {
38
+ if (username !== id) {
39
+ throw boom.forbidden(
40
+ `User ${username} is not authorized to update admins for the pipeline (id=${id})`
41
+ );
42
+ }
43
+ } else {
44
+ // Only SD cluster admins can update the admins
45
+ const scmDisplayName = bannerFactory.scm.getDisplayName({ scmContext });
46
+
47
+ const adminDetails = request.server.plugins.banners.screwdriverAdminDetails(
48
+ username,
49
+ scmDisplayName,
50
+ scmUserId
51
+ );
52
+
53
+ if (!adminDetails.isAdmin) {
54
+ throw boom.forbidden(
55
+ `User ${username} does not have Screwdriver administrative privileges to update the admins for the pipeline (id=${id})`
56
+ );
57
+ }
58
+ }
59
+
60
+ const pipeline = await pipelineFactory.get({ id });
61
+
62
+ // check if pipeline exists
63
+ if (!pipeline) {
64
+ throw boom.notFound(`Pipeline ${id} does not exist`);
65
+ }
66
+ if (pipeline.state === 'DELETING') {
67
+ throw boom.conflict('This pipeline is being deleted.');
68
+ }
69
+
70
+ const users = await userFactory.list({
71
+ params: {
72
+ username: usernames,
73
+ scmContext: payloadScmContext
74
+ }
75
+ });
76
+
77
+ const adminUsernamesForUpdate = [];
78
+ const newAdmins = new Set(pipeline.adminUserIds);
79
+
80
+ users.forEach(user => {
81
+ newAdmins.add(user.id);
82
+ adminUsernamesForUpdate.push(user.username);
83
+ });
84
+
85
+ pipeline.adminUserIds = Array.from(newAdmins);
86
+
87
+ try {
88
+ const result = await pipeline.update();
89
+
90
+ logger.info(`Updated admins ${adminUsernamesForUpdate} for pipeline(id=${id})`);
91
+
92
+ return h.response(result.toJson()).code(200);
93
+ } catch (err) {
94
+ logger.error(
95
+ `Failed to update admins ${adminUsernamesForUpdate} for pipeline(id=${id}): ${err.message}`
96
+ );
97
+ throw boom.internal(`Failed to update admins for pipeline ${id}`);
98
+ }
99
+ },
100
+ validate: {
101
+ params: joi.object({
102
+ id: idSchema
103
+ })
104
+ }
105
+ }
106
+ });