Skip to content

Commit c6a0644

Browse files
committed
UI updates and better handling of close events.
1 parent 84216a6 commit c6a0644

28 files changed

+377
-229
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,5 +79,6 @@ Note: heroku domain should match subdomain of topcoder-dev or topcoder depending
7979
- setup both git provider to authorize topcoder-x to manage your repo on behalf of you
8080
- go to project management and create/edit projects, create hook and label
8181
- go to git access control menu and check list of groups have authorized
82-
- click get link button to get the shareable link which can be used by topcoder member to self assign to the repository.
82+
- click get link button to get the shareable link which can be used by topcoder member to self assign to the repository. Click to icon next to url to copy to clipboard.
83+
- normal member cannot use the application, allowed roles are configured in API, if normal user tries to access the app, error is shown in login page.
8384

src/.DS_Store

0 Bytes
Binary file not shown.

src/.eslintrc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"extends":"eslint-config-topcoder/nodejs",
2+
"extends": "eslint-config-topcoder/nodejs",
33
"env": {
44
"mocha": true
55
},
@@ -10,5 +10,7 @@
1010
"experimentalObjectRestSpread": true
1111
}
1212
},
13-
"rules": { }
13+
"rules": {
14+
"lodash/prefer-invoke-map": 0
15+
}
1416
}

src/app.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ _.forEach(routes, (verbs, path) => {
4444
const decoded = jwtDecode(v3jwt);
4545
req.currentUser = {
4646
handle: decoded.handle.toLowerCase(),
47+
roles: decoded.roles,
4748
};
4849
}
4950
req.signature = `${def.controller}#${def.method}`;
@@ -61,6 +62,20 @@ _.forEach(routes, (verbs, path) => {
6162
return res.redirect(`${constants.TOPCODER_VALUES[config.TOPCODER_ENV].TC_LOGIN_URL}?retUrl=${encodeURIComponent(callbackUri)}`);
6263
});
6364
}
65+
if (!def.allowNormalUser) {
66+
actions.push((req, res, next) => {
67+
// check if any allowed role is matched with user's roles
68+
if (_(req.currentUser.roles).map((i) => i.toLowerCase())
69+
.intersection(_.map(config.ALLOWED_TOPCODER_ROLES, (j) => j.toLowerCase())).size() === 0) {
70+
const statusCode = 403;
71+
return res.status(statusCode).json({
72+
code: 'Forbidden',
73+
message: 'You are not allowed to access this resource.',
74+
});
75+
}
76+
return next();
77+
});
78+
}
6479
actions.push(method);
6580
app[verb](`/api/${config.API_VERSION}${path}`, actions);
6681
});

src/common/constants.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ const GITHUB_OWNER_CALLBACK_URL = '/api/v1/github/owneruser/callback';
6363
const GITLAB_OWNER_CALLBACK_URL = '/api/v1/gitlab/owneruser/callback';
6464

6565
const OWNER_USER_LOGIN_SUCCESS_URL = '/#/app/settings';
66-
const USER_ADDED_TO_TEAM_SUCCESS_URL = '/#/app/members';
66+
const USER_ADDED_TO_TEAM_SUCCESS_URL = '/#/members';
6767

6868
const TC_LOGIN_CALLBACK_URL = '/api/v1/tclogin';
6969
const JWT_V3_NAME = 'v3jwt';

src/config.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,6 @@ module.exports = {
3434
},
3535
HOOK_BASE_URL: process.env.HOOK_BASE_URL || 'http://x.topcoder-dev.com/',
3636
TOPCODER_ENV: process.env.TOPCODER_ENV || 'dev',
37-
LABELS: process.env.LABELS || [{ name: 'Open for pickup', color: '112233' }, { name: 'Assigned', color: '445566' }, { name: 'Ready for review', color: '123123' }, { name: 'Paid', color: '456456' }, { name: 'Feedback', color: 'ff0011' }, { name: 'Fix accepted', color: 'aabb11' },]
37+
LABELS: process.env.LABELS || [{ name: 'Open for pickup', color: '112233' }, { name: 'Assigned', color: '445566' }, { name: 'Ready for review', color: '123123' }, { name: 'Paid', color: '456456' }, { name: 'Feedback', color: 'ff0011' }, { name: 'Fix accepted', color: 'aabb11' }],
38+
ALLOWED_TOPCODER_ROLES: process.env.ALLOWED_TOPCODER_ROLES || ['administrator', 'admin', 'connect manager', 'connect admin'],
3839
};

src/controllers/ProjectController.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,10 @@ async function update(req) {
3434
/**
3535
* get all projects
3636
* @param {Object} req the request
37-
* @param {Object} res the response
3837
* @returns {Array} the result
3938
*/
40-
async function getAll() {
41-
return await ProjectService.getAll();
39+
async function getAll(req) {
40+
return await ProjectService.getAll(req.query.status);
4241
}
4342

4443
/**

src/controllers/SecurityController.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright (c) 2018 TopCoder, Inc. All rights reserved.
3+
*/
4+
5+
/**
6+
* This controller exposes security related endpoints.
7+
*
8+
* @author veshu
9+
* @version 1.0
10+
*/
11+
12+
const helper = require('../common/helper');
13+
const securityService = require('../services/SecurityService');
14+
15+
/**
16+
* check if current user is authorized for Topcoder X or not.
17+
* @param {Object} req the request
18+
* @returns {Object} the result
19+
*/
20+
async function isAuthorized(req) {
21+
return await securityService.isRolesAllowed(req.currentUser.roles);
22+
}
23+
24+
module.exports = {
25+
isAuthorized,
26+
};
27+
28+
helper.buildController(module.exports);

src/front/config.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"local":{"API_URL":"https://127.0.0.1:8443","ADMIN_TOOL_URL":"http://localhost:8080/api/v2","API_VERSION_PATH":"v3","COOKIES_SECURE":false,"AUTH_URL":"https://accounts.topcoder-dev.com/member","ACCOUNTS_CONNECTOR_URL":"https://accounts.topcoder-dev.com/connector.html","JWT_V3_NAME":"v3jwt","JWT_V2_NAME":"tcjwt","BACKEND_API":"http://localhost:4000","DIRECT_URL_BASE":"https://www.topcoder-dev.com/direct/projectOverview?formData.projectId=","LABELS":["Open for pickup","Assigned","Ready for review","Paid","Feedback","Fix accepted"],"LABELS_COLOR":["112233","445566","123123","456456","ff0011","aabb11"],"HOOK_BASE_URL":"https://b9602b91.ngrok.io","OWNER_LOGIN_GITHUB_URL":"/api/v1/github/owneruser/login","OWNER_LOGIN_GITLAB_URL":"/api/v1/gitlab/owneruser/login"},"heroku":{"API_URL":"https://api.topcoder-dev.com","ADMIN_TOOL_URL":"https://api.topcoder-dev.com/v2","API_VERSION_PATH":"v3","COOKIES_SECURE":false,"AUTH_URL":"https://accounts.topcoder-dev.com/member","ACCOUNTS_CONNECTOR_URL":"https://accounts.topcoder-dev.com/connector.html","JWT_V3_NAME":"v3jwt","JWT_V2_NAME":"tcjwt","BACKEND_API":"http://topcoder-x-backend-dev.herokuapp.com","DIRECT_URL_BASE":"https://www.topcoder-dev.com/direct/projectOverview?formData.projectId=","LABELS":["Open for pickup","Assigned","Ready for review","Paid","Feedback","Fix accepted"],"LABELS_COLOR":["112233","445566","123123","456456","ff0011","aabb11"],"HOOK_BASE_URL":"http://x.topcoder-dev.com/","OWNER_LOGIN_GITHUB_URL":"/api/v1/github/owneruser/login","OWNER_LOGIN_GITLAB_URL":"/api/v1/gitlab/owneruser/login"},"dev":{"API_URL":"https://api.topcoder-dev.com","ADMIN_TOOL_URL":"https://api.topcoder-dev.com/v2","API_VERSION_PATH":"v3","COOKIES_SECURE":false,"AUTH_URL":"https://accounts.topcoder-dev.com/member","ACCOUNTS_CONNECTOR_URL":"https://accounts.topcoder-dev.com/connector.html","JWT_V3_NAME":"v3jwt","JWT_V2_NAME":"tcjwt","DIRECT_URL_BASE":"https://www.topcoder-dev.com/direct/projectOverview?formData.projectId=","LABELS":["Open for pickup","Assigned","Ready for review","Paid","Feedback","Fix accepted"],"LABELS_COLOR":["112233","445566","123123","456456","ff0011","aabb11"],"HOOK_BASE_URL":"https://b9602b91.ngrok.io","OWNER_LOGIN_GITHUB_URL":"/api/v1/github/owneruser/login","OWNER_LOGIN_GITLAB_URL":"/api/v1/gitlab/owneruser/login"},"qa":{"API_URL":"https://api.topcoder-qa.com","ADMIN_TOOL_URL":"https://api.topcoder-qa.com/v2","API_VERSION_PATH":"v3","COOKIES_SECURE":false,"AUTH_URL":"https://accounts.topcoder-qa.com/member","ACCOUNTS_CONNECTOR_URL":"https://accounts.topcoder-qa.com/connector.html","JWT_V3_NAME":"v3jwt","JWT_V2_NAME":"tcjwt","BACKEND_API":"http://localhost:4000","DIRECT_URL_BASE":"https://www.topcoder-dev.com/direct/projectOverview?formData.projectId=","LABELS":["Open for pickup","Assigned","Ready for review","Paid","Feedback","Fix accepted"],"LABELS_COLOR":["112233","445566","123123","456456","ff0011","aabb11"],"HOOK_BASE_URL":"https://b9602b91.ngrok.io","OWNER_LOGIN_GITHUB_URL":"/api/v1/github/owneruser/login","OWNER_LOGIN_GITLAB_URL":"/api/v1/gitlab/owneruser/login"},"prod":{"API_URL":"https://api.topcoder.com","ADMIN_TOOL_URL":"https://api.topcoder.com/v2","API_VERSION_PATH":"v3","COOKIES_SECURE":false,"AUTH_URL":"https://accounts.topcoder.com/member","ACCOUNTS_CONNECTOR_URL":"https://accounts.topcoder.com/connector.html","JWT_V3_NAME":"v3jwt","JWT_V2_NAME":"tcjwt","BACKEND_API":"http://topcoderx.topcoder.com:80/api/v1","DIRECT_URL_BASE":"https://www.topcoder-dev.com/direct/projectOverview?formData.projectId=","LABELS":["Open for pickup","Assigned","Ready for review","Paid","Feedback","Fix accepted"],"LABELS_COLOR":["112233","445566","123123","456456","ff0011","aabb11"],"HOOK_BASE_URL":"https://b9602b91.ngrok.io","OWNER_LOGIN_GITHUB_URL":"/api/v1/github/owneruser/login","OWNER_LOGIN_GITLAB_URL":"/api/v1/gitlab/owneruser/login"}}

src/front/src/app/app.js

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -86,24 +86,26 @@ angular.module('topcoderX', [
8686
data: { pageTitle: 'Project Management' },
8787
resolve: { auth: authenticate }
8888
})
89-
.state('app.challenges', {
90-
url: '/challenges',
91-
templateUrl: 'app/challenges/challenges.html',
92-
data: { pageTitle: 'Topcoder Platform' },
93-
resolve: { auth: authenticate }
94-
})
95-
.state('app.tickets', {
96-
url: '/tickets',
97-
templateUrl: 'app/challenges/tickets.html',
98-
data: { pageTitle: 'Git Tickets' },
99-
resolve: { auth: authenticate }
100-
})
101-
.state('app.changelog', {
102-
url: '/changelog',
103-
templateUrl: 'app/changelog/changelog.html',
104-
data: { pageTitle: 'Changelog' },
105-
resolve: { auth: authenticate }
106-
})
89+
// following code is commented to hide the menu
90+
// un comment this when pages are developed
91+
// .state('app.challenges', {
92+
// url: '/challenges',
93+
// templateUrl: 'app/challenges/challenges.html',
94+
// data: { pageTitle: 'Topcoder Platform' },
95+
// resolve: { auth: authenticate }
96+
// })
97+
// .state('app.tickets', {
98+
// url: '/tickets',
99+
// templateUrl: 'app/challenges/tickets.html',
100+
// data: { pageTitle: 'Git Tickets' },
101+
// resolve: { auth: authenticate }
102+
// })
103+
// .state('app.changelog', {
104+
// url: '/changelog',
105+
// templateUrl: 'app/changelog/changelog.html',
106+
// data: { pageTitle: 'Changelog' },
107+
// resolve: { auth: authenticate }
108+
// })
107109
.state('app.settings', {
108110
url: '/settings',
109111
templateUrl: 'app/settings/settings.html',
@@ -117,8 +119,9 @@ angular.module('topcoderX', [
117119
templateUrl: 'app/git-access-control/access-control.html',
118120
controller: 'GitAccessController',
119121
controllerAs: 'vm',
122+
resolve: { auth: authenticate }
120123
})
121-
.state('app.membersAdded', {
124+
.state('membersAdded', {
122125
url: '/members/:provider',
123126
templateUrl: 'app/members/member.html',
124127
controller: 'MemberController',

0 commit comments

Comments
 (0)