Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ID-690 Get User(s) Endpoint v2 #1208

Merged
merged 12 commits into from
Oct 19, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import org.broadinstitute.dsde.workbench.sam.db.TestDbReference
import org.broadinstitute.dsde.workbench.sam.db.tables._
import org.broadinstitute.dsde.workbench.sam.google.{GoogleExtensionRoutes, GoogleExtensions, GoogleGroupSynchronizer, GoogleKeyCache}
import org.broadinstitute.dsde.workbench.sam.model._
import org.broadinstitute.dsde.workbench.sam.model.api.SamUser
import org.broadinstitute.dsde.workbench.sam.service.UserService._
import org.broadinstitute.dsde.workbench.sam.service._
import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import org.broadinstitute.dsde.workbench.sam.azure.AzureService
import org.broadinstitute.dsde.workbench.sam.dataAccess.{AccessPolicyDAO, DirectoryDAO, StatefulMockAccessPolicyDaoBuilder}
import org.broadinstitute.dsde.workbench.sam.google.GoogleExtensions
import org.broadinstitute.dsde.workbench.sam.model._
import org.broadinstitute.dsde.workbench.sam.model.api.SamUser
import org.broadinstitute.dsde.workbench.sam.service._
import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext
import org.broadinstitute.dsde.workbench.sam.{Generator, MockSamDependencies, MockTestSupport}
Expand Down
86 changes: 86 additions & 0 deletions src/main/resources/swagger/api-docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2793,6 +2793,54 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/ErrorReport'
/api/users/v2/self:
get:
tags:
- Users
summary: gets the user
operationId: getSamUserSelf
responses:
200:
description: user exists
content:
application/json:
schema:
$ref: '#/components/schemas/SamUserResponse'
404:
description: user not found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorReport'
/api/users/v2/{sam_user_id}:
get:
tags:
- Admin
summary: gets a user
description: Gets a SamUser by their id. This endpoint is scoped to the permissions of the caller.
A normal user can call the endpoint with their own id, but trying to get another user will result in a 404.
Admin permissions grant the caller the ability to get any id.
operationId: getSamUserById
parameters:
- name: sam_user_id
in: path
description: the id of the sam user to get
required: true
schema:
type: string
responses:
200:
description: user exists
content:
application/json:
schema:
$ref: '#/components/schemas/SamUserResponse'
404:
description: user not found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorReport'
/register/user/v1:
get:
tags:
Expand Down Expand Up @@ -3799,6 +3847,44 @@ components:
format: date-time
description: User's time of last update
description: specification of a User
SamUserResponse:
type: object
required:
- id
- email
- allowed
- createdAt
- updatedAt
properties:
id:
type: string
description: User's Id
googleSubjectId:
type: string
description: User's Google subject Id
email:
type: string
description: User's email address
format: email
azureB2CId:
type: string
description: User's Azure B2C Id
allowed:
type: boolean
description: Whether or not the user allowed to use the system
createdAt:
type: string
format: date-time
description: User's time of creation
registeredAt:
type: string
format: date-time
description: User's time of registration
updatedAt:
type: string
format: date-time
description: User's time of last update
description: specification of a User
UpdateUserRequest:
type: object
properties:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import akka.http.scaladsl.server.Directives._
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.model.SamJsonSupport._
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
import org.broadinstitute.dsde.workbench.sam.model._
import org.broadinstitute.dsde.workbench.sam.model.api.{AccessPolicyMembershipRequest, AdminUpdateUserRequest}
import org.broadinstitute.dsde.workbench.sam.model.api.{AccessPolicyMembershipRequest, AdminUpdateUserRequest, SamUser}
import org.broadinstitute.dsde.workbench.sam.service.ResourceService
import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext
import spray.json.DefaultJsonProtocol._
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.broadinstitute.dsde.workbench.sam.api

import akka.http.scaladsl.server
import org.broadinstitute.dsde.workbench.sam.model.SamUser
import org.broadinstitute.dsde.workbench.sam.model.api.SamUser
import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext

trait ExtensionRoutes {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import org.broadinstitute.dsde.workbench.model.WorkbenchIdentityJsonSupport._
import org.broadinstitute.dsde.workbench.model._
import org.broadinstitute.dsde.workbench.sam._
import org.broadinstitute.dsde.workbench.sam.model.{ResourceId, _}
import org.broadinstitute.dsde.workbench.sam.model.SamJsonSupport._
import org.broadinstitute.dsde.workbench.sam.model.api.SamJsonSupport._
import org.broadinstitute.dsde.workbench.sam.model.api.SamUser
import org.broadinstitute.dsde.workbench.sam.service.ManagedGroupService
import org.broadinstitute.dsde.workbench.sam.service.ManagedGroupService.ManagedGroupPolicyName
import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import akka.http.scaladsl.server
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.{Directive0, ExceptionHandler}
import org.broadinstitute.dsde.workbench.model._
import org.broadinstitute.dsde.workbench.sam.model.SamJsonSupport._
import org.broadinstitute.dsde.workbench.sam.model.SamUser
import org.broadinstitute.dsde.workbench.sam.model.api.SamJsonSupport._
import org.broadinstitute.dsde.workbench.sam.service.UserService
import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext
import spray.json.JsBoolean
Expand All @@ -17,7 +16,7 @@ import scala.concurrent.ExecutionContext

/** Created by mbemis on 5/22/17.
*/
trait UserRoutes extends SamUserDirectives with SamRequestContextDirectives {
trait OldUserRoutes extends SamUserDirectives with SamRequestContextDirectives {
implicit val executionContext: ExecutionContext
val userService: UserService

Expand All @@ -33,7 +32,7 @@ trait UserRoutes extends SamUserDirectives with SamRequestContextDirectives {
})
}

def userRoutes(samRequestContext: SamRequestContext): server.Route =
def oldUserRoutes(samRequestContext: SamRequestContext): server.Route =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should mark this as deprecated

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should only mark as deprecated once all the functionality is implemented in the V2 routes

pathPrefix("user") {
(pathPrefix("v1") | pathEndOrSingleSlash) {
pathEndOrSingleSlash {
Expand Down Expand Up @@ -151,33 +150,4 @@ trait UserRoutes extends SamUserDirectives with SamRequestContextDirectives {
}
}
}

def apiUserRoutes(samUser: SamUser, samRequestContext: SamRequestContext): server.Route = pathPrefix("users") {
Ghost-in-a-Jar marked this conversation as resolved.
Show resolved Hide resolved
pathPrefix("v1") {
get {
path(Segment) { email =>
pathEnd {
complete {
userService.getUserIdInfoFromEmail(WorkbenchEmail(email), samRequestContext).map {
case Left(_) => StatusCodes.NotFound -> None
case Right(None) => StatusCodes.NoContent -> None
case Right(Some(userIdInfo)) => StatusCodes.OK -> Some(userIdInfo)
}
}
}
}
} ~
pathPrefix("invite") {
post {
path(Segment) { inviteeEmail =>
complete {
userService
.inviteUser(WorkbenchEmail(inviteeEmail.trim), samRequestContext)
.map(userStatus => StatusCodes.Created -> userStatus)
}
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import org.broadinstitute.dsde.workbench.model.WorkbenchIdentityJsonSupport._
import org.broadinstitute.dsde.workbench.model._
import org.broadinstitute.dsde.workbench.sam.config.LiquibaseConfig
import org.broadinstitute.dsde.workbench.sam.model.RootPrimitiveJsonSupport._
import org.broadinstitute.dsde.workbench.sam.model.SamJsonSupport._
import org.broadinstitute.dsde.workbench.sam.model.api.SamJsonSupport._
import org.broadinstitute.dsde.workbench.sam.model._
import org.broadinstitute.dsde.workbench.sam.model.api.AccessPolicyMembershipRequest
import org.broadinstitute.dsde.workbench.sam.model.api.{AccessPolicyMembershipRequest, SamUser}
import org.broadinstitute.dsde.workbench.sam.service.ResourceService
import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext
import spray.json.DefaultJsonProtocol._
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,16 @@ abstract class SamRoutes(
val openTelemetry: OpenTelemetryMetrics[IO]
) extends LazyLogging
with ResourceRoutes
with UserRoutes
with OldUserRoutes
with StatusRoutes
with TermsOfServiceRoutes
with ExtensionRoutes
with ManagedGroupRoutes
with AdminRoutes
with AzureRoutes
with ServiceAdminRoutes {
with ServiceAdminRoutes
with UserRoutesV1
with UserRoutesV2 {

def route: server.Route = (logRequestResult & handleExceptions(myExceptionHandler)) {
oidcConfig.swaggerRoutes("swagger/api-docs.yaml") ~
Expand All @@ -64,7 +66,7 @@ abstract class SamRoutes(
termsOfServiceRoutes ~
withExecutionContext(ExecutionContext.global) {
withSamRequestContext { samRequestContext =>
pathPrefix("register")(userRoutes(samRequestContext)) ~
pathPrefix("register")(oldUserRoutes(samRequestContext)) ~
pathPrefix("api") {
// these routes are for machine to machine authorized requests
// the whitelisted service admin account email is in the header of the request
Expand All @@ -75,8 +77,9 @@ abstract class SamRoutes(
adminRoutes(samUser, samRequestContextWithUser) ~
extensionRoutes(samUser, samRequestContextWithUser) ~
groupRoutes(samUser, samRequestContextWithUser) ~
apiUserRoutes(samUser, samRequestContextWithUser) ~
azureRoutes(samUser, samRequestContextWithUser)
azureRoutes(samUser, samRequestContextWithUser) ~
userRoutesV1(samUser, samRequestContextWithUser) ~
userRoutesV2(samUser, samRequestContextWithUser)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ import org.broadinstitute.dsde.workbench.sam._
import org.broadinstitute.dsde.workbench.sam.api.RejectionHandlers.termsOfServiceRejectionHandler
import org.broadinstitute.dsde.workbench.sam.config.AppConfig.AdminConfig
import org.broadinstitute.dsde.workbench.sam.config.TermsOfServiceConfig
import org.broadinstitute.dsde.workbench.sam.model.SamJsonSupport._
import org.broadinstitute.dsde.workbench.sam.model.{SamUser, TermsOfServiceAcceptance}
import org.broadinstitute.dsde.workbench.sam.model.api.SamJsonSupport._
import org.broadinstitute.dsde.workbench.sam.model.TermsOfServiceAcceptance
import org.broadinstitute.dsde.workbench.sam.model.api.SamUser
import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext

/** Directives to get user information.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import akka.http.scaladsl.model.StatusCodes.{NotFound, OK}
import akka.http.scaladsl.server
import akka.http.scaladsl.server.Directives._
import org.broadinstitute.dsde.workbench.model._
import org.broadinstitute.dsde.workbench.sam.model.SamJsonSupport._
import org.broadinstitute.dsde.workbench.sam.model.api.SamJsonSupport._
import org.broadinstitute.dsde.workbench.sam.service.ResourceService
import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext
import spray.json.DefaultJsonProtocol._
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import org.broadinstitute.dsde.workbench.model._
import org.broadinstitute.dsde.workbench.model.google.ServiceAccountSubjectId
import org.broadinstitute.dsde.workbench.sam.api.StandardSamUserDirectives._
import org.broadinstitute.dsde.workbench.sam.azure.ManagedIdentityObjectId
import org.broadinstitute.dsde.workbench.sam.model.SamUser
import org.broadinstitute.dsde.workbench.sam.model.api.SamUser
import org.broadinstitute.dsde.workbench.sam.service.UserService._
import org.broadinstitute.dsde.workbench.sam.service.{TosService, UserService}
import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.broadinstitute.dsde.workbench.sam.api

import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.server
import akka.http.scaladsl.server.Directives._
import org.broadinstitute.dsde.workbench.model._
import org.broadinstitute.dsde.workbench.sam.model.api.SamJsonSupport._
import org.broadinstitute.dsde.workbench.sam.model.api.SamUser
import org.broadinstitute.dsde.workbench.sam.service.UserService
import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext

trait UserRoutesV1 extends SamUserDirectives with SamRequestContextDirectives {
val userService: UserService

def userRoutesV1(samUser: SamUser, samRequestContext: SamRequestContext): server.Route = pathPrefix("users") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should have happened before, but we should mark this as deprecated

pathPrefix("v1") {
get {
path(Segment) { email =>
pathEnd {
complete {
userService.getUserIdInfoFromEmail(WorkbenchEmail(email), samRequestContext).map {
case Left(_) => StatusCodes.NotFound -> None
case Right(None) => StatusCodes.NoContent -> None
case Right(Some(userIdInfo)) => StatusCodes.OK -> Some(userIdInfo)
}
}
}
}
} ~
pathPrefix("invite") {
post {
path(Segment) { inviteeEmail =>
complete {
userService
.inviteUser(WorkbenchEmail(inviteeEmail.trim), samRequestContext)
.map(userStatus => StatusCodes.Created -> userStatus)
}
}
Ghost-in-a-Jar marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
}

}
Loading
Loading