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

Commit 7697670

Browse files
committed
1. Merge with master
2. Fix issue in test.generateToken.js 3. Add reset password api.
2 parents 6b5a2e0 + 437d5f3 commit 7697670

File tree

350 files changed

+19592
-954
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

350 files changed

+19592
-954
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,6 @@ pids
44
deploy/prod.sh
55
node_modules
66
test/tmp/submissions/*.zip
7+
test/tmp/design_submissions/*.zip
8+
test/tmp/design_tmp_submissions/*.zip
9+

actions/auth.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ exports.action = {
2424
blockedConnectionTypes: [],
2525
outputExample: {},
2626
version: 'v2',
27+
cacheEnabled: false,
2728
run: function (api, connection, next) {
2829
api.log("Execute generateJwt#run", 'debug');
2930
var form = {
@@ -80,6 +81,7 @@ exports.refreshJwt = {
8081
blockedConnectionTypes: [],
8182
outputExample: {},
8283
version: 'v2',
84+
cacheEnabled: false,
8385
run: function (api, connection, next) {
8486
api.log("Execute refreshJwt#run", 'debug');
8587
var form = {

actions/challengeRegistration.js

Lines changed: 189 additions & 48 deletions
Large diffs are not rendered by default.

actions/challengeUnregistration.js

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
/*
2+
* Copyright (C) 2014 TopCoder Inc., All Rights Reserved.
3+
*
4+
* The APIs to un-register a challenge (studio category or software category) for the current logged-in user.
5+
*
6+
* @version 1.0
7+
* @author bugbuka
8+
*/
9+
"use strict";
10+
11+
var async = require('async');
12+
var _ = require('underscore');
13+
var moment = require('moment');
14+
var ForumWrapper = require("forum-connector").ForumWrapper;
15+
var UnauthorizedError = require('../errors/UnauthorizedError');
16+
var NotFoundError = require('../errors/NotFoundError');
17+
var ForbiddenError = require('../errors/ForbiddenError');
18+
19+
//constants
20+
var SUBMITTER_RESOURCE_ROLE_ID = 1,
21+
PROJECT_USER_AUDIT_DELETE_TYPE = 2;
22+
23+
/**
24+
* Checks if specified challenge category ID implies the presence of records in project_result and component_inquiry
25+
* tables for challenge registrants.
26+
*
27+
* @param {Number} categoryId - ID for challenge category.
28+
* @returns {boolean} true if above records are required; false otherwise.
29+
* @since 1.3
30+
*/
31+
function isProjectResultCategory(categoryId) {
32+
return (categoryId === 1 // Component Design
33+
|| categoryId === 2 // Component Development
34+
|| categoryId === 5 // Component Testing
35+
|| categoryId === 6 // Application Specification
36+
|| categoryId === 7 // Application Architecture
37+
|| categoryId === 9 // Bug Hunt
38+
|| categoryId === 13 // Test Scenarios
39+
|| categoryId === 26 // Test Suites
40+
|| categoryId === 14 // Application Assembly
41+
|| categoryId === 23 // Application Conceptualization
42+
|| categoryId === 19 // UI Prototype
43+
|| categoryId === 24 // RIA Build
44+
|| categoryId === 25 // RIA Component
45+
|| categoryId === 29 // Copilot Posting
46+
|| categoryId === 35 // Content Creation
47+
|| categoryId === 36 // Reporting
48+
|| categoryId === 38 // First2Finish
49+
|| categoryId === 39 // Code
50+
);
51+
}
52+
53+
/**
54+
* Remove forum permissions. It is initialized only once.
55+
*
56+
* @param {Object} api The api object that is used to access the infrastructure.
57+
* @param {Number} userId The current logged-in user's id.
58+
* @param {Number} forumCategoryId The sql params.
59+
* @param {Function<err, data>} next The callback to be called after this function is done.
60+
*/
61+
var removeForumPermissions = function (api, userId, forumCategoryId, next) {
62+
63+
if (api.config.general.grantForumAccess !== true || forumCategoryId === 0) {
64+
next();
65+
return;
66+
}
67+
68+
if (forumCategoryId === null) {
69+
api.log('Could not find forum category ' + forumCategoryId, 'error');
70+
next(new Error('Could not find forum category ' + forumCategoryId));
71+
return;
72+
}
73+
74+
api.log('start to remove user ' + userId + ' from forum category ' + forumCategoryId + '.');
75+
async.waterfall([
76+
function (cb) {
77+
api.challengeHelper.getForumWrapper(api, cb);
78+
}, function (forumWrapper, cb) {
79+
forumWrapper.removeRole(userId, "Software_Users_" + forumCategoryId, cb);
80+
}, function (forumWrapper, cb) {
81+
forumWrapper.removeRole(userId, "Software_Moderators_" + forumCategoryId, cb);
82+
}, function (forumWrapper, cb) {
83+
forumWrapper.removeUserPermission(userId, forumCategoryId, cb);
84+
}, function (forumWrapper, cb) {
85+
forumWrapper.deleteCategoryWatch(userId, forumCategoryId, cb);
86+
}
87+
], function (err) {
88+
if (err) {
89+
next(err);
90+
return;
91+
}
92+
next();
93+
});
94+
};
95+
96+
/**
97+
* Unregister a development (software) challenge for the current logged-in user.
98+
*
99+
* @param {Object} api The api object that is used to access the infrastructure.
100+
* @param {Number} userId The current logged-in user's id.
101+
* @param {Object} sqlParams The sql params.
102+
* @param {Object} unregisterInfo The data used to do unregistration.
103+
* @param {Object} dbConnectionMap The database connection map for the current request.
104+
* @param {Function<err, data>} next The callback to be called after this function is done.
105+
*/
106+
var unregisterChallenge = function (api, userId, sqlParams, unregisterInfo, dbConnectionMap, next) {
107+
async.series([
108+
function (cb) {
109+
if (sqlParams.isStudio || isProjectResultCategory(sqlParams.categoryId)) {
110+
api.dataAccess.executeQuery("delete_challenge_result", sqlParams, dbConnectionMap, cb);
111+
} else {
112+
cb();
113+
}
114+
115+
}, function (cb) {
116+
117+
if (_.size(unregisterInfo.userChallengeResources) < 1) {
118+
api.log("Could not find user challenge resource", 'error');
119+
cb(new Error('Could not find user challenge resource'));
120+
return;
121+
}
122+
var submitterRoleResourceId = _.filter(unregisterInfo.userChallengeResources, function (resource) {
123+
return resource.resource_role_id === SUBMITTER_RESOURCE_ROLE_ID;
124+
})[0].resource_id;
125+
126+
api.dataAccess.executeQuery("delete_challenge_resources", {resourceId : submitterRoleResourceId}, dbConnectionMap, cb);
127+
}, function (cb) {
128+
129+
api.challengeHelper.aduitResourceAddition(api, userId, sqlParams.challengeId, SUBMITTER_RESOURCE_ROLE_ID, PROJECT_USER_AUDIT_DELETE_TYPE, dbConnectionMap, cb);
130+
}, function (cb) {
131+
132+
if (_.size(unregisterInfo.userChallengeResources) === 1 && unregisterInfo.userChallengeResources[0].resource_role_id === SUBMITTER_RESOURCE_ROLE_ID) { // Only remove forum permissions if the user has no other roles left.
133+
if (unregisterInfo.challengeForum.length === 0) {
134+
api.log("Could not find user challenge forum", 'error');
135+
cb(new Error('Could not find user challenge forum'));
136+
return;
137+
}
138+
var forumCategoryId = parseInt(unregisterInfo.challengeForum[0].forum_category_id, 10);
139+
removeForumPermissions(api, userId, forumCategoryId, cb);
140+
}
141+
cb();
142+
}
143+
], next);
144+
};
145+
146+
/**
147+
* The action to unregister a challenge for the current logged-in user.
148+
*
149+
* @param {Object} api The api object that is used to access the infrastructure.
150+
* @param {Object} connection The connection for the current request.
151+
* @param {Function<err, data>} next The callback to be called after this function is done.
152+
*/
153+
var unregisterChallengeAction = function (api, connection, next) {
154+
155+
var helper = api.helper,
156+
sqlParams = {},
157+
userId = connection.caller.userId,
158+
challengeId = Number(connection.params.challengeId),
159+
160+
execQuery = function (name) {
161+
return function (cbx) {
162+
api.dataAccess.executeQuery(name, sqlParams, connection.dbConnectionMap, cbx);
163+
};
164+
};
165+
166+
async.waterfall([
167+
function (cb) {
168+
169+
//Simple validations of the incoming parameters
170+
var error = helper.checkPositiveInteger(challengeId, 'challengeId') ||
171+
helper.checkMaxInt(challengeId, 'challengeId') ||
172+
helper.checkMember(connection, 'You don\'t have the authority to access this. Please login.');
173+
174+
if (error) {
175+
cb(error);
176+
return;
177+
}
178+
179+
//Check if the user passes validations for joining the challenge
180+
sqlParams.userId = userId;
181+
sqlParams.challengeId = challengeId;
182+
183+
api.dataAccess.executeQuery("challenge_unregistration_validations", sqlParams, connection.dbConnectionMap, cb);
184+
}, function (rows, cb) {
185+
if (rows.length === 0) {
186+
187+
cb(new NotFoundError('No such challenge exists.'));
188+
} else if (!rows[0].reg_open) {
189+
190+
cb(new ForbiddenError('You cannot unregister since registration phase is closed.'));
191+
} else if (!rows[0].user_has_submitter_resource_role) {
192+
193+
cb(new ForbiddenError('You are not registered for this challenge.'));
194+
}
195+
196+
sqlParams.categoryId = rows[0].category_id;
197+
sqlParams.isStudio = rows[0].is_studio;
198+
199+
async.series({
200+
userChallengeResources: execQuery('get_user_challenge_resource'),
201+
challengeForum: execQuery('get_challenge_forum')
202+
}, cb);
203+
204+
},
205+
function (result, cb) {
206+
unregisterChallenge(api, userId, sqlParams, result, connection.dbConnectionMap, cb);
207+
}
208+
], function (err) {
209+
if (err) {
210+
api.helper.handleError(api, connection, err);
211+
} else {
212+
api.log("unregister the challenge succeeded.", 'debug');
213+
connection.response = {message : "ok"};
214+
}
215+
next(connection, true);
216+
});
217+
218+
};
219+
220+
/**
221+
* The API to unregister a challenge for the current logged-in user.
222+
*/
223+
exports.unregisterChallenge = {
224+
name: "unregisterChallenge",
225+
description: "unregisterChallenge",
226+
inputs: {
227+
required: ["challengeId"],
228+
optional: []
229+
},
230+
blockedConnectionTypes: [],
231+
outputExample: {},
232+
version: 'v2',
233+
cacheEnabled : false,
234+
transaction: 'write',
235+
databases: ["tcs_catalog"],
236+
run: function (api, connection, next) {
237+
if (connection.dbConnectionMap) {
238+
api.log("Execute unregisterChallenge#run", 'debug');
239+
unregisterChallengeAction(api, connection, next);
240+
} else {
241+
api.helper.handleNoConnection(api, connection, next);
242+
}
243+
}
244+
};
245+
246+

0 commit comments

Comments
 (0)