Skip to content

Commit dbf0f82

Browse files
author
sachin-maheshwari
authored
Merge pull request #82 from topcoder-platform/feature/m2m-support
m2m implementation.
2 parents 40520c2 + 04ee4f2 commit dbf0f82

File tree

11 files changed

+123
-67
lines changed

11 files changed

+123
-67
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ workflows:
7676
- test
7777
filters:
7878
branches:
79-
only: dev
79+
only: 'dev'
8080
- deployProd:
8181
requires:
8282
- test

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM node:6.9.4
1+
FROM node:8.2.1
22
LABEL version="1.0"
33
LABEL description="Projects microservice"
44

config/custom-environment-variables.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"apiVersion": "API_VERSION",
3-
"authSecret": "AUTH_SECRET",
3+
"AUTH_SECRET": "AUTH_SECRET",
44
"logLevel": "LOG_LEVEL",
55
"version": "APP_VERSION",
66
"captureLogs": "CAPTURE_LOGS",
@@ -28,8 +28,12 @@
2828
"minPoolSize": "DB_MIN_POOL_SIZE"
2929
},
3030
"analyticsKey": "SEGMENT_ANALYTICS_KEY",
31-
"validIssuers": "VALID_ISSUERS",
31+
"VALID_ISSUERS": "VALID_ISSUERS",
3232
"jwksUri": "JWKS_URI",
3333
"busApiUrl": "BUS_API_URL",
34-
"busApiToken": "BUS_API_TOKEN"
34+
"AUTH0_URL" : "AUTH0_URL",
35+
"AUTH0_CLIENT_ID": "AUTH0_CLIENT_ID",
36+
"AUTH0_CLIENT_SECRET": "AUTH0_CLIENT_SECRET",
37+
"AUTH0_AUDIENCE": "AUTH0_AUDIENCE",
38+
"TOKEN_CACHE_TIME" : "TOKEN_CACHE_TIME"
3539
}

config/default.json

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
{
22
"apiVersion": "v4",
3-
"authSecret": "secret",
4-
"authDomain": "topcoder-dev.com",
3+
"AUTH_SECRET": "secret",
54
"logLevel": "info",
65
"version": "v4",
76
"captureLogs": "false",
@@ -33,9 +32,12 @@
3332
"idleTimeout": 1000
3433
},
3534
"analyticsKey": "",
36-
"validIssuers": "[\"https:\/\/topcoder-newauth.auth0.com\/\",\"https:\/\/api.topcoder-dev.com\"]",
37-
"jwksUri": "",
35+
"VALID_ISSUERS": "[\"https:\/\/topcoder-newauth.auth0.com\/\",\"https:\/\/api.topcoder-dev.com\"]",
3836
"busApiUrl": "http://api.topcoder-dev.com",
39-
"busApiToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoicHJvamVjdC1zZXJ2aWNlIiwiaWF0IjoxNTEyNzQ3MDgyLCJleHAiOjE1MjEzODcwODJ9.PHuNcFDaotGAL8RhQXQMdpL8yOKXxjB5DbBIodmt7RE",
40-
"HEALTH_CHECK_URL": "_health"
37+
"HEALTH_CHECK_URL": "_health",
38+
"AUTH0_CLIENT_ID": "",
39+
"AUTH0_CLIENT_SECRET": "",
40+
"AUTH0_AUDIENCE": "",
41+
"AUTH0_URL": "",
42+
"TOKEN_CACHE_TIME": ""
4143
}

config/development.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
{
2-
"authDomain": "topcoder-dev.com",
32
"pubsubQueueName": "dev.project.service",
43
"pubsubExchangeName": "dev.projects",
54
"attachmentsS3Bucket": "topcoder-dev-media"

config/test.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
{
2-
"authSecret": "secret",
3-
"authDomain": "topcoder-dev.com",
2+
"AUTH_SECRET": "secret",
43
"logLevel": "debug",
54
"captureLogs": "false",
65
"logentriesToken": "",

deploy.sh

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,6 @@ make_task_def(){
117117
"name": "BUS_API_URL",
118118
"value": "%s"
119119
},
120-
{
121-
"name": "BUS_API_TOKEN",
122-
"value": "%s"
123-
},
124120
{
125121
"name": "SYSTEM_USER_CLIENT_ID",
126122
"value": "%s"
@@ -156,6 +152,26 @@ make_task_def(){
156152
{
157153
"name": "SEGMENT_ANALYTICS_KEY",
158154
"value": "%s"
155+
},
156+
{
157+
"name": "AUTH0_URL",
158+
"value": "%s"
159+
},
160+
{
161+
"name": "AUTH0_AUDIENCE",
162+
"value": "%s"
163+
},
164+
{
165+
"name": "AUTH0_CLIENT_ID",
166+
"value": "%s"
167+
},
168+
{
169+
"name": "AUTH0_CLIENT_SECRET",
170+
"value": "%s"
171+
},
172+
{
173+
"name": "TOKEN_CACHE_TIME",
174+
"value": "%s"
159175
}
160176
],
161177
"portMappings": [
@@ -180,7 +196,6 @@ make_task_def(){
180196
MEMBER_SERVICE_ENDPOINT=$(eval "echo \$${ENV}_MEMBER_SERVICE_ENDPOINT")
181197
IDENTITY_SERVICE_ENDPOINT=$(eval "echo \$${ENV}_IDENTITY_SERVICE_ENDPOINT")
182198
BUS_API_URL=$(eval "echo \$${ENV}_BUS_API_URL")
183-
BUS_API_TOKEN=$(eval "echo \$${ENV}_BUS_API_TOKEN")
184199
SYSTEM_USER_CLIENT_ID=$(eval "echo \$${ENV}_SYSTEM_USER_CLIENT_ID")
185200
SYSTEM_USER_CLIENT_SECRET=$(eval "echo \$${ENV}_SYSTEM_USER_CLIENT_SECRET")
186201
CAPTURE_LOGS=$(eval "echo \$${ENV}_CAPTURE_LOGS")
@@ -201,7 +216,14 @@ make_task_def(){
201216
echo "NODE_ENV"
202217
echo $NODE_ENV
203218

204-
task_def=$(printf "$task_template" $family $ACCOUNT_ID $AWS_ECS_CONTAINER_NAME $ACCOUNT_ID $AWS_REGION $AWS_REPOSITORY $CIRCLE_SHA1 $NODE_ENV $LOG_LEVEL $CAPTURE_LOGS $LOGENTRIES_TOKEN $API_VERSION $AWS_REGION $AWS_ACCESS_KEY_ID $AWS_SECRET_ACCESS_KEY $AUTH_DOMAIN $AUTH_SECRET $VALID_ISSUERS $DB_MASTER_URL $MEMBER_SERVICE_ENDPOINT $IDENTITY_SERVICE_ENDPOINT $BUS_API_URL $BUS_API_TOKEN $SYSTEM_USER_CLIENT_ID $SYSTEM_USER_CLIENT_SECRET $PROJECTS_ES_URL $PROJECTS_ES_INDEX_NAME $RABBITMQ_URL $DIRECT_PROJECT_SERVICE_ENDPOINT $FILE_SERVICE_ENDPOINT $CONNECT_PROJECTS_URL $SEGMENT_ANALYTICS_KEY $PORT $PORT $AWS_ECS_CLUSTER $AWS_REGION $NODE_ENV)
219+
AUTH0_URL=$(eval "echo \$${ENV}_AUTH0_URL")
220+
AUTH0_AUDIENCE=$(eval "echo \$${ENV}_AUTH0_AUDIENCE")
221+
AUTH0_CLIENT_ID=$(eval "echo \$${ENV}_AUTH0_CLIENT_ID")
222+
AUTH0_CLIENT_SECRET=$(eval "echo \$${ENV}_AUTH0_CLIENT_SECRET")
223+
TOKEN_CACHE_TIME=$(eval "echo \$${ENV}_TOKEN_CACHE_TIME")
224+
225+
226+
task_def=$(printf "$task_template" $family $ACCOUNT_ID $AWS_ECS_CONTAINER_NAME $ACCOUNT_ID $AWS_REGION $AWS_REPOSITORY $CIRCLE_SHA1 $NODE_ENV $LOG_LEVEL $CAPTURE_LOGS $LOGENTRIES_TOKEN $API_VERSION $AWS_REGION $AWS_ACCESS_KEY_ID $AWS_SECRET_ACCESS_KEY $AUTH_DOMAIN $AUTH_SECRET $VALID_ISSUERS $DB_MASTER_URL $MEMBER_SERVICE_ENDPOINT $IDENTITY_SERVICE_ENDPOINT $BUS_API_URL $SYSTEM_USER_CLIENT_ID $SYSTEM_USER_CLIENT_SECRET $PROJECTS_ES_URL $PROJECTS_ES_INDEX_NAME $RABBITMQ_URL $DIRECT_PROJECT_SERVICE_ENDPOINT $FILE_SERVICE_ENDPOINT $CONNECT_PROJECTS_URL $SEGMENT_ANALYTICS_KEY "$AUTH0_URL" "$AUTH0_AUDIENCE" $AUTH0_CLIENT_ID "$AUTH0_CLIENT_SECRET" $TOKEN_CACHE_TIME $PORT $PORT $AWS_ECS_CLUSTER $AWS_REGION $NODE_ENV)
205227
}
206228

207229
push_ecr_image(){
@@ -240,4 +262,4 @@ check_service_status() {
240262
configure_aws_cli
241263
push_ecr_image
242264
deploy_cluster
243-
check_service_status
265+
check_service_status

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
"pg": "^4.5.5",
5656
"pg-native": "^1.10.0",
5757
"sequelize": "^3.23.0",
58-
"tc-core-library-js": "appirio-tech/tc-core-library-js.git#v2.2",
58+
"tc-core-library-js": "appirio-tech/tc-core-library-js.git#v2.3",
5959
"traverse": "^0.6.6",
6060
"urlencode": "^1.1.0"
6161
},

src/constants.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,7 @@ export const BUS_API_EVENT = {
7777
export const REGEX = {
7878
URL: /^(http(s?):\/\/)?(www\.)?[a-zA-Z0-9\.\-\_]+(\.[a-zA-Z]{2,15})+(\:[0-9]{2,5})?(\/[a-zA-Z0-9\_\-\s\.\/\?\%\#\&\=;]*)?$/, // eslint-disable-line
7979
};
80+
81+
export const TOKEN_SCOPES = {
82+
CONNECT_PROJECT_ADMIN: 'all:connect_project',
83+
};

src/services/busApi.js

Lines changed: 52 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,38 @@ import config from 'config';
22

33
const Promise = require('bluebird');
44
const axios = require('axios');
5+
const tcCoreLibAuth = require('tc-core-library-js').auth;
56

7+
const m2m = tcCoreLibAuth.m2m(config);
68

79
let client = null;
810

911
/**
1012
* Get Http client to bus api
1113
* @return {Object} Http Client to bus api
1214
*/
13-
function getClient() {
15+
async function getClient() {
1416
if (client) return client;
1517
const apiBusUrl = config.get('busApiUrl');
16-
const apiBusToken = config.get('busApiToken');
18+
try {
19+
const token = await m2m.getMachineToken(config.AUTH0_CLIENT_ID, config.AUTH0_CLIENT_SECRET);
20+
client = axios.create({ baseURL: apiBusUrl });
1721

18-
client = axios.create({ baseURL: apiBusUrl });
22+
// Alter defaults after instance has been created
23+
client.defaults.headers.common.Authorization = `Bearer ${token}`;
1924

20-
// Alter defaults after instance has been created
21-
client.defaults.headers.common.Authorization = `Bearer ${apiBusToken}`;
25+
// Add a response interceptor
26+
client.interceptors.response.use(function (res) { // eslint-disable-line
27+
return res;
28+
}, function (error) { // eslint-disable-line
29+
// Ingore response errors
30+
return Promise.resolve();
31+
});
2232

23-
// Add a response interceptor
24-
client.interceptors.response.use(function (res) { // eslint-disable-line
25-
return res;
26-
}, function (error) { // eslint-disable-line
27-
// Ingore response errors
28-
return Promise.resolve();
29-
});
30-
31-
return client;
33+
return client;
34+
} catch (err) {
35+
return Promise.reject(`Bus api calling - Error in genearting m2m token : ${err.message}`);
36+
}
3237
}
3338

3439
/**
@@ -42,39 +47,42 @@ function getClient() {
4247
function createEvent(type, message, logger) {
4348
const body = JSON.stringify(message);
4449
logger.debug(`Sending message: ${JSON.stringify(message)}`);
45-
return getClient().post('/bus/events', {
46-
type,
47-
message: body,
48-
})
49-
.then((resp) => {
50-
logger.debug('Sent event to bus-api');
51-
logger.debug(`Sent event to bus-api [data]: ${resp.data}`);
52-
logger.debug(`Sent event to bus-api [status]: ${resp.status}`);
53-
})
54-
.catch((error) => {
55-
logger.debug('Error sending event to bus-api');
56-
if (error.response) {
57-
// The request was made and the server responded with a status code
58-
// that falls out of the range of 2xx
59-
logger.debug(error.response.data);
60-
logger.debug(error.response.status);
61-
logger.debug(error.response.headers);
62-
} else if (error.request) {
63-
// The request was made but no response was received
64-
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
65-
// http.ClientRequest in node.js
66-
logger.debug(error.request);
67-
} else {
68-
// Something happened in setting up the request that triggered an Error
69-
logger.debug(error.message);
70-
}
71-
logger.debug(error.config);
72-
73-
Promise.resolve(); // eslint-disable-line
50+
return getClient().then((busClient) => {
51+
logger.debug('calling bus-api');
52+
busClient.post('/bus/events', {
53+
type,
54+
message: body,
55+
})
56+
.then((resp) => {
57+
logger.debug('Sent event to bus-api');
58+
logger.debug(`Sent event to bus-api [data]: ${resp.data}`);
59+
logger.debug(`Sent event to bus-api [status]: ${resp.status}`);
60+
})
61+
.catch((error) => {
62+
logger.debug('Error sending event to bus-api');
63+
if (error.response) {
64+
// The request was made and the server responded with a status code
65+
// that falls out of the range of 2xx
66+
logger.debug(error.response.data);
67+
logger.debug(error.response.status);
68+
logger.debug(error.response.headers);
69+
} else if (error.request) {
70+
// The request was made but no response was received
71+
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
72+
// http.ClientRequest in node.js
73+
logger.debug(error.request);
74+
} else {
75+
// Something happened in setting up the request that triggered an Error
76+
logger.debug(error.message);
77+
}
78+
logger.debug(error.config);
79+
Promise.resolve(); // eslint-disable-line
80+
});
81+
}).catch((errMessage) => {
82+
logger.debug(errMessage);
7483
});
7584
}
7685

77-
7886
module.exports = {
7987
createEvent,
8088
};

src/util.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import urlencode from 'urlencode';
1717
import elasticsearch from 'elasticsearch';
1818
import Promise from 'bluebird';
1919
import AWS from 'aws-sdk';
20-
import { ADMIN_ROLES } from './constants';
20+
import { ADMIN_ROLES, TOKEN_SCOPES } from './constants';
2121

2222
const exec = require('child_process').exec;
2323
const models = require('./models').default;
@@ -70,6 +70,12 @@ _.assignIn(util, {
7070
* @return {boolean} true/false
7171
*/
7272
hasRole: (req, role) => {
73+
const isMachineToken = _.get(req, 'authUser.isMachine', false);
74+
const tokenScopes = _.get(req, 'authUser.scopes', []);
75+
if (isMachineToken) {
76+
if (_.indexOf(tokenScopes, TOKEN_SCOPES.CONNECT_PROJECT_ADMIN) >= 0) return true;
77+
return false;
78+
}
7379
let roles = _.get(req, 'authUser.roles', []);
7480
roles = roles.map(s => s.toLowerCase());
7581
return _.indexOf(roles, role.toLowerCase()) >= 0;
@@ -81,6 +87,12 @@ _.assignIn(util, {
8187
* @return {boolean} true/false
8288
*/
8389
hasRoles: (req, roles) => {
90+
const isMachineToken = _.get(req, 'authUser.isMachine', false);
91+
const tokenScopes = _.get(req, 'authUser.scopes', []);
92+
if (isMachineToken) {
93+
if (_.indexOf(tokenScopes, TOKEN_SCOPES.CONNECT_PROJECT_ADMIN) >= 0) return true;
94+
return false;
95+
}
8496
let authRoles = _.get(req, 'authUser.roles', []);
8597
authRoles = authRoles.map(s => s.toLowerCase());
8698
return _.intersection(authRoles, roles.map(r => r.toLowerCase())).length > 0;
@@ -101,6 +113,12 @@ _.assignIn(util, {
101113
* @return {boolean} true/false
102114
*/
103115
hasAdminRole: (req) => {
116+
const isMachineToken = _.get(req, 'authUser.isMachine', false);
117+
const tokenScopes = _.get(req, 'authUser.scopes', []);
118+
if (isMachineToken) {
119+
if (_.indexOf(tokenScopes, TOKEN_SCOPES.CONNECT_PROJECT_ADMIN) >= 0) return true;
120+
return false;
121+
}
104122
let roles = _.get(req, 'authUser.roles', []);
105123
roles = roles.map(s => s.toLowerCase());
106124
return _.intersection(roles, ADMIN_ROLES.map(r => r.toLowerCase())).length > 0;

0 commit comments

Comments
 (0)