diff --git a/src/main/resources/swagger/api-docs.yaml b/src/main/resources/swagger/api-docs.yaml index 33cf4f925..eb96ece53 100755 --- a/src/main/resources/swagger/api-docs.yaml +++ b/src/main/resources/swagger/api-docs.yaml @@ -98,6 +98,34 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorReport' + /api/admin/v2/user/{userId}/repairCloudAccess: + get: + tags: + - Admin + summary: Ensures that a user's proxy group exists and that it is added to any google groups that it should be in. + operationId: adminRepairUserCloudAccess + parameters: + - name: userId + in: path + description: User ID of the user to have their cloud access repaired + required: true + schema: + type: string + responses: + 204: + description: User access was repaired successfully (as long as the group sync messages succeed) + 403: + description: You do not have admin privileges + content: { } + 404: + description: User not found + content: { } + 500: + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorReport' /api/admin/v1/user/email/{email}: get: tags: diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/AdminRoutes.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/AdminRoutes.scala index 0ac4f07ed..3e2629276 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/AdminRoutes.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/AdminRoutes.scala @@ -11,6 +11,7 @@ import cats.effect.IO import org.broadinstitute.dsde.workbench.model._ import org.broadinstitute.dsde.workbench.model.google.GoogleProject import org.broadinstitute.dsde.workbench.sam.config.LiquibaseConfig +import org.broadinstitute.dsde.workbench.sam.dataAccess.DirectoryDAO import org.broadinstitute.dsde.workbench.sam.model.api.SamJsonSupport._ import org.broadinstitute.dsde.workbench.sam.model.SamResourceActions.{adminAddMember, adminReadPolicies, adminRemoveMember} import org.broadinstitute.dsde.workbench.sam.model.SamResourceTypes.resourceTypeAdminName @@ -28,6 +29,7 @@ trait AdminRoutes extends SecurityDirectives with SamRequestContextDirectives wi implicit val executionContext: ExecutionContext val resourceService: ResourceService + val directoryDAO: DirectoryDAO val managedGroupService: ManagedGroupService val liquibaseConfig: LiquibaseConfig @@ -145,6 +147,14 @@ trait AdminRoutes extends SecurityDirectives with SamRequestContextDirectives wi .map(user => (if (user.isDefined) OK else NotFound) -> user) } } + } ~ + pathPrefix("repairCloudAccess") { + putWithTelemetry(samRequestContext, userIdParam(workbenchUserId)) { + complete { + repairCloudAccess(workbenchUserId, samRequestContext) + .map(_ => NoContent) + } + } } } } @@ -265,6 +275,17 @@ trait AdminRoutes extends SecurityDirectives with SamRequestContextDirectives wi } } } + def repairCloudAccess(workbenchUserId: WorkbenchUserId, samRequestContext: SamRequestContext): IO[Unit] = { + for { + maybeUser <- userService + .getUser(workbenchUserId, samRequestContext = samRequestContext) + user = maybeUser.getOrElse(throw new WorkbenchExceptionWithErrorReport(ErrorReport(StatusCodes.NotFound, s"User ${workbenchUserId.value} not found"))) + _ <- cloudExtensions.onUserCreate(user, samRequestContext) + groups <- directoryDAO.listUserDirectMemberships(user.id, samRequestContext) + _ <- cloudExtensions.onGroupUpdate(groups, Set(user.id), samRequestContext) + } yield IO.pure(()) + } + def requireAdminResourceAction(action: ResourceAction, resourceType: ResourceType, user: SamUser, samRequestContext: SamRequestContext): Directive0 = requireAction(