From 761c3d0a0fc9c46d7b69571dc6ad7f3845d89854 Mon Sep 17 00:00:00 2001 From: "Mr. Lance E Sloan (lsloan)" Date: Mon, 20 Dec 2021 16:31:36 -0500 Subject: [PATCH] #252 - check for user existence @ssciolla: I'm not sure whether I wrote this API entry with the security we would like. Give me feedback. --- ccm_web/server/src/api/api.admin.handler.ts | 36 ++++++++++++++++++++- ccm_web/server/src/api/api.controller.ts | 12 ++++++- ccm_web/server/src/api/api.service.ts | 6 ++++ 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/ccm_web/server/src/api/api.admin.handler.ts b/ccm_web/server/src/api/api.admin.handler.ts index 5ab6a311d..3999f6815 100644 --- a/ccm_web/server/src/api/api.admin.handler.ts +++ b/ccm_web/server/src/api/api.admin.handler.ts @@ -5,7 +5,8 @@ import { APIErrorData, isAPIErrorData } from './api.interfaces' import { handleAPIError, HttpMethod, makeResponse } from './api.utils' import { CanvasAccount, - CanvasCourse, CanvasUser, + CanvasCourse, + CanvasUser, CourseWithSections, CourseWorkflowState } from '../canvas/canvas.interfaces' @@ -176,4 +177,37 @@ export class AdminApiHandler { return createUserResponses } + + async getUserInfo (loginId: string): Promise { + const safeLoginId = loginId.replace('@', '+') + + try { + const endpoint = `users/sis_login_id:${safeLoginId}` + const method = HttpMethod.Get + logger.debug(`Sending admin request to Canvas endpoint: "${endpoint}"; method: "${method}"`) + const response = await this.requestor.get(endpoint) + logger.debug(`Received response with status code (${String(response.statusCode)})`) + const { + id, + name, + sortable_name, // eslint-disable-line + short_name // eslint-disable-line + } = response.body + return { + id, + name, + sortable_name, + short_name, + login_id: loginId, + email: undefined as any + } + } catch (error) { + const errorResponse = handleAPIError(error, `Login ID: ${loginId}`) + return { + statusCode: errorResponse.canvasStatusCode, + errors: [errorResponse] + } + } + + } } diff --git a/ccm_web/server/src/api/api.controller.ts b/ccm_web/server/src/api/api.controller.ts index 919fa4199..eeff69aac 100644 --- a/ccm_web/server/src/api/api.controller.ts +++ b/ccm_web/server/src/api/api.controller.ts @@ -15,7 +15,7 @@ import { SectionUserDto, SectionUsersDto } from './dtos/api.section.users.dto' import { JwtAuthGuard } from '../auth/jwt-auth.guard' import { SessionGuard } from '../auth/session.guard' import { - CanvasCourseBase, CanvasCourseSection, CanvasCourseSectionBase, CanvasEnrollment, CourseWithSections + CanvasCourseBase, CanvasCourseSection, CanvasCourseSectionBase, CanvasEnrollment, CourseWithSections, CanvasUser } from '../canvas/canvas.interfaces' import { InvalidTokenInterceptor } from '../canvas/invalid.token.interceptor' import { UserDec } from '../user/user.decorator' @@ -103,6 +103,16 @@ export class APIController { return result } + @UseInterceptors(InvalidTokenInterceptor) @Get('admin/user/:loginId') + async getUserInfoAsAdmin ( + @Param('loginId') loginId: string, + @UserDec() user: User + ): Promise { + const result = await this.apiService.getUserInfoAsAdmin(user, loginId) + if (isAPIErrorData(result)) throw new HttpException(result, result.statusCode) + return result + } + @UseInterceptors(InvalidTokenInterceptor) @Get('instructor/sections') async getCourseSectionsInTermAsInstructor ( diff --git a/ccm_web/server/src/api/api.service.ts b/ccm_web/server/src/api/api.service.ts index 1a0018f06..a6c6e427b 100644 --- a/ccm_web/server/src/api/api.service.ts +++ b/ccm_web/server/src/api/api.service.ts @@ -151,6 +151,12 @@ export class APIService { }) } + async getUserInfoAsAdmin (user: User, loginId: string): Promise { + const adminRequestor = this.canvasService.createRequestorForAdmin('/api/v1/') + const adminHandler = new AdminApiHandler(adminRequestor, user.loginId) + return await adminHandler.getUserInfo(loginId) + } + async mergeSections (user: User, targetCourseId: number, sectionIds: number[]): Promise { const requestor = await this.canvasService.createRequestorForUser(user, '/api/v1/') const courseHandler = new CourseApiHandler(requestor, targetCourseId)