diff --git a/docs/Topcoder-bookings-api.postman_collection.json b/docs/Topcoder-bookings-api.postman_collection.json index ec79947b..9b3b3f8e 100644 --- a/docs/Topcoder-bookings-api.postman_collection.json +++ b/docs/Topcoder-bookings-api.postman_collection.json @@ -4694,6 +4694,30 @@ } }, "response": [] + }, + { + "name": "GET /taas-teams/me", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member}}" + } + ], + "url": { + "raw": "{{URL}}/taas-teams/me", + "host": [ + "{{URL}}" + ], + "path": [ + "taas-teams", + "me" + ] + } + }, + "response": [] } ] }, @@ -9810,4 +9834,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 5b8f7d2b..fb38c7ef 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1894,6 +1894,52 @@ paths: application/json: schema: $ref: '#/components/schemas/Error' + + /taas-teams/me: + get: + tags: + - Teams + description: | + Return details about the current user. + security: + - bearerAuth: [] + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/UbahnUser' + '400': + description: Bad request + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '401': + description: Not authenticated + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '404': + description: Not Found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' /health: get: tags: @@ -2719,10 +2765,13 @@ components: example: 'xxx@xxx.com' ProjectMember: type: object - 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"} + 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"} ProjectMemberInvite: type: object 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"} + UbahnUser: + type: object + 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"} Error: required: - message diff --git a/src/common/helper.js b/src/common/helper.js index 50adc94b..0f456215 100644 --- a/src/common/helper.js +++ b/src/common/helper.js @@ -598,17 +598,17 @@ function encodeQueryString (queryObj, nesting = '') { } /** - * Function to get user ids - * @param {Integer} userId user id from jwt token - * @returns {String} user id. + * Function to list users by external id. + * @param {Integer} externalId the legacy user id + * @returns {Array} the users found */ -async function getUserIds (userId) { +async function listUsersByExternalId (externalId) { const token = await getM2MUbahnToken() const q = { enrich: true, externalProfile: { organizationId: config.ORG_ID, - externalId: userId + externalId } } const url = `${config.TC_API}/users?${encodeQueryString(q)}` @@ -617,21 +617,21 @@ async function getUserIds (userId) { .set('Authorization', `Bearer ${token}`) .set('Content-Type', 'application/json') .set('Accept', 'application/json') - localLogger.debug({ context: 'getUserIds', message: `response body: ${JSON.stringify(res.body)}` }) + localLogger.debug({ context: 'listUserByExternalId', message: `response body: ${JSON.stringify(res.body)}` }) return res.body } /** - * Function to get user id - * @param {Integer} userId user id from jwt token - * @returns {String} user id. + * Function to get user by external id. + * @param {Integer} externalId the legacy user id + * @returns {Object} the user */ -async function getUserId (userId) { - const ids = await getUserIds(userId) - if (_.isEmpty(ids)) { - throw new errors.NotFoundError(`userId: ${userId} "user" not found`) +async function getUserByExternalId (externalId) { + const users = await listUsersByExternalId(externalId) + if (_.isEmpty(users)) { + throw new errors.NotFoundError(`externalId: ${externalId} "user" not found`) } - return ids[0].id + return users[0] } /** @@ -883,7 +883,7 @@ async function getSkillById (skillId) { } /** - * Encapsulate the getUserId function. + * Encapsulate the getUserByExternalId function. * Make sure a user exists in ubahn(/v5/users) and return the id of the user. * * In the case the user does not exist in /v5/users but can be found in /v3/users @@ -894,7 +894,7 @@ async function getSkillById (skillId) { */ async function ensureUbahnUserId (currentUser) { try { - return await getUserId(currentUser.userId) + return (await getUserByExternalId(currentUser.userId)).id } catch (err) { if (!(err instanceof errors.NotFoundError)) { throw err @@ -1138,6 +1138,7 @@ module.exports = { } return ensureUbahnUserId({ userId }) }, + getUserByExternalId, getM2MToken, getM2MUbahnToken, postEvent, diff --git a/src/controllers/TeamController.js b/src/controllers/TeamController.js index 6cf1a6b4..b8f7c149 100644 --- a/src/controllers/TeamController.js +++ b/src/controllers/TeamController.js @@ -83,6 +83,15 @@ async function deleteMember (req, res) { res.status(HttpStatus.NO_CONTENT).end() } +/** + * Return details about the current user. + * @param req the request + * @param res the response + */ +async function getMe (req, res) { + res.send(await service.getMe(req.authUser)) +} + module.exports = { searchTeams, getTeam, @@ -91,5 +100,6 @@ module.exports = { addMembers, searchMembers, searchInvites, - deleteMember + deleteMember, + getMe } diff --git a/src/routes/TeamRoutes.js b/src/routes/TeamRoutes.js index 3df14b0c..f5d062c6 100644 --- a/src/routes/TeamRoutes.js +++ b/src/routes/TeamRoutes.js @@ -28,6 +28,14 @@ module.exports = { scopes: [constants.Scopes.READ_TAAS_TEAM] } }, + '/taas-teams/me': { + get: { + controller: 'TeamController', + method: 'getMe', + auth: 'jwt', + scopes: [constants.Scopes.READ_TAAS_TEAM] + } + }, '/taas-teams/:id': { get: { controller: 'TeamController', diff --git a/src/services/TeamService.js b/src/services/TeamService.js index 640791a2..0519543e 100644 --- a/src/services/TeamService.js +++ b/src/services/TeamService.js @@ -513,6 +513,21 @@ deleteMember.schema = Joi.object().keys({ projectMemberId: Joi.number().integer().required() }).required() +/** + * Return details about the current user. + * + * @param {Object} currentUser the user who perform this operation. + * @params {Object} criteria the search criteria + * @returns {Object} the user data for current user + */ +async function getMe (currentUser) { + return helper.getUserByExternalId(currentUser.userId) +} + +getMe.schema = Joi.object().keys({ + currentUser: Joi.object().required() +}).required() + module.exports = { searchTeams, getTeam, @@ -521,5 +536,6 @@ module.exports = { addMembers, searchMembers, searchInvites, - deleteMember + deleteMember, + getMe }