Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit 75aba54

Browse files
committed
Challenge for August release
#316 #415 #422
1 parent b35ef6b commit 75aba54

33 files changed

+1519
-71
lines changed

Diff for: TopcoderXDeploy.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ You can do this by clicking your logged in username in the upper right of the To
157157

158158
Once you have registered your account, go into `Project Management` and add a new project for either a Gitlab or Github project you have access to. Gitlab is likely easier for testing - you can create a free test project under your own account.
159159

160-
Use Topcoder Connect ID `16665` since this has a valid billing account in the dev environment.
160+
Use Topcoder Connect ID `17249` since this has a valid billing account in the dev environment.
161161

162162
Once it's been added, click `Manage` for the project in the list on `Project Management` and click `Add Webhooks`. Once the webhook has been added, you should be able to see it in the Gitlab project under `Settings` --> `Integrations` --> `Webhooks`
163163

Diff for: package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
"create-tables": "CREATE_DB=true node scripts/create-update-tables.js",
2525
"migrate-user-mapping": "node scripts/migrate-user-mapping.js",
2626
"add-organisation": "node scripts/add-organisation.js",
27-
"log-repository-collisions": "node scripts/log-repository-collisions.js"
27+
"log-repository-collisions": "node scripts/log-repository-collisions.js",
28+
"migrate-repo-url": "node scripts/migrate-repo-url.js"
2829
},
2930
"dependencies": {
3031
"angular": "~1.8.0",

Diff for: scripts/log-repository-collisions.js

+15-13
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,21 @@ async function main() {
1717
archived: 'false'
1818
}).consistent().limit(BATCH_SIZE).startAt(previousKey).exec()
1919
for (const project of projects) {
20-
// If url was already found colliding go to a next iteration
21-
if (collidingUrls.includes(project.repoUrl)) continue;
22-
const collisions = await models.Project.scan({
23-
repoUrl: project.repoUrl,
24-
archived: 'false'
25-
}).exec()
26-
// If scan found only this project go to a next interation
27-
if (collisions.length < 2) continue;
28-
logger.info(`Repository ${project.repoUrl} has ${collisions.length} collisions`);
29-
_.forEach(collisions, collision => {
30-
logger.info(`--- ID: ${collision.id}`)
31-
})
32-
collidingUrls.push(project.repoUrl)
20+
for (const repoUrl of project.repoUrls) {
21+
// If url was already found colliding go to a next iteration
22+
if (collidingUrls.includes(repoUrl)) continue;
23+
const collisions = await models.Project.scan({
24+
repoUrl: { contains: project.repoUrl },
25+
archived: 'false'
26+
}).exec()
27+
// If scan found only this project go to a next interation
28+
if (collisions.length < 2) continue;
29+
logger.info(`Repository ${repoUrl} has ${collisions.length} collisions`);
30+
_.forEach(collisions, collision => {
31+
logger.info(`--- ID: ${collision.id}`)
32+
})
33+
collidingUrls.push(repoUrl)
34+
}
3335
}
3436
previousKey = projects.lastKey
3537
previousSize = projects.scannedCount

Diff for: scripts/migrate-repo-url.js

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
const AWS = require('aws-sdk');
2+
const helper = require('../src/common/helper');
3+
const dbHelper = require('../src/common/db-helper');
4+
const Project = require('../src/models').Project;
5+
6+
if (process.env.IS_LOCAL=="true") {
7+
AWS.config.update({
8+
endpoint: 'http://localhost:8000'
9+
});
10+
}
11+
var documentClient = new AWS.DynamoDB.DocumentClient();
12+
13+
(async () => {
14+
console.log('Migrating...');
15+
const params = {
16+
TableName: 'Topcoder_X.Project'
17+
};
18+
19+
let items;
20+
do {
21+
items = await documentClient.scan(params).promise();
22+
items.Items.forEach(async (item) => {
23+
console.log(item);
24+
item.repoUrls = [item.repoUrl];
25+
await dbHelper.update(Project, item.id, item);
26+
});
27+
params.ExclusiveStartKey = items.LastEvaluatedKey;
28+
} while(typeof items.LastEvaluatedKey !== 'undefined');
29+
})();

Diff for: src/common/db-helper.js

+10-10
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ async function scan(model, scanParams) {
5959
model.scan(scanParams).exec((err, result) => {
6060
if (err) {
6161
logger.error(`DynamoDB scan error ${err}`);
62-
reject(err);
62+
return reject(err);
6363
}
6464

6565
return resolve(result.count === 0 ? [] : result);
@@ -171,8 +171,8 @@ async function queryOneUserMappingByTCUsername(model, tcusername) {
171171
*/
172172
async function queryOneActiveProject(model, repoUrl) {
173173
return await new Promise((resolve, reject) => {
174-
model.query('repoUrl').eq(repoUrl)
175-
.where('archived')
174+
model.scan('repoUrls').contains(repoUrl)
175+
.filter('archived')
176176
.eq('false')
177177
.all()
178178
.exec((err, result) => {
@@ -202,7 +202,7 @@ async function queryOneActiveCopilotPayment(model, project, username) {
202202
.all()
203203
.exec((err, result) => {
204204
if (err || !result) {
205-
logger.debug(`queryOneActiveProject. Error. ${err}`);
205+
logger.debug(`queryOneActiveCopilotPayment. Error. ${err}`);
206206
return reject(err);
207207
}
208208
return resolve(result.count === 0 ? null : result[0]);
@@ -225,7 +225,7 @@ async function queryOneUserGroupMapping(model, groupId, gitlabUserId) {
225225
.all()
226226
.exec((err, result) => {
227227
if (err || !result) {
228-
logger.debug(`queryOneActiveProject. Error. ${err}`);
228+
logger.debug(`queryOneUserGroupMapping. Error. ${err}`);
229229
return reject(err);
230230
}
231231
return resolve(result.count === 0 ? null : result[0]);
@@ -251,7 +251,7 @@ async function queryOneUserTeamMapping(model, teamId, githubUserName, githubOrgI
251251
.all()
252252
.exec((err, result) => {
253253
if (err || !result) {
254-
logger.debug(`queryOneActiveProject. Error. ${err}`);
254+
logger.debug(`queryOneUserTeamMapping. Error. ${err}`);
255255
return reject(err);
256256
}
257257
return resolve(result.count === 0 ? null : result[0]);
@@ -268,15 +268,15 @@ async function queryOneUserTeamMapping(model, teamId, githubUserName, githubOrgI
268268
*/
269269
async function queryOneActiveProjectWithFilter(model, repoUrl, projectIdToFilter) {
270270
return await new Promise((resolve, reject) => {
271-
model.query('repoUrl').eq(repoUrl)
272-
.where('archived')
271+
model.scan('repoUrls').contains(repoUrl)
272+
.filter('archived')
273273
.eq('false')
274274
.filter('id')
275275
.not().eq(projectIdToFilter)
276276
.all()
277277
.exec((err, result) => {
278278
if (err || !result) {
279-
logger.debug(`queryOneActiveProject. Error. ${err}`);
279+
logger.debug(`queryOneActiveProjectWithFilter. Error. ${err}`);
280280
return reject(err);
281281
}
282282
return resolve(result.count === 0 ? null : result[0]);
@@ -296,7 +296,7 @@ async function create(Model, data) {
296296
dbItem.save((err) => {
297297
if (err) {
298298
logger.error(`DynamoDB create error ${err}`);
299-
reject(err);
299+
return reject(err);
300300
}
301301

302302
return resolve(dbItem);

Diff for: src/controllers/GithubPATsController.js

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright (c) 2018 TopCoder, Inc. All rights reserved.
3+
*/
4+
5+
/**
6+
* This controller exposes Github PATs endpoints.
7+
*
8+
* @author kevinkid
9+
* @version 1.0
10+
*/
11+
const helper = require('../common/helper');
12+
const GithubPATsService = require('../services/GithubPATsService');
13+
14+
/**
15+
* searches the pat according to criteria
16+
* @param {Object} req the request
17+
* @param {Object} res the response
18+
* @returns {Object} the result
19+
*/
20+
async function search(req) {
21+
return await GithubPATsService.search(req.query);
22+
}
23+
24+
/**
25+
* create pat
26+
* @param {Object} req the request
27+
* @param {Object} res the response
28+
* @returns {Object} the result
29+
*/
30+
async function create(req) {
31+
return await GithubPATsService.create(req.body.pat);
32+
}
33+
34+
/**
35+
* remove pat item
36+
* @param {Object} req the request
37+
* @param {Object} res the response
38+
* @returns {Object} the result
39+
*/
40+
async function remove(req) {
41+
return await GithubPATsService.remove(req.params.id);
42+
}
43+
44+
45+
module.exports = {
46+
search,
47+
create,
48+
remove,
49+
};
50+
51+
helper.buildController(module.exports);

Diff for: src/controllers/ProjectController.js

+37-3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
*/
1111
const helper = require('../common/helper');
1212
const ProjectService = require('../services/ProjectService');
13+
const models = require('../models');
1314

1415
/**
1516
* create project
@@ -47,7 +48,18 @@ async function getAll(req) {
4748
* @returns {Object} the result
4849
*/
4950
async function createLabel(req) {
50-
return await ProjectService.createLabel(req.body, req.currentUser);
51+
const dbProject = await helper.ensureExists(models.Project, req.body.projectId, 'Project');
52+
for (const repoUrl of dbProject.repoUrls) { // eslint-disable-line no-restricted-syntax
53+
try {
54+
await ProjectService.createLabel(req.body, req.currentUser, repoUrl);
55+
}
56+
catch (err) {
57+
throw new Error(`Adding the labels failed. Repo ${repoUrl}`);
58+
}
59+
}
60+
return {
61+
success: false
62+
};
5163
}
5264

5365
/**
@@ -57,7 +69,18 @@ async function createLabel(req) {
5769
* @returns {Object} the result
5870
*/
5971
async function createHook(req) {
60-
return await ProjectService.createHook(req.body, req.currentUser);
72+
const dbProject = await helper.ensureExists(models.Project, req.body.projectId, 'Project');
73+
for (const repoUrl of dbProject.repoUrls) { // eslint-disable-line no-restricted-syntax
74+
try {
75+
await ProjectService.createHook(req.body, req.currentUser, repoUrl);
76+
}
77+
catch (err) {
78+
throw new Error(`Adding the webhook failed. Repo ${repoUrl}`);
79+
}
80+
}
81+
return {
82+
success: false
83+
};
6184
}
6285

6386
/**
@@ -67,7 +90,18 @@ async function createHook(req) {
6790
* @returns {Object} the result
6891
*/
6992
async function addWikiRules(req) {
70-
return await ProjectService.addWikiRules(req.body, req.currentUser);
93+
const dbProject = await helper.ensureExists(models.Project, req.body.projectId, 'Project');
94+
for (const repoUrl of dbProject.repoUrls) { // eslint-disable-line no-restricted-syntax
95+
try {
96+
await ProjectService.addWikiRules(req.body, req.currentUser, repoUrl);
97+
}
98+
catch (err) {
99+
throw new Error(`Adding the wiki rules failed. Repo ${repoUrl}`);
100+
}
101+
}
102+
return {
103+
success: false
104+
};
71105
}
72106

73107
/**

Diff for: src/controllers/UserController.js

+44
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,54 @@ async function getUserToken(req) {
4545
return await UserService.getUserToken(req.query.username, req.query.tokenType);
4646
}
4747

48+
/**
49+
* searches user mappings according to criteria
50+
* @param {Object} req the request
51+
* @param {Object} res the response
52+
* @returns {Object} the result
53+
*/
54+
async function search(req) {
55+
return await UserService.search(req.query);
56+
}
57+
58+
/**
59+
* create user mapping
60+
* @param {Object} req the request
61+
* @param {Object} res the response
62+
* @returns {Object} the result
63+
*/
64+
async function create(req) {
65+
return await UserService.create(req.body.userMapping);
66+
}
67+
68+
/**
69+
* update user mapping
70+
* @param {Object} req the request
71+
* @param {Object} res the response
72+
* @returns {Object} the result
73+
*/
74+
async function update(req) {
75+
return await UserService.update(req.body.userMapping);
76+
}
77+
78+
/**
79+
* remove user mapping
80+
* @param {Object} req the request
81+
* @param {Object} res the response
82+
* @returns {Object} the result
83+
*/
84+
async function remove(req) {
85+
return await UserService.remove(req.params.username);
86+
}
87+
4888
module.exports = {
4989
getUserSetting,
5090
revokeUserSetting,
5191
getUserToken,
92+
search,
93+
create,
94+
remove,
95+
update,
5296
};
5397

5498
helper.buildController(module.exports);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
'use strict';
2+
3+
angular.module('topcoderX')
4+
.controller('AddGithubPATController', ['$scope', '$state', 'GithubPATsService', 'Alert',
5+
function ($scope, $state, GithubPATsService, Alert) {
6+
$scope.pat = {
7+
name: '',
8+
owner: '',
9+
personalAccessToken: ''
10+
};
11+
12+
// handle error output
13+
function _handleError(error, defaultMsg) {
14+
const errMsg = error.data ? error.data.message : defaultMsg;
15+
Alert.error(errMsg, $scope);
16+
}
17+
18+
// create/update pat item
19+
$scope.save = function () {
20+
if (!$scope.editing) {
21+
GithubPATsService.create($scope.pat).then(function (response) {
22+
if (response.data.exist) {
23+
Alert.error('Organisation is already exist with a PAT. Please delete first.', $scope);
24+
}
25+
else $state.go('app.githubPATs');
26+
}).catch(function (error) {
27+
_handleError(error, 'An error occurred while creating PAT.');
28+
});
29+
}
30+
};
31+
}
32+
]);

0 commit comments

Comments
 (0)