Skip to content

Commit 2d435e0

Browse files
Merge pull request #15 from hesibo/develop
Add support for M2M
2 parents 41985d6 + a779f5b commit 2d435e0

19 files changed

+3263
-712
lines changed

README.md

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ The following parameters can be set in config files or in env variables:
3535
- GROUPS_API_URL: TC groups API base URL
3636
- COPILOT_RESOURCE_ROLE_IDS: copilot resource role ids allowed to upload attachment
3737
- HEALTH_CHECK_TIMEOUT: health check timeout in milliseconds
38-
38+
- SCOPES: the configurable M2M token scopes, refer `config/default.js` for more details
39+
- M2M_AUDIT_HANDLE: the audit name used when perform create/update operation using M2M token
3940

4041
Set the following environment variables so that the app can get TC M2M token (use 'set' insted of 'export' for Windows OS):
4142

@@ -44,46 +45,30 @@ Set the following environment variables so that the app can get TC M2M token (us
4445
- export AUTH0_URL=https://topcoder-dev.auth0.com/oauth/token
4546
- export AUTH0_AUDIENCE=https://m2m.topcoder-dev.com/
4647

48+
Also properly configure AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION, ATTACHMENT_S3_BUCKET, IS_LOCAL_DB config parameters.
4749

48-
Also properly configure AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION, ATTACHMENT_S3_BUCKET config parameters.
49-
50+
## DynamoDB Setup
51+
We can use DynamoDB setup on Docker for testing purpose. Just run `docker-compose up` in `local` folder.
52+
You can also use your own AWS DynamoDB service for testing purpose.
5053

51-
## DynamoDB Setup with Docker
52-
We will use DynamoDB setup on Docker.
53-
Note that you may need to modify regions in `local/init-dynamodb.sh` and `local/config`.
54+
## AWS S3 Setup
55+
Go to https://console.aws.amazon.com/ and login. Choose S3 from Service folder and click `Create bucket`. Following the instruction to create S3 bucket.
5456

55-
Just run `docker-compose up` in local folder
57+
## Mock api
58+
For postman verification, please use the mock api under mock-api folder. It provides mock endpoint to fetch challenge resources and groups.
59+
Go to `mock-api` folder and run command `npm run start` to start the mock-api listening on port 4000
5660

57-
If you have already installed aws-cli in your local machine, you can execute `./local/init-dynamodb.sh` to
58-
create the table. If not you can still create table following `Create Table via awscli in Docker`.
59-
60-
## Create Table via awscli in Docker
61+
## Create Tables
6162
1. Make sure DynamoDB are running as per instructions above.
62-
63-
2. Run the following commands
64-
```
65-
docker exec -ti dynamodb sh
66-
```
67-
Next
68-
```
69-
./init-dynamodb.sh
70-
```
71-
72-
3. Now the tables have been created, you can use following command to verify
73-
```
74-
aws dynamodb scan --table-name Challenge --endpoint-url http://localhost:7777
75-
aws dynamodb scan --table-name ChallengeType --endpoint-url http://localhost:7777
76-
aws dynamodb scan --table-name ChallengeSetting --endpoint-url http://localhost:7777
77-
aws dynamodb scan --table-name AuditLog --endpoint-url http://localhost:7777
78-
aws dynamodb scan --table-name Phase --endpoint-url http://localhost:7777
79-
aws dynamodb scan --table-name TimelineTemplate --endpoint-url http://localhost:7777
80-
aws dynamodb scan --table-name Attachment --endpoint-url http://localhost:7777
81-
```
63+
2. Make sure you have configured all config parameters. Refer [Configuration](#configuration)
64+
3. Run `npm run create-tables` to create tables.
8265

8366
## Scripts
8467
1. Drop/delete tables: `npm run drop-tables`
8568
2. Creating tables: `npm run create-tables`
8669
3. Seed/Insert data to tables: `npm run seed-tables`
70+
4. Initialize database in default environment: `npm run init-db`
71+
5. View table data in default environment: `npm run view-data <ModelName>`, ModelName can be `Challenge`, `ChallengeType`, `ChallengeSetting`, `AuditLog`, `Phase`, `TimelineTemplate`or `Attachment`
8772

8873
### Notes
8974
- The seed data are located in `src/scripts/seed`
@@ -93,9 +78,11 @@ aws dynamodb scan --table-name Attachment --endpoint-url http://localhost:7777
9378
- Install dependencies `npm install`
9479
- Run lint `npm run lint`
9580
- Run lint fix `npm run lint:fix`
81+
- Create tables `npm run create-tables`
9682
- Clear and init db `npm run init-db`
9783
- Start app `npm start`
9884
- App is running at `http://localhost:3000`
85+
- Start mock-api, go to `mock-api` folder and `npm start`, mock api is running at `http://localhost:4000`
9986

10087
## Verification
10188
Refer to the verification document `Verification.md`

Verification.md

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,7 @@
55
- run tests from up to down in order
66

77
## DynamoDB Verification
8-
1. Open a new console and run the command `docker exec -ti dynamodb sh` to use `aws-cli`
9-
10-
2. On the console you opened in step 1, run these following commands you can verify the data that inserted into database during the executing of postman tests
11-
```
12-
aws dynamodb scan --table-name Challenge --endpoint-url http://localhost:7777
13-
aws dynamodb scan --table-name ChallengeType --endpoint-url http://localhost:7777
14-
aws dynamodb scan --table-name ChallengeSetting --endpoint-url http://localhost:7777
15-
aws dynamodb scan --table-name AuditLog --endpoint-url http://localhost:7777
16-
aws dynamodb scan --table-name Phase --endpoint-url http://localhost:7777
17-
aws dynamodb scan --table-name TimelineTemplate --endpoint-url http://localhost:7777
18-
aws dynamodb scan --table-name Attachment --endpoint-url http://localhost:7777
19-
```
8+
Run command `npm run view-data <ModelName>` to view table data, ModelName can be `Challenge`, `ChallengeType`, `ChallengeSetting`, `AuditLog`, `Phase`, `TimelineTemplate`or `Attachment`
209

2110
## S3 Verification
2211

app-routes.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,13 @@ module.exports = (app) => {
4545

4646
actions.push((req, res, next) => {
4747
if (req.authUser.isMachine) {
48-
next(new errors.ForbiddenError('M2M is not supported.'))
48+
// M2M
49+
if (!req.authUser.scopes || !helper.checkIfExists(def.scopes, req.authUser.scopes)) {
50+
next(new errors.ForbiddenError('You are not allowed to perform this action!'))
51+
} else {
52+
req.authUser.handle = config.M2M_AUDIT_HANDLE
53+
next()
54+
}
4955
} else {
5056
req.authUser.userId = String(req.authUser.userId)
5157
// User roles authorization
@@ -74,7 +80,10 @@ module.exports = (app) => {
7480
if (!req.authUser) {
7581
next()
7682
} else if (req.authUser.isMachine) {
77-
next(new errors.ForbiddenError('M2M is not supported.'))
83+
if (!def.scopes || !req.authUser.scopes || !helper.checkIfExists(def.scopes, req.authUser.scopes)) {
84+
req.authUser = undefined
85+
}
86+
next()
7887
} else {
7988
req.authUser.userId = String(req.authUser.userId)
8089
next()

config/default.js

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,55 @@ module.exports = {
3333
FILE_UPLOAD_SIZE_LIMIT: process.env.FILE_UPLOAD_SIZE_LIMIT
3434
? Number(process.env.FILE_UPLOAD_SIZE_LIMIT) : 50 * 1024 * 1024, // 50M
3535
CHALLENGES_API_URL: process.env.CHALLENGES_API_URL || 'http://localhost:4000/v5/challenges',
36-
GROUPS_API_URL: process.env.GROUPS_API_URL || 'http://api.topcoder-dev.com/v5/groups',
36+
GROUPS_API_URL: process.env.GROUPS_API_URL || 'http://localhost:4000/v5/groups',
3737
// copilot resource role ids allowed to upload attachment
3838
COPILOT_RESOURCE_ROLE_IDS: process.env.COPILOT_RESOURCE_ROLE_IDS
3939
? process.env.COPILOT_RESOURCE_ROLE_IDS.split(',') : ['10ba038e-48da-487b-96e8-8d3b99b6d18b'],
4040

4141
// health check timeout in milliseconds
42-
HEALTH_CHECK_TIMEOUT: process.env.HEALTH_CHECK_TIMEOUT || 3000
42+
HEALTH_CHECK_TIMEOUT: process.env.HEALTH_CHECK_TIMEOUT || 3000,
43+
44+
SCOPES: {
45+
CHALLENGES: {
46+
READ: process.env.SCOPE_CHALLENGES_READ || 'read:challenges',
47+
CREATE: process.env.SCOPE_CHALLENGES_CREATE || 'create:challenges',
48+
UPDATE: process.env.SCOPE_CHALLENGES_UPDATE || 'update:challenges',
49+
ALL: process.env.SCOPE_CHALLENGES_ALL || 'all:challenges'
50+
},
51+
CHALLENGE_TYPES: {
52+
CREATE: process.env.SCOPE_CHALLENGE_TYPES_CREATE || 'create:challenge_types',
53+
UPDATE: process.env.SCOPE_CHALLENGE_TYPES_UPDATE || 'update:challenge_types',
54+
ALL: process.env.SCOPE_CHALLENGE_TYPES_ALL || 'all:challenge_types'
55+
},
56+
CHALLENGE_SETTINGS: {
57+
READ: process.env.SCOPE_CHALLENGE_SETTINGS_READ || 'read:challenge_settings',
58+
CREATE: process.env.SCOPE_CHALLENGE_SETTINGS_CREATE || 'create:challenge_settings',
59+
UPDATE: process.env.SCOPE_CHALLENGE_SETTINGS_UPDATE || 'update:challenge_settings',
60+
ALL: process.env.SCOPE_CHALLENGE_SETTINGS_ALL || 'all:challenge_settings'
61+
},
62+
CHALLENGE_AUDIT_LOGS: {
63+
READ: process.env.SCOPE_CHALLENGE_AUDIT_LOGS_READ || 'read:challenge_audit_logs'
64+
},
65+
CHALLENGE_PHASES: {
66+
READ: process.env.SCOPE_CHALLENGE_PHASES_READ || 'read:challenge_phases',
67+
CREATE: process.env.SCOPE_CHALLENGE_PHASES_CREATE || 'create:challenge_phases',
68+
DELETE: process.env.SCOPE_CHALLENGE_PHASES_DELETE || 'delete:challenge_phases',
69+
UPDATE: process.env.SCOPE_CHALLENGE_PHASES_UPDATE || 'update:challenge_phases',
70+
ALL: process.env.SCOPE_CHALLENGE_PHASES_ALL || 'all:challenge_phases'
71+
},
72+
TIMELINE_TEMPLATES: {
73+
READ: process.env.SCOPE_TIMELINE_TEMPLATES_READ || 'read:timeline_templates',
74+
CREATE: process.env.SCOPE_TIMELINE_TEMPLATES_CREATE || 'create:timeline_templates',
75+
DELETE: process.env.SCOPE_TIMELINE_TEMPLATES_DELETE || 'delete:timeline_templates',
76+
UPDATE: process.env.SCOPE_TIMELINE_TEMPLATES_UPDATE || 'update:timeline_templates',
77+
ALL: process.env.SCOPE_TIMELINE_TEMPLATES_ALL || 'all:timeline_templates'
78+
},
79+
CHALLENGE_ATTACHMENTS: {
80+
READ: process.env.SCOPE_CHALLENGE_ATTACHMENTS_READ || 'read:challenge_attachments',
81+
CREATE: process.env.SCOPE_CHALLENGE_ATTACHMENTS_CREATE || 'create:challenge_attachments',
82+
ALL: process.env.SCOPE_CHALLENGE_ATTACHMENTS_ALL || 'all:challenge_attachments'
83+
}
84+
},
85+
86+
M2M_AUDIT_HANDLE: process.env.M2M_AUDIT_HANDLE || 'TopcoderService'
4387
}

docs/swagger.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,16 @@ info:
2121
2222
## Access levels
2323
24+
- M2M token is supported, all non-public-accessed endpoint can be accessed using M2M token with proper scopes.
25+
2426
- Only admins and copilots can create/update an entity.
2527
2628
- Copilots can **only** update entities they have created. (eg. copilot A
2729
cannot update a challenge created by copilot B)
2830
2931
- Non-admin users can access challenges with groups only if they belong to any of the groups
32+
33+
- It will be considered as admin user if using valid M2M token(having read challenge scope) to list challenges or retrieve challenge by id
3034
host: api.topcoder.com
3135
basePath: /v5
3236
schemes:

0 commit comments

Comments
 (0)