Skip to content

Commit 439527c

Browse files
authored
Merge pull request #161 from imcaizheng/new-endpoint-taas-team-me
Add new endpoint `GET /taas-teams/me`
2 parents 8f1d3bb + a6587cc commit 439527c

File tree

6 files changed

+146
-20
lines changed

6 files changed

+146
-20
lines changed

docs/Topcoder-bookings-api.postman_collection.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4694,6 +4694,36 @@
46944694
}
46954695
},
46964696
"response": []
4697+
},
4698+
{
4699+
"name": "GET /taas-teams/me",
4700+
"request": {
4701+
"method": "GET",
4702+
"header": [
4703+
{
4704+
"key": "Authorization",
4705+
"type": "text",
4706+
"value": "Bearer {{token_member}}"
4707+
}
4708+
],
4709+
"url": {
4710+
"raw": "{{URL}}/taas-teams/me?enrich=true",
4711+
"host": [
4712+
"{{URL}}"
4713+
],
4714+
"path": [
4715+
"taas-teams",
4716+
"me"
4717+
],
4718+
"query": [
4719+
{
4720+
"key": "enrich",
4721+
"value": "true"
4722+
}
4723+
]
4724+
}
4725+
},
4726+
"response": []
46974727
}
46984728
]
46994729
},

docs/swagger.yaml

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1894,6 +1894,59 @@ paths:
18941894
application/json:
18951895
schema:
18961896
$ref: '#/components/schemas/Error'
1897+
1898+
/taas-teams/me:
1899+
get:
1900+
tags:
1901+
- Teams
1902+
description: |
1903+
Return details about the current user.
1904+
security:
1905+
- bearerAuth: []
1906+
parameters:
1907+
- in: query
1908+
name: enrich
1909+
required: false
1910+
schema:
1911+
type: boolean
1912+
description: whether to return enriched data or not.
1913+
responses:
1914+
'200':
1915+
description: OK
1916+
content:
1917+
application/json:
1918+
schema:
1919+
$ref: '#/components/schemas/UbahnUser'
1920+
'400':
1921+
description: Bad request
1922+
content:
1923+
application/json:
1924+
schema:
1925+
$ref: '#/components/schemas/Error'
1926+
'401':
1927+
description: Not authenticated
1928+
content:
1929+
application/json:
1930+
schema:
1931+
$ref: '#/components/schemas/Error'
1932+
'403':
1933+
description: Forbidden
1934+
content:
1935+
application/json:
1936+
schema:
1937+
$ref: '#/components/schemas/Error'
1938+
'404':
1939+
description: Not Found
1940+
content:
1941+
application/json:
1942+
schema:
1943+
$ref: '#/components/schemas/Error'
1944+
'500':
1945+
description: Internal Server Error
1946+
content:
1947+
application/json:
1948+
schema:
1949+
$ref: '#/components/schemas/Error'
18971950
/health:
18981951
get:
18991952
tags:
@@ -2719,10 +2772,13 @@ components:
27192772
example: 'xxx@xxx.com'
27202773
ProjectMember:
27212774
type: object
2722-
example: {"id": 14329, "userId": 40159097, "role": "customer", "createdAt": "2021-02-24T12:34:45.074Z", "updatedAt": "2021-02-24T12:34:45.075Z", "createdBy": -101, "updatedBy": -101, "handle": "tester1234", "photoURL": null, "workingHourStart": "9:00", "workingHourEnd": "17:00", "timeZone": "Asia/Kolkata", "email": "sathya.jayabal@gmail.com"}
2775+
example: {"id": 14329, "userId": 40159097, "role": "customer", "createdAt": "2021-02-24T12:34:45.074Z", "updatedAt": "2021-02-24T12:34:45.075Z", "createdBy": -101, "updatedBy": -101, "handle": "tester1234", "photoURL": null, "workingHourStart": "9:00", "workingHourEnd": "17:00", "timeZone": "Asia/Kolkata", "email": "xxx@xxx.com"}
27232776
ProjectMemberInvite:
27242777
type: object
27252778
example: {"createdAt": "2021-02-24T11:02:12.673Z", "deletedAt": null, "role": "customer", "updatedBy": -101, "createdBy": -101, "id": 3686, "projectId": 16705, "userId": 23008602, "email": null, "deletedBy": null, "updatedAt": "2021-02-24T11:02:12.674Z", "status": "pending"}
2779+
UbahnUser:
2780+
type: object
2781+
example: {"lastName": "DeLaurentis", "updatedBy": "tcAdmin", "achievements": [{"certifierId": "certifierId", "updatedBy": "tcAdmin", "createdBy": "tc-user", "certifiedDate": "2020-05-04T07:36:28.036Z", "created": "2020-05-13T08:44:27.244Z", "name": "Topcoder", "id": "a49e1013-fd42-4c08-bc12-492510cadb96", "achievementsProviderId": "ce05133f-129e-484d-9ef9-72bf51ff81f9", "uri": "http://www.google.com/xx", "updated": "2021-01-05T10:58:32.429Z", "userId": "0bcb0d86-09bb-410a-b2b1-fba90d1a7699", "achievementprovider": {"updatedBy": "tcAdmin", "createdBy": "tc-user", "created": "2020-05-13T08:42:41.877Z", "name": "achievementsProviders_02", "id": "ce05133f-129e-484d-9ef9-72bf51ff81f9", "updated": "2021-01-05T10:58:32.341Z"}}], "created": "2020-05-05T10:18:03.882Z", "handle": "lazybaer", "skills": [{"certifierId": null, "skillId": "d67f35c3-fa42-4866-a0f9-0a4b84fcf4a9", "updatedBy": "tcAdmin", "createdBy": "lazybaer", "certifiedDate": null, "created": "2020-10-23T16:22:11.208Z", "skill": {"updatedBy": "tcAdmin", "skillprovider": {"updatedBy": "tcAdmin", "createdBy": "TonyJ", "created": "2020-08-31T12:30:00.543Z", "name": "Wipro Digital", "id": "26fb37b1-5f9f-4727-baa9-f3c87de84ab1", "updated": "2021-01-05T10:58:32.836Z"}, "createdBy": "0", "created": "2020-09-01T21:59:21.554Z", "skillProviderId": "26fb37b1-5f9f-4727-baa9-f3c87de84ab1", "name": "GitHub", "externalId": null, "id": "d67f35c3-fa42-4866-a0f9-0a4b84fcf4a9", "uri": null, "updated": "2021-01-05T10:58:33.332Z"}, "metricValue": null, "id": "8a84c1b4-1884-4a3c-90b2-eb86bf469bb6", "updated": "2021-01-05T10:58:34.080Z", "userId": "0bcb0d86-09bb-410a-b2b1-fba90d1a7699"}], "firstName": "Christopher", "externalProfiles": [{"organizationId": "0d2320f9-be61-4ba4-973e-edc3bb682a69", "updatedBy": "tcAdmin", "createdBy": "TonyJ", "isInactive": false, "created": "2020-08-31T12:30:38.495Z", "organization": {"updatedBy": "tcAdmin", "createdBy": "TonyJ", "created": "2020-08-31T12:29:58.081Z", "name": "Wipro Digital", "skillProviders": [{"organizationId": "0d2320f9-be61-4ba4-973e-edc3bb682a69", "updatedBy": "tcAdmin", "createdBy": "TonyJ", "created": "2020-08-31T12:30:08.410Z", "skillProviderId": "26fb37b1-5f9f-4727-baa9-f3c87de84ab1", "id": "5b26cdd3-fe68-4b30-85c5-ceaf280bd688", "updated": "2021-01-05T10:58:32.919Z"}], "id": "0d2320f9-be61-4ba4-973e-edc3bb682a69", "updated": "2021-01-05T10:58:32.261Z"}, "externalId": "8547899", "id": "870af97b-8c3b-4659-92d6-cac126bbe9de", "uri": null, "updated": "2021-01-05T10:58:32.724Z", "userId": "0bcb0d86-09bb-410a-b2b1-fba90d1a7699"}], "createdBy": "tc-Copilot", "attributes": [{"attributeId": "d709276a-80c3-491c-9b29-a4f065b2a56f", "updatedBy": "tcAdmin", "createdBy": "tc-Admin", "created": "2020-05-13T08:19:13.709Z", "id": "21de9324-900d-41ea-b127-f297dfb9a873", "attribute": {"updatedBy": "tcAdmin", "attributegroup": {"organizationId": "36ed815b-3da1-49f1-a043-aaed0a4e81ad", "updatedBy": "tc-Admin", "createdBy": "tc-Admin", "created": "2020-05-13T07:15:01.215Z", "name": "group 03", "id": "84634bbd-8191-40cf-a03e-9962d7e39fda", "updated": "2020-05-13T07:16:20.636Z"}, "createdBy": "tc-Admin", "created": "2020-05-13T07:32:03.128Z", "name": "Billing Account", "id": "d709276a-80c3-491c-9b29-a4f065b2a56f", "attributeGroupId": "84634bbd-8191-40cf-a03e-9962d7e39fda", "updated": "2021-01-05T10:58:32.604Z"}, "value": "74314457", "updated": "2021-01-05T10:58:33.739Z", "userId": "0bcb0d86-09bb-410a-b2b1-fba90d1a7699"}], "id": "0bcb0d86-09bb-410a-b2b1-fba90d1a7699", "updated": "2021-01-05T10:58:32.113Z"}
27262782
Error:
27272783
required:
27282784
- message

src/common/helper.js

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -598,17 +598,18 @@ function encodeQueryString (queryObj, nesting = '') {
598598
}
599599

600600
/**
601-
* Function to get user ids
602-
* @param {Integer} userId user id from jwt token
603-
* @returns {String} user id.
601+
* Function to list users by external id.
602+
* @param {Integer} externalId the legacy user id
603+
* @param {Boolean} enrich whether to return enriched data or not
604+
* @returns {Array} the users found
604605
*/
605-
async function getUserIds (userId) {
606+
async function listUsersByExternalId (externalId, enrich = false) {
606607
const token = await getM2MUbahnToken()
607608
const q = {
608-
enrich: true,
609+
enrich,
609610
externalProfile: {
610611
organizationId: config.ORG_ID,
611-
externalId: userId
612+
externalId
612613
}
613614
}
614615
const url = `${config.TC_API}/users?${encodeQueryString(q)}`
@@ -617,21 +618,22 @@ async function getUserIds (userId) {
617618
.set('Authorization', `Bearer ${token}`)
618619
.set('Content-Type', 'application/json')
619620
.set('Accept', 'application/json')
620-
localLogger.debug({ context: 'getUserIds', message: `response body: ${JSON.stringify(res.body)}` })
621+
localLogger.debug({ context: 'listUserByExternalId', message: `response body: ${JSON.stringify(res.body)}` })
621622
return res.body
622623
}
623624

624625
/**
625-
* Function to get user id
626-
* @param {Integer} userId user id from jwt token
627-
* @returns {String} user id.
626+
* Function to get user by external id.
627+
* @param {Integer} externalId the legacy user id
628+
* @param {Boolean} enrich whether to return enriched data or not
629+
* @returns {Object} the user
628630
*/
629-
async function getUserId (userId) {
630-
const ids = await getUserIds(userId)
631-
if (_.isEmpty(ids)) {
632-
throw new errors.NotFoundError(`userId: ${userId} "user" not found`)
631+
async function getUserByExternalId (externalId, enrich) {
632+
const users = await listUsersByExternalId(externalId, enrich)
633+
if (_.isEmpty(users)) {
634+
throw new errors.NotFoundError(`externalId: ${externalId} "user" not found`)
633635
}
634-
return ids[0].id
636+
return users[0]
635637
}
636638

637639
/**
@@ -883,7 +885,7 @@ async function getSkillById (skillId) {
883885
}
884886

885887
/**
886-
* Encapsulate the getUserId function.
888+
* Encapsulate the getUserByExternalId function.
887889
* Make sure a user exists in ubahn(/v5/users) and return the id of the user.
888890
*
889891
* In the case the user does not exist in /v5/users but can be found in /v3/users
@@ -894,7 +896,7 @@ async function getSkillById (skillId) {
894896
*/
895897
async function ensureUbahnUserId (currentUser) {
896898
try {
897-
return await getUserId(currentUser.userId)
899+
return (await getUserByExternalId(currentUser.userId, true)).id
898900
} catch (err) {
899901
if (!(err instanceof errors.NotFoundError)) {
900902
throw err
@@ -1138,6 +1140,7 @@ module.exports = {
11381140
}
11391141
return ensureUbahnUserId({ userId })
11401142
},
1143+
getUserByExternalId,
11411144
getM2MToken,
11421145
getM2MUbahnToken,
11431146
postEvent,

src/controllers/TeamController.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,15 @@ async function deleteMember (req, res) {
8383
res.status(HttpStatus.NO_CONTENT).end()
8484
}
8585

86+
/**
87+
* Return details about the current user.
88+
* @param req the request
89+
* @param res the response
90+
*/
91+
async function getMe (req, res) {
92+
res.send(await service.getMe(req.authUser, req.query))
93+
}
94+
8695
module.exports = {
8796
searchTeams,
8897
getTeam,
@@ -91,5 +100,6 @@ module.exports = {
91100
addMembers,
92101
searchMembers,
93102
searchInvites,
94-
deleteMember
103+
deleteMember,
104+
getMe
95105
}

src/routes/TeamRoutes.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ module.exports = {
2828
scopes: [constants.Scopes.READ_TAAS_TEAM]
2929
}
3030
},
31+
'/taas-teams/me': {
32+
get: {
33+
controller: 'TeamController',
34+
method: 'getMe',
35+
auth: 'jwt',
36+
scopes: [constants.Scopes.READ_TAAS_TEAM]
37+
}
38+
},
3139
'/taas-teams/:id': {
3240
get: {
3341
controller: 'TeamController',

src/services/TeamService.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,24 @@ deleteMember.schema = Joi.object().keys({
513513
projectMemberId: Joi.number().integer().required()
514514
}).required()
515515

516+
/**
517+
* Return details about the current user.
518+
*
519+
* @param {Object} currentUser the user who perform this operation.
520+
* @params {Object} criteria the search criteria
521+
* @returns {Object} the user data for current user
522+
*/
523+
async function getMe (currentUser, criteria) {
524+
return helper.getUserByExternalId(currentUser.userId, criteria.enrich)
525+
}
526+
527+
getMe.schema = Joi.object().keys({
528+
currentUser: Joi.object().required(),
529+
criteria: Joi.object().keys({
530+
enrich: Joi.boolean()
531+
}).required()
532+
}).required()
533+
516534
module.exports = {
517535
searchTeams,
518536
getTeam,
@@ -521,5 +539,6 @@ module.exports = {
521539
addMembers,
522540
searchMembers,
523541
searchInvites,
524-
deleteMember
542+
deleteMember,
543+
getMe
525544
}

0 commit comments

Comments
 (0)