Skip to content

Commit 69e62c6

Browse files
authored
Merge pull request #517 from topcoder-platform/feature/restful-invites
Restful Invites
2 parents 44a8a0b + be61078 commit 69e62c6

31 files changed

+2585
-898
lines changed

docs/Project API.postman_collection.json

Lines changed: 269 additions & 28 deletions
Large diffs are not rendered by default.

docs/swagger.yaml

Lines changed: 108 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2890,7 +2890,7 @@ paths:
28902890
example:
28912891
'work.create': true
28922892
'workItem.edit': true
2893-
2893+
28942894
'401':
28952895
description: Unauthorized
28962896
schema:
@@ -3519,31 +3519,26 @@ paths:
35193519
description: Internal Server Error
35203520
schema:
35213521
$ref: '#/definitions/ErrorModel'
3522-
'/projects/{projectId}/members/invite':
3522+
'/projects/{projectId}/invites':
35233523
get:
35243524
tags:
35253525
- project member invite
3526-
operationId: getCurrentUserInvite
3526+
operationId: listProjectInvites
35273527
security:
35283528
- Bearer: []
3529-
description: Retrieve the invite for current user.
3529+
description: >-
3530+
If user can "view" this project, he/she can get all invitations.
3531+
Otherwise user can only see his/her own invitation in this project.
3532+
If user has no invitation in this project or this project doesn't exist, an empty array will be returned.
35303533
parameters:
35313534
- $ref: '#/parameters/projectIdParam'
35323535
responses:
35333536
'200':
35343537
description: The invite for current user
35353538
schema:
3536-
$ref: '#/definitions/ProjectMemberInviteSuccessAndFailure'
3537-
'400':
3538-
description: Bad request
3539-
schema:
3540-
$ref: '#/definitions/ErrorModel'
3541-
'401':
3542-
description: Unauthorized
3543-
schema:
3544-
$ref: '#/definitions/ErrorModel'
3545-
'404':
3546-
description: Invite not found
3539+
$ref: '#/definitions/ProjectMemberInviteListResult'
3540+
'403':
3541+
description: Forbidden
35473542
schema:
35483543
$ref: '#/definitions/ErrorModel'
35493544
'500':
@@ -3567,27 +3562,54 @@ paths:
35673562
schema:
35683563
$ref: '#/definitions/AddProjectMemberInvitesRequest'
35693564
responses:
3570-
'200':
3571-
description: Returns the newly created invite
3565+
'201':
3566+
description: Created
35723567
schema:
35733568
$ref: '#/definitions/ProjectMemberInviteSuccessAndFailure'
35743569
'400':
35753570
description: Bad request
35763571
schema:
35773572
$ref: '#/definitions/ErrorModel'
3578-
'401':
3579-
description: Unauthorized
3573+
'403':
3574+
description: Forbidden
3575+
schema:
3576+
$ref: '#/definitions/ErrorModel'
3577+
'500':
3578+
description: Internal Server Error
35803579
schema:
35813580
$ref: '#/definitions/ErrorModel'
3581+
'/projects/{projectId}/invites/{inviteId}':
3582+
get:
3583+
tags:
3584+
- project member invite
3585+
operationId: getProjectMemberInvite
3586+
security:
3587+
- Bearer: []
3588+
description: >-
3589+
Get an invite. Users who can "view" this project can see this invitation.
3590+
User got invited by this inviteId can also see this invitation.
3591+
If project/invitation doesn't exist, or this invitation is not for logged-in user, it will return 404 response.
3592+
parameters:
3593+
- $ref: '#/parameters/projectIdParam'
3594+
- $ref: '#/parameters/inviteIdParam'
3595+
responses:
3596+
'200':
3597+
description: Returns the newly updated invite
3598+
schema:
3599+
$ref: '#/definitions/ProjectMemberInvite'
35823600
'403':
35833601
description: Forbidden
35843602
schema:
35853603
$ref: '#/definitions/ErrorModel'
3604+
'404':
3605+
description: Not Found
3606+
schema:
3607+
$ref: '#/definitions/ErrorModel'
35863608
'500':
35873609
description: Internal Server Error
35883610
schema:
35893611
$ref: '#/definitions/ErrorModel'
3590-
put:
3612+
patch:
35913613
tags:
35923614
- project member invite
35933615
operationId: updateProjectMemberInvite
@@ -3598,6 +3620,7 @@ paths:
35983620
restriction will be applied based on role to be updated.
35993621
parameters:
36003622
- $ref: '#/parameters/projectIdParam'
3623+
- $ref: '#/parameters/inviteIdParam'
36013624
- in: body
36023625
name: body
36033626
required: true
@@ -3607,19 +3630,50 @@ paths:
36073630
'200':
36083631
description: Returns the newly updated invite
36093632
schema:
3610-
$ref: '#/definitions/ProjectMemberInviteSuccessAndFailure'
3633+
$ref: '#/definitions/ProjectMemberInvite'
36113634
'400':
36123635
description: Bad request
36133636
schema:
36143637
$ref: '#/definitions/ErrorModel'
3615-
'401':
3616-
description: Unauthorized
3638+
'403':
3639+
description: Forbidden
3640+
schema:
3641+
$ref: '#/definitions/ErrorModel'
3642+
'404':
3643+
description: Not Found
3644+
schema:
3645+
$ref: '#/definitions/ErrorModel'
3646+
'500':
3647+
description: Internal Server Error
3648+
schema:
3649+
$ref: '#/definitions/ErrorModel'
3650+
delete:
3651+
tags:
3652+
- project member invite
3653+
operationId: deleteProjectMemberInvite
3654+
security:
3655+
- Bearer: []
3656+
description: >-
3657+
Cancel an invite. All users who can access this endpoint, however more
3658+
restriction will be applied based on role to be cancelled.
3659+
parameters:
3660+
- $ref: '#/parameters/projectIdParam'
3661+
- $ref: '#/parameters/inviteIdParam'
3662+
responses:
3663+
'204':
3664+
description: Cancel success
3665+
'400':
3666+
description: Bad request
36173667
schema:
36183668
$ref: '#/definitions/ErrorModel'
36193669
'403':
36203670
description: Forbidden
36213671
schema:
36223672
$ref: '#/definitions/ErrorModel'
3673+
'404':
3674+
description: Not Found
3675+
schema:
3676+
$ref: '#/definitions/ErrorModel'
36233677
'500':
36243678
description: Internal Server Error
36253679
schema:
@@ -4794,6 +4848,13 @@ parameters:
47944848
required: true
47954849
type: integer
47964850
format: int64
4851+
inviteIdParam:
4852+
name: inviteId
4853+
in: path
4854+
description: project member invite identifier
4855+
required: true
4856+
type: integer
4857+
format: int64
47974858
definitions:
47984859
ErrorModel:
47994860
type: object
@@ -6119,6 +6180,9 @@ definitions:
61196180
email:
61206181
type: string
61216182
description: The user email
6183+
hashEmail:
6184+
type: string
6185+
description: The email hash value
61226186
role:
61236187
description: The user role in the project
61246188
type: string
@@ -6156,26 +6220,41 @@ definitions:
61566220
type: object
61576221
properties:
61586222
success:
6159-
$ref: '#/definitions/ProjectMemberInvite'
6223+
type: array
6224+
items:
6225+
$ref: '#/definitions/ProjectMemberInvite'
61606226
failed:
61616227
type: array
61626228
items:
61636229
type: object
6230+
properties:
6231+
email:
6232+
description: invitation user email(Optional)
6233+
type: string
6234+
handle:
6235+
description: invitation user handle(Optional)
6236+
type: string
6237+
message:
6238+
description: create invitation error message
6239+
type: string
6240+
ProjectMemberInviteListResult:
6241+
type: array
6242+
items:
6243+
$ref: '#/definitions/ProjectMemberInvite'
61646244
AddProjectMemberInvitesRequest:
61656245
title: Add project member invites request object
61666246
type: object
61676247
properties:
6168-
userIds:
6169-
description: 'The user Id list, could not present with emails'
6248+
handles:
6249+
description: 'The user handle list, could not present with emails'
61706250
type: array
61716251
items:
6172-
type: integer
6173-
format: int64
6252+
type: string
61746253
emails:
61756254
type: array
61766255
items:
61776256
type: string
6178-
description: 'The user email list, could not present with userIds'
6257+
description: 'The user email list, could not present with handles'
61796258
role:
61806259
description: The target role in the project
61816260
type: string
@@ -6187,13 +6266,6 @@ definitions:
61876266
title: Update project member invite request object
61886267
type: object
61896268
properties:
6190-
userId:
6191-
type: integer
6192-
format: int64
6193-
description: 'The user Id, could not present with email'
6194-
email:
6195-
type: string
6196-
description: 'The user email, could not present with userId'
61976269
status:
61986270
description: The invite status
61996271
type: string

local/mock-services/server.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ server.use(authMiddleware);
2525
server.get('/v3/members/_search', (req, res) => {
2626
const fields = _.isString(req.query.fields) ? req.query.fields.split(',') : [];
2727
const filter = _.isString(req.query.query) ?
28-
req.query.query.replace('%2520', ' ').replace('%20', ' ').split(' OR ') : [];
28+
req.query.query.replace(/%2520/g, ' ').replace(/%20/g, ' ').split(' OR ') : [];
2929
const criteria = _.map(filter, (single) => {
3030
const ret = {};
3131
const splitted = single.split(':');
@@ -45,6 +45,7 @@ server.get('/v3/members/_search', (req, res) => {
4545
});
4646
const userIds = _.map(criteria, 'userId');
4747
const handles = _.map(criteria, 'handle');
48+
const handleLowers = _.map(criteria, 'handleLower');
4849
const cloned = _.cloneDeep(members);
4950
const response = {
5051
id: 'res1',
@@ -66,6 +67,12 @@ server.get('/v3/members/_search', (req, res) => {
6667
found = _.pick(found, fields);
6768
}
6869
return found;
70+
} else if (_.indexOf(handleLowers, single.result.content.handleLower) > -1) {
71+
let found = single.result.content;
72+
if (fields.length > 0) {
73+
found = _.pick(found, fields);
74+
}
75+
return found;
6976
}
7077
return null;
7178
}).filter(_.identity);
@@ -76,7 +83,7 @@ server.get('/v3/members/_search', (req, res) => {
7683

7784
// add filter route for project members
7885
server.get('/users', (req, res) => {
79-
const filter = req.query.filter.replace('%2520', ' ').replace('%20', ' ').replace('%3D', ' ');
86+
const filter = req.query.filter.replace(/%2520/g, ' ').replace(/%20/g, ' ').replace('%3D', ' ');
8087
const allEmails = filter.split('=')[1];
8188
const emails = allEmails.split('OR');
8289
const cloned = _.cloneDeep(members);
@@ -97,7 +104,7 @@ server.get('/users', (req, res) => {
97104
// add additional search route for project members
98105
server.get('/roles', (req, res) => {
99106
const filter = _.isString(req.query.filter) ?
100-
req.query.filter.replace('%2520', ' ').replace('%20', ' ').split('=') : [];
107+
req.query.filter.replace(/%2520/g, ' ').replace(/%20/g, ' ').split('=') : [];
101108
const cloned = _.cloneDeep(roles);
102109
const response = {
103110
id: 'res1',
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--
2+
-- UPDATE EXISTING TABLES:
3+
-- project_member_invites:
4+
-- added column `hashEmail`
5+
6+
--
7+
-- project_member_invites
8+
9+
-- Add new column
10+
ALTER TABLE project_member_invites ADD COLUMN "hashEmail" character varying(255) ;

0 commit comments

Comments
 (0)