From 0a3647688d67e92d67d9719f0b40579bba796308 Mon Sep 17 00:00:00 2001 From: tlangs Date: Thu, 12 Oct 2023 16:46:42 -0400 Subject: [PATCH 1/8] refactor SamUser into its own file --- .../dsde/workbench/sam/MockTestSupport.scala | 1 + .../sam/provider/SamProviderSpec.scala | 1 + .../dsde/workbench/sam/api/AdminRoutes.scala | 4 +- .../workbench/sam/api/ExtensionRoutes.scala | 2 +- .../sam/api/ManagedGroupRoutes.scala | 3 +- .../workbench/sam/api/ResourceRoutes.scala | 4 +- .../dsde/workbench/sam/api/SamRoutes.scala | 2 +- .../workbench/sam/api/SamUserDirectives.scala | 5 +- .../sam/api/ServiceAdminRoutes.scala | 2 +- .../sam/api/StandardSamUserDirectives.scala | 2 +- .../dsde/workbench/sam/api/UserRoutes.scala | 6 +- .../workbench/sam/audit/SamAuditModel.scala | 2 +- .../workbench/sam/azure/AzureRoutes.scala | 1 + .../workbench/sam/azure/AzureService.scala | 2 +- .../sam/dataAccess/AccessPolicyDAO.scala | 2 +- .../sam/dataAccess/DirectoryDAO.scala | 3 +- .../sam/dataAccess/PostgresDirectoryDAO.scala | 1 + .../workbench/sam/db/tables/UserTable.scala | 2 +- .../sam/google/GoogleExtensionRoutes.scala | 3 +- .../sam/google/GoogleExtensions.scala | 3 +- .../GoogleGroupSyncMessageReceiver.scala | 2 +- .../dsde/workbench/sam/model/SamModel.scala | 115 +---------------- .../sam/model/api/SamJsonSupport.scala | 117 ++++++++++++++++++ .../workbench/sam/model/api/SamUser.scala | 40 ++++++ .../sam/service/CloudExtensions.scala | 3 +- .../sam/service/ResourceService.scala | 2 +- .../workbench/sam/service/TosService.scala | 3 +- .../workbench/sam/service/UserService.scala | 2 +- .../sam/util/SamRequestContext.scala | 2 +- src/test/scala/Generator.scala | 1 + .../dsde/workbench/sam/TestSupport.scala | 1 + .../api/AdminResourceTypesRoutesSpec.scala | 2 +- .../sam/api/AdminServiceUserRoutesSpec.scala | 3 +- .../sam/api/AdminUserRoutesSpec.scala | 4 +- .../sam/api/ManagedGroupRoutesSpec.scala | 3 +- .../sam/api/ManagedGroupRoutesV1Spec.scala | 3 +- .../workbench/sam/api/MockSamRoutes.scala | 2 +- .../sam/api/MockSamRoutesBuilder.scala | 2 +- .../sam/api/MockSamUserDirectives.scala | 2 +- .../sam/api/ResourceRoutesSpec.scala | 2 +- .../sam/api/ResourceRoutesV1Spec.scala | 2 +- .../sam/api/ResourceRoutesV2Spec.scala | 2 +- .../workbench/sam/api/RouteSecuritySpec.scala | 2 +- .../api/StandardSamUserDirectivesSpec.scala | 2 +- .../workbench/sam/api/TestSamRoutes.scala | 1 + .../workbench/sam/api/UserRoutesSpec.scala | 3 +- .../workbench/sam/api/UserRoutesV1Spec.scala | 2 +- .../workbench/sam/api/UserRoutesV2Spec.scala | 2 +- .../workbench/sam/azure/AzureRoutesSpec.scala | 4 +- .../workbench/sam/azure/MockCrlService.scala | 3 +- .../sam/dataAccess/MockDirectoryDAO.scala | 3 +- .../dataAccess/MockDirectoryDaoBuilder.scala | 3 +- .../StatefulMockDirectoryDaoBuilder.scala | 3 +- .../google/GoogleExtensionRoutesSpec.scala | 2 +- .../google/GoogleExtensionRoutesV1Spec.scala | 2 +- .../GoogleGroupSyncMessageReceiverSpec.scala | 2 +- .../sam/matchers/BeForUserMatcher.scala | 3 +- .../sam/matchers/BeSameUserMatcher.scala | 2 +- .../sam/model/UserStatusBuilder.scala | 2 + .../sam/service/ManagedGroupServiceSpec.scala | 1 + .../service/MockCloudExtensionsBuilder.scala | 2 +- .../sam/service/MockTosServiceBuilder.scala | 3 +- .../sam/service/MockUserService.scala | 3 +- .../sam/service/MockUserServiceBuilder.scala | 4 +- .../StatefulMockCloudExtensionsBuilder.scala | 2 +- .../sam/service/TestUserServiceBuilder.scala | 2 +- .../sam/service/UserServiceSpec.scala | 1 + .../UserServiceSpecs/CreateUserSpec.scala | 3 +- .../UserServiceSpecs/InviteUserSpec.scala | 3 +- 69 files changed, 253 insertions(+), 178 deletions(-) create mode 100644 src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamJsonSupport.scala create mode 100644 src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamUser.scala diff --git a/pact4s/src/test/scala/org/broadinstitute/dsde/workbench/sam/MockTestSupport.scala b/pact4s/src/test/scala/org/broadinstitute/dsde/workbench/sam/MockTestSupport.scala index 12c217041..c10db52af 100644 --- a/pact4s/src/test/scala/org/broadinstitute/dsde/workbench/sam/MockTestSupport.scala +++ b/pact4s/src/test/scala/org/broadinstitute/dsde/workbench/sam/MockTestSupport.scala @@ -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 diff --git a/pact4s/src/test/scala/org/broadinstitute/dsde/workbench/sam/provider/SamProviderSpec.scala b/pact4s/src/test/scala/org/broadinstitute/dsde/workbench/sam/provider/SamProviderSpec.scala index e6af93b82..0936ba754 100644 --- a/pact4s/src/test/scala/org/broadinstitute/dsde/workbench/sam/provider/SamProviderSpec.scala +++ b/pact4s/src/test/scala/org/broadinstitute/dsde/workbench/sam/provider/SamProviderSpec.scala @@ -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} 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 4730ee170..fce64b8d6 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 @@ -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._ diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/ExtensionRoutes.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/ExtensionRoutes.scala index 57a49f889..b89d75d45 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/ExtensionRoutes.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/ExtensionRoutes.scala @@ -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 { diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/ManagedGroupRoutes.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/ManagedGroupRoutes.scala index c1d35d0b9..7fd7d4b8e 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/ManagedGroupRoutes.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/ManagedGroupRoutes.scala @@ -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 diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/ResourceRoutes.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/ResourceRoutes.scala index fbb0339b0..d566b74b5 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/ResourceRoutes.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/ResourceRoutes.scala @@ -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._ diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/SamRoutes.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/SamRoutes.scala index f4128dcd9..12bd46c2f 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/SamRoutes.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/SamRoutes.scala @@ -64,7 +64,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 diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/SamUserDirectives.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/SamUserDirectives.scala index 346da5288..0be1f67d9 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/SamUserDirectives.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/SamUserDirectives.scala @@ -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. diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/ServiceAdminRoutes.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/ServiceAdminRoutes.scala index ccc3d83f8..adb7c99b5 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/ServiceAdminRoutes.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/ServiceAdminRoutes.scala @@ -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._ diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/StandardSamUserDirectives.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/StandardSamUserDirectives.scala index 4cdd6034d..f468b35d1 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/StandardSamUserDirectives.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/StandardSamUserDirectives.scala @@ -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 diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutes.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutes.scala index 0a9fbe4cc..579d9551c 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutes.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutes.scala @@ -7,8 +7,8 @@ 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.model.api.SamUser import org.broadinstitute.dsde.workbench.sam.service.UserService import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext import spray.json.JsBoolean @@ -33,7 +33,7 @@ trait UserRoutes extends SamUserDirectives with SamRequestContextDirectives { }) } - def userRoutes(samRequestContext: SamRequestContext): server.Route = + def oldUserRoutes(samRequestContext: SamRequestContext): server.Route = pathPrefix("user") { (pathPrefix("v1") | pathEndOrSingleSlash) { pathEndOrSingleSlash { diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/audit/SamAuditModel.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/audit/SamAuditModel.scala index 3bec90aff..335b0e963 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/audit/SamAuditModel.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/audit/SamAuditModel.scala @@ -41,7 +41,7 @@ final case class AccessChangeEvent(eventType: AccessChangeEventType, resource: F object SamAuditModelJsonSupport { import DefaultJsonProtocol._ import org.broadinstitute.dsde.workbench.model.WorkbenchIdentityJsonSupport._ - import org.broadinstitute.dsde.workbench.sam.model.SamJsonSupport._ + import org.broadinstitute.dsde.workbench.sam.model.api.SamJsonSupport._ implicit object InetAddressFormat extends RootJsonFormat[InetAddress] { def write(ip: InetAddress) = JsString(ip.getHostAddress) diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/azure/AzureRoutes.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/azure/AzureRoutes.scala index 054a179d9..f1c53b321 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/azure/AzureRoutes.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/azure/AzureRoutes.scala @@ -12,6 +12,7 @@ import org.broadinstitute.dsde.workbench.sam._ import org.broadinstitute.dsde.workbench.sam.api.{SecurityDirectives, _} import org.broadinstitute.dsde.workbench.sam.azure.AzureJsonSupport._ import org.broadinstitute.dsde.workbench.sam.model._ +import org.broadinstitute.dsde.workbench.sam.model.api.SamUser import org.broadinstitute.dsde.workbench.sam.service.CloudExtensions import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext import spray.json.JsString diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/azure/AzureService.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/azure/AzureService.scala index c92202e55..c4b20c2ab 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/azure/AzureService.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/azure/AzureService.scala @@ -14,7 +14,7 @@ import org.broadinstitute.dsde.workbench.model.{ErrorReport, WorkbenchEmail, Wor import org.broadinstitute.dsde.workbench.sam._ import org.broadinstitute.dsde.workbench.sam.config.ManagedAppPlan import org.broadinstitute.dsde.workbench.sam.dataAccess.{AzureManagedResourceGroupDAO, DirectoryDAO} -import org.broadinstitute.dsde.workbench.sam.model._ +import org.broadinstitute.dsde.workbench.sam.model.api.SamUser import org.broadinstitute.dsde.workbench.sam.util.OpenCensusIOUtils._ import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/AccessPolicyDAO.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/AccessPolicyDAO.scala index 127842aa6..0d49e8ee6 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/AccessPolicyDAO.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/AccessPolicyDAO.scala @@ -3,7 +3,7 @@ package org.broadinstitute.dsde.workbench.sam.dataAccess import cats.data.NonEmptyList import cats.effect.IO import org.broadinstitute.dsde.workbench.model._ -import org.broadinstitute.dsde.workbench.sam.model.api.AccessPolicyMembershipResponse +import org.broadinstitute.dsde.workbench.sam.model.api.{AccessPolicyMembershipResponse, SamUser} import org.broadinstitute.dsde.workbench.sam.model.{FullyQualifiedResourceId, _} import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/DirectoryDAO.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/DirectoryDAO.scala index 35a8f5295..9fa505248 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/DirectoryDAO.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/DirectoryDAO.scala @@ -4,7 +4,8 @@ import cats.effect.IO import org.broadinstitute.dsde.workbench.model._ import org.broadinstitute.dsde.workbench.model.google.ServiceAccountSubjectId import org.broadinstitute.dsde.workbench.sam.azure.{ManagedIdentityObjectId, PetManagedIdentity, PetManagedIdentityId} -import org.broadinstitute.dsde.workbench.sam.model.{BasicWorkbenchGroup, SamUser, SamUserTos} +import org.broadinstitute.dsde.workbench.sam.model.api.SamUser +import org.broadinstitute.dsde.workbench.sam.model.{BasicWorkbenchGroup, SamUserTos} import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext import java.time.Instant diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/PostgresDirectoryDAO.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/PostgresDirectoryDAO.scala index 876b6dd74..e76483133 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/PostgresDirectoryDAO.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/PostgresDirectoryDAO.scala @@ -12,6 +12,7 @@ import org.broadinstitute.dsde.workbench.sam.db.SamTypeBinders._ import org.broadinstitute.dsde.workbench.sam.db._ import org.broadinstitute.dsde.workbench.sam.db.tables._ import org.broadinstitute.dsde.workbench.sam.model._ +import org.broadinstitute.dsde.workbench.sam.model.api.SamUser import org.broadinstitute.dsde.workbench.sam.util.{DatabaseSupport, SamRequestContext} import org.postgresql.util.PSQLException import scalikejdbc._ diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/db/tables/UserTable.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/db/tables/UserTable.scala index 5e30bd33e..95079b395 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/db/tables/UserTable.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/db/tables/UserTable.scala @@ -2,7 +2,7 @@ package org.broadinstitute.dsde.workbench.sam.db.tables import org.broadinstitute.dsde.workbench.model._ import org.broadinstitute.dsde.workbench.sam.db.SamTypeBinders -import org.broadinstitute.dsde.workbench.sam.model.SamUser +import org.broadinstitute.dsde.workbench.sam.model.api.SamUser import scalikejdbc._ import java.time.Instant diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/google/GoogleExtensionRoutes.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/google/GoogleExtensionRoutes.scala index 3ac13f953..c031fdfa7 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/google/GoogleExtensionRoutes.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/google/GoogleExtensionRoutes.scala @@ -17,8 +17,9 @@ import org.broadinstitute.dsde.workbench.sam.api.{ SecurityDirectives, ioMarshaller } -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.SamUser import org.broadinstitute.dsde.workbench.sam.service.CloudExtensions import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext import spray.json.DefaultJsonProtocol._ diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/google/GoogleExtensions.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/google/GoogleExtensions.scala index 775039eba..c6a7beedf 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/google/GoogleExtensions.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/google/GoogleExtensions.scala @@ -25,8 +25,9 @@ import org.broadinstitute.dsde.workbench.model.google._ import org.broadinstitute.dsde.workbench.sam._ import org.broadinstitute.dsde.workbench.sam.config.{GoogleServicesConfig, PetServiceAccountConfig} import org.broadinstitute.dsde.workbench.sam.dataAccess.{AccessPolicyDAO, DirectoryDAO, LockDetails, PostgresDistributedLockDAO} -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.SamUser import org.broadinstitute.dsde.workbench.sam.service.UserService._ import org.broadinstitute.dsde.workbench.sam.service.{CloudExtensions, CloudExtensionsInitializer, ManagedGroupService, SamApplication} import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/google/GoogleGroupSyncMessageReceiver.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/google/GoogleGroupSyncMessageReceiver.scala index f6f8e85c0..de091ebb6 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/google/GoogleGroupSyncMessageReceiver.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/google/GoogleGroupSyncMessageReceiver.scala @@ -78,7 +78,7 @@ class GoogleGroupSyncMessageReceiver(groupSynchronizer: GoogleGroupSynchronizer) private[google] def parseMessage(message: PubsubMessage): WorkbenchGroupIdentity = { val messageJson = message.getData.toStringUtf8.parseJson (Try { - import org.broadinstitute.dsde.workbench.sam.model.SamJsonSupport.FullyQualifiedPolicyIdFormat + import org.broadinstitute.dsde.workbench.sam.model.api.SamJsonSupport.FullyQualifiedPolicyIdFormat messageJson.convertTo[FullyQualifiedPolicyId] } recover { case _: DeserializationException => import WorkbenchIdentityJsonSupport.WorkbenchGroupNameFormat diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/SamModel.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/SamModel.scala index 1a2b5c373..6d6a35bdb 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/SamModel.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/SamModel.scala @@ -2,9 +2,7 @@ package org.broadinstitute.dsde.workbench.sam.model import monocle.macros.Lenses import org.broadinstitute.dsde.workbench.model._ -import org.broadinstitute.dsde.workbench.model.google.GoogleModelJsonSupport.InstantFormat -import org.broadinstitute.dsde.workbench.sam.model.api.SamApiJsonProtocol.PolicyInfoResponseBodyJsonFormat -import org.broadinstitute.dsde.workbench.sam.model.api.{AccessPolicyMembershipRequest, AccessPolicyMembershipResponse, AdminUpdateUserRequest} +import org.broadinstitute.dsde.workbench.sam.model.api.{AccessPolicyMembershipRequest, AccessPolicyMembershipResponse, SamUser} import org.broadinstitute.dsde.workbench.sam.service.ManagedGroupService.MangedGroupRoleName import spray.json.{DefaultJsonProtocol, JsValue, RootJsonFormat} @@ -12,82 +10,6 @@ import java.time.Instant /** Created by dvoet on 5/26/17. */ -object SamJsonSupport { - import DefaultJsonProtocol._ - import org.broadinstitute.dsde.workbench.model.WorkbenchIdentityJsonSupport._ - - implicit val ResourceActionPatternFormat = jsonFormat3(ResourceActionPattern.apply) - - implicit val ResourceActionFormat = ValueObjectFormat(ResourceAction.apply) - - implicit val ResourceRoleNameFormat = ValueObjectFormat(ResourceRoleName.apply) - - implicit val ResourceTypeNameFormat = ValueObjectFormat(ResourceTypeName.apply) - - implicit val ResourceRoleFormat = jsonFormat4(ResourceRole.apply) - - implicit val ResourceTypeFormat = jsonFormat6(ResourceType.apply) - - implicit val SamUserFormat = jsonFormat8(SamUser.apply) - - implicit val UserStatusDetailsFormat = jsonFormat2(UserStatusDetails.apply) - - implicit val UserStatusFormat = jsonFormat2(UserStatus.apply) - - implicit val UserStatusInfoFormat = jsonFormat4(UserStatusInfo.apply) - - implicit val UserIdInfoFormat = jsonFormat3(UserIdInfo.apply) - - implicit val TermsOfServiceAcceptanceFormat = ValueObjectFormat(TermsOfServiceAcceptance.apply) - - implicit val termsOfServiceDetailsFormat = jsonFormat4(TermsOfServiceDetails.apply) - - implicit val termsOfAcceptanceStatusFormat = jsonFormat3(TermsOfServiceComplianceStatus.apply) - - implicit val UserStatusDiagnosticsFormat = jsonFormat5(UserStatusDiagnostics.apply) - - implicit val AccessPolicyNameFormat = ValueObjectFormat(AccessPolicyName.apply) - - implicit val ResourceIdFormat = ValueObjectFormat(ResourceId.apply) - - implicit val FullyQualifiedResourceIdFormat = jsonFormat2(FullyQualifiedResourceId.apply) - - implicit val AccessPolicyDescendantPermissionsFormat: RootJsonFormat[AccessPolicyDescendantPermissions] = jsonFormat3(AccessPolicyDescendantPermissions.apply) - - implicit val PolicyIdentifiersFormat = jsonFormat3(PolicyIdentifiers.apply) - - implicit val AccessPolicyMembershipResponseFormat = jsonFormat5(AccessPolicyMembershipResponse.apply) - - implicit val AccessPolicyResponseEntryFormat = jsonFormat3(AccessPolicyResponseEntry.apply) - - implicit val UserPolicyResponseFormat = jsonFormat5(UserPolicyResponse.apply) - - implicit val UserUpdateRequestFormat = jsonFormat3(AdminUpdateUserRequest.apply) - - implicit val RolesAndActionsFormat = jsonFormat2(RolesAndActions.apply) - - implicit val UserResourcesResponseFormat = jsonFormat6(UserResourcesResponse.apply) - - implicit val FullyQualifiedPolicyIdFormat = jsonFormat2(FullyQualifiedPolicyId.apply) - - implicit val ManagedGroupMembershipEntryFormat = jsonFormat3(ManagedGroupMembershipEntry.apply) - - implicit val ManagedGroupAccessInstructionsFormat = ValueObjectFormat(ManagedGroupAccessInstructions.apply) - - implicit val GroupSyncResponseFormat = jsonFormat2(GroupSyncResponse.apply) - - implicit val AccessPolicyMembershipRequestFormat = jsonFormat5(AccessPolicyMembershipRequest.apply) - - implicit val CreateResourceRequestFormat = jsonFormat5(CreateResourceRequest.apply) - - implicit val CreateResourcePolicyResponseFormat = jsonFormat2(CreateResourcePolicyResponse.apply) - - implicit val CreateResourceResponseFormat = jsonFormat4(CreateResourceResponse.apply) - - implicit val SignedUrlRequestFormat = jsonFormat4(SignedUrlRequest.apply) - - implicit val RequesterPaysSignedUrlRequestFormat = jsonFormat3(RequesterPaysSignedUrlRequest.apply) -} object RootPrimitiveJsonSupport { implicit val rootBooleanJsonFormat: RootJsonFormat[Boolean] = new RootJsonFormat[Boolean] { @@ -316,40 +238,6 @@ object BasicWorkbenchGroup { requesterPaysProject: Option[String] = None ) -object SamUser { - def apply( - id: WorkbenchUserId, - googleSubjectId: Option[GoogleSubjectId], - email: WorkbenchEmail, - azureB2CId: Option[AzureB2CId], - enabled: Boolean - ): SamUser = - SamUser(id, googleSubjectId, email, azureB2CId, enabled, Instant.EPOCH, None, Instant.EPOCH) -} - -final case class SamUser( - id: WorkbenchUserId, - googleSubjectId: Option[GoogleSubjectId], - email: WorkbenchEmail, - azureB2CId: Option[AzureB2CId], - enabled: Boolean, - createdAt: Instant, - registeredAt: Option[Instant], - updatedAt: Instant -) { - def toUserIdInfo = UserIdInfo(id, email, googleSubjectId) - - override def equals(other: Any): Boolean = other match { - case user: SamUser => - this.id == user.id && - this.googleSubjectId == user.googleSubjectId && - this.email == user.email && - this.azureB2CId == user.azureB2CId && - this.enabled == user.enabled - case _ => false - } -} - final case class SamUserTos(id: WorkbenchUserId, version: String, action: String, createdAt: Instant) { override def equals(other: Any): Boolean = other match { case userTos: SamUserTos => @@ -359,7 +247,6 @@ final case class SamUserTos(id: WorkbenchUserId, version: String, action: String case _ => false } } - object SamLenses { val resourceIdentityAccessPolicy = AccessPolicy.id composeLens FullyQualifiedPolicyId.resource val resourceTypeNameInAccessPolicy = resourceIdentityAccessPolicy composeLens FullyQualifiedResourceId.resourceTypeName diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamJsonSupport.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamJsonSupport.scala new file mode 100644 index 000000000..257b3383e --- /dev/null +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamJsonSupport.scala @@ -0,0 +1,117 @@ +package org.broadinstitute.dsde.workbench.sam.model.api + +import org.broadinstitute.dsde.workbench.model.ValueObjectFormat +import org.broadinstitute.dsde.workbench.sam.model.{ + AccessPolicyDescendantPermissions, + AccessPolicyName, + AccessPolicyResponseEntry, + CreateResourcePolicyResponse, + CreateResourceRequest, + CreateResourceResponse, + FullyQualifiedPolicyId, + FullyQualifiedResourceId, + GroupSyncResponse, + ManagedGroupAccessInstructions, + ManagedGroupMembershipEntry, + PolicyIdentifiers, + RequesterPaysSignedUrlRequest, + ResourceAction, + ResourceActionPattern, + ResourceId, + ResourceRole, + ResourceRoleName, + ResourceType, + ResourceTypeName, + RolesAndActions, + SignedUrlRequest, + TermsOfServiceAcceptance, + TermsOfServiceComplianceStatus, + TermsOfServiceDetails, + UserIdInfo, + UserPolicyResponse, + UserResourcesResponse, + UserStatus, + UserStatusDetails, + UserStatusDiagnostics, + UserStatusInfo +} +import org.broadinstitute.dsde.workbench.model.google.GoogleModelJsonSupport.InstantFormat +import spray.json.{DefaultJsonProtocol, RootJsonFormat} +import org.broadinstitute.dsde.workbench.sam.model.api.SamApiJsonProtocol.PolicyInfoResponseBodyJsonFormat + +object SamJsonSupport { + import DefaultJsonProtocol._ + import org.broadinstitute.dsde.workbench.model.WorkbenchIdentityJsonSupport._ + + implicit val ResourceActionPatternFormat = jsonFormat3(ResourceActionPattern.apply) + + implicit val ResourceActionFormat = ValueObjectFormat(ResourceAction.apply) + + implicit val ResourceRoleNameFormat = ValueObjectFormat(ResourceRoleName.apply) + + implicit val ResourceTypeNameFormat = ValueObjectFormat(ResourceTypeName.apply) + + implicit val ResourceRoleFormat = jsonFormat4(ResourceRole.apply) + + implicit val ResourceTypeFormat = jsonFormat6(ResourceType.apply) + + implicit val SamUserFormat = jsonFormat8(SamUser.apply) + + implicit val UserStatusDetailsFormat = jsonFormat2(UserStatusDetails.apply) + + implicit val UserStatusFormat = jsonFormat2(UserStatus.apply) + + implicit val UserStatusInfoFormat = jsonFormat4(UserStatusInfo.apply) + + implicit val UserIdInfoFormat = jsonFormat3(UserIdInfo.apply) + + implicit val TermsOfServiceAcceptanceFormat = ValueObjectFormat(TermsOfServiceAcceptance.apply) + + implicit val termsOfServiceDetailsFormat = jsonFormat4(TermsOfServiceDetails.apply) + + implicit val termsOfAcceptanceStatusFormat = jsonFormat3(TermsOfServiceComplianceStatus.apply) + + implicit val UserStatusDiagnosticsFormat = jsonFormat5(UserStatusDiagnostics.apply) + + implicit val AccessPolicyNameFormat = ValueObjectFormat(AccessPolicyName.apply) + + implicit val ResourceIdFormat = ValueObjectFormat(ResourceId.apply) + + implicit val FullyQualifiedResourceIdFormat = jsonFormat2(FullyQualifiedResourceId.apply) + + implicit val AccessPolicyDescendantPermissionsFormat: RootJsonFormat[AccessPolicyDescendantPermissions] = jsonFormat3(AccessPolicyDescendantPermissions.apply) + + implicit val PolicyIdentifiersFormat = jsonFormat3(PolicyIdentifiers.apply) + + implicit val AccessPolicyMembershipResponseFormat = jsonFormat5(AccessPolicyMembershipResponse.apply) + + implicit val AccessPolicyResponseEntryFormat = jsonFormat3(AccessPolicyResponseEntry.apply) + + implicit val UserPolicyResponseFormat = jsonFormat5(UserPolicyResponse.apply) + + implicit val UserUpdateRequestFormat = jsonFormat3(AdminUpdateUserRequest.apply) + + implicit val RolesAndActionsFormat = jsonFormat2(RolesAndActions.apply) + + implicit val UserResourcesResponseFormat = jsonFormat6(UserResourcesResponse.apply) + + implicit val FullyQualifiedPolicyIdFormat = jsonFormat2(FullyQualifiedPolicyId.apply) + + implicit val ManagedGroupMembershipEntryFormat = jsonFormat3(ManagedGroupMembershipEntry.apply) + + implicit val ManagedGroupAccessInstructionsFormat = ValueObjectFormat(ManagedGroupAccessInstructions.apply) + + implicit val GroupSyncResponseFormat = jsonFormat2(GroupSyncResponse.apply) + + implicit val AccessPolicyMembershipRequestFormat = jsonFormat5(AccessPolicyMembershipRequest.apply) + + implicit val CreateResourceRequestFormat = jsonFormat5(CreateResourceRequest.apply) + + implicit val CreateResourcePolicyResponseFormat = jsonFormat2(CreateResourcePolicyResponse.apply) + + implicit val CreateResourceResponseFormat = jsonFormat4(CreateResourceResponse.apply) + + implicit val SignedUrlRequestFormat = jsonFormat4(SignedUrlRequest.apply) + + implicit val RequesterPaysSignedUrlRequestFormat = jsonFormat3(RequesterPaysSignedUrlRequest.apply) +} diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamUser.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamUser.scala new file mode 100644 index 000000000..6c8138287 --- /dev/null +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamUser.scala @@ -0,0 +1,40 @@ +package org.broadinstitute.dsde.workbench.sam.model.api + +import org.broadinstitute.dsde.workbench.model.{AzureB2CId, GoogleSubjectId, WorkbenchEmail, WorkbenchUserId} +import org.broadinstitute.dsde.workbench.sam.model.UserIdInfo + +import java.time.Instant + +object SamUser { + def apply( + id: WorkbenchUserId, + googleSubjectId: Option[GoogleSubjectId], + email: WorkbenchEmail, + azureB2CId: Option[AzureB2CId], + enabled: Boolean + ): SamUser = + SamUser(id, googleSubjectId, email, azureB2CId, enabled, Instant.EPOCH, None, Instant.EPOCH) +} + +final case class SamUser( + id: WorkbenchUserId, + googleSubjectId: Option[GoogleSubjectId], + email: WorkbenchEmail, + azureB2CId: Option[AzureB2CId], + enabled: Boolean, + createdAt: Instant, + registeredAt: Option[Instant], + updatedAt: Instant +) { + def toUserIdInfo = UserIdInfo(id, email, googleSubjectId) + + override def equals(other: Any): Boolean = other match { + case user: SamUser => + this.id == user.id && + this.googleSubjectId == user.googleSubjectId && + this.email == user.email && + this.azureB2CId == user.azureB2CId && + this.enabled == user.enabled + case _ => false + } +} diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/CloudExtensions.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/CloudExtensions.scala index e727807e6..66b929eff 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/CloudExtensions.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/CloudExtensions.scala @@ -10,7 +10,8 @@ import org.broadinstitute.dsde.workbench.model._ import org.broadinstitute.dsde.workbench.model.google.GoogleProject import org.broadinstitute.dsde.workbench.sam.api.ExtensionRoutes import org.broadinstitute.dsde.workbench.sam.dataAccess.DirectoryDAO -import org.broadinstitute.dsde.workbench.sam.model.{BasicWorkbenchGroup, ResourceTypeName, SamUser} +import org.broadinstitute.dsde.workbench.sam.model.api.SamUser +import org.broadinstitute.dsde.workbench.sam.model.{BasicWorkbenchGroup, ResourceTypeName} import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext import org.broadinstitute.dsde.workbench.util.health.SubsystemStatus import org.broadinstitute.dsde.workbench.util.health.Subsystems.Subsystem diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/ResourceService.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/ResourceService.scala index 56d93bd5d..d9f11d0fc 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/ResourceService.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/ResourceService.scala @@ -14,7 +14,7 @@ import org.broadinstitute.dsde.workbench.sam.audit.SamAuditModelJsonSupport._ import org.broadinstitute.dsde.workbench.sam.audit._ import org.broadinstitute.dsde.workbench.sam.dataAccess.{AccessPolicyDAO, DirectoryDAO, LoadResourceAuthDomainResult} import org.broadinstitute.dsde.workbench.sam.model._ -import org.broadinstitute.dsde.workbench.sam.model.api.{AccessPolicyMembershipRequest, AccessPolicyMembershipResponse} +import org.broadinstitute.dsde.workbench.sam.model.api.{AccessPolicyMembershipRequest, AccessPolicyMembershipResponse, SamUser} import org.broadinstitute.dsde.workbench.sam.util.{API_TIMING_DURATION_BUCKET, SamRequestContext} import java.util.UUID diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/TosService.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/TosService.scala index 946ebbd1f..47a063b6e 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/TosService.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/TosService.scala @@ -11,7 +11,8 @@ import org.broadinstitute.dsde.workbench.sam.errorReportSource import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext import org.broadinstitute.dsde.workbench.sam.config.TermsOfServiceConfig import org.broadinstitute.dsde.workbench.sam.db.tables.TosTable -import org.broadinstitute.dsde.workbench.sam.model.{SamUser, SamUserTos, TermsOfServiceComplianceStatus, TermsOfServiceDetails} +import org.broadinstitute.dsde.workbench.sam.model.api.SamUser +import org.broadinstitute.dsde.workbench.sam.model.{SamUserTos, TermsOfServiceComplianceStatus, TermsOfServiceDetails} import scala.concurrent.ExecutionContext import java.io.{FileNotFoundException, IOException} diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/UserService.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/UserService.scala index 8d192cdb0..58806e5ce 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/UserService.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/UserService.scala @@ -12,7 +12,7 @@ import org.broadinstitute.dsde.workbench.openTelemetry.OpenTelemetryMetrics import org.broadinstitute.dsde.workbench.sam.azure.ManagedIdentityObjectId import org.broadinstitute.dsde.workbench.sam.dataAccess.DirectoryDAO import org.broadinstitute.dsde.workbench.sam.model._ -import org.broadinstitute.dsde.workbench.sam.model.api.AdminUpdateUserRequest +import org.broadinstitute.dsde.workbench.sam.model.api.{AdminUpdateUserRequest, SamUser} import org.broadinstitute.dsde.workbench.sam.service.UserService.genWorkbenchUserId import org.broadinstitute.dsde.workbench.sam.util.AsyncLogging.IOWithLogging import org.broadinstitute.dsde.workbench.sam.util.{API_TIMING_DURATION_BUCKET, SamRequestContext} diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/util/SamRequestContext.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/util/SamRequestContext.scala index 59359ad74..4690c9917 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/util/SamRequestContext.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/util/SamRequestContext.scala @@ -2,7 +2,7 @@ package org.broadinstitute.dsde.workbench.sam.util import io.opencensus.trace.Span import org.broadinstitute.dsde.workbench.sam.audit.AuditInfo -import org.broadinstitute.dsde.workbench.sam.model.SamUser +import org.broadinstitute.dsde.workbench.sam.model.api.SamUser import java.net.InetAddress diff --git a/src/test/scala/Generator.scala b/src/test/scala/Generator.scala index 65b8953c1..2ea1fe295 100644 --- a/src/test/scala/Generator.scala +++ b/src/test/scala/Generator.scala @@ -10,6 +10,7 @@ import org.broadinstitute.dsde.workbench.sam.azure._ import org.broadinstitute.dsde.workbench.sam.dataAccess.LockDetails import org.broadinstitute.dsde.workbench.sam.model.SamResourceActions._ 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.scalacheck._ diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/TestSupport.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/TestSupport.scala index e206845d1..76034f97b 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/TestSupport.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/TestSupport.scala @@ -25,6 +25,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 diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/AdminResourceTypesRoutesSpec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/AdminResourceTypesRoutesSpec.scala index b68309d96..b49394abe 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/AdminResourceTypesRoutesSpec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/AdminResourceTypesRoutesSpec.scala @@ -8,7 +8,7 @@ import cats.implicits.catsSyntaxOptionId import org.broadinstitute.dsde.workbench.model._ import org.broadinstitute.dsde.workbench.sam.api.TestSamRoutes.resourceTypeAdmin import org.broadinstitute.dsde.workbench.sam.dataAccess.{MockAccessPolicyDAO, MockDirectoryDAO} -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._ import org.broadinstitute.dsde.workbench.sam.model._ import org.broadinstitute.dsde.workbench.sam.model.api._ diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/AdminServiceUserRoutesSpec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/AdminServiceUserRoutesSpec.scala index 1b9d3f659..114754b38 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/AdminServiceUserRoutesSpec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/AdminServiceUserRoutesSpec.scala @@ -4,8 +4,9 @@ import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ import akka.http.scaladsl.model.StatusCodes import akka.http.scaladsl.testkit.ScalatestRouteTest import org.broadinstitute.dsde.workbench.model.{WorkbenchEmail, WorkbenchUserId} -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.SamUser import org.broadinstitute.dsde.workbench.sam.service._ import org.broadinstitute.dsde.workbench.sam.{Generator, TestSupport} import org.mockito.scalatest.MockitoSugar diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/AdminUserRoutesSpec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/AdminUserRoutesSpec.scala index cfb216fce..f3dcdb5ad 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/AdminUserRoutesSpec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/AdminUserRoutesSpec.scala @@ -6,9 +6,9 @@ import akka.http.scaladsl.testkit.ScalatestRouteTest import org.broadinstitute.dsde.workbench.model.{WorkbenchEmail, WorkbenchUserId} import org.broadinstitute.dsde.workbench.sam.TestSupport.enabledMapNoTosAccepted import org.broadinstitute.dsde.workbench.sam.matchers.BeForUserMatcher.beForUser -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.AdminUpdateUserRequest +import org.broadinstitute.dsde.workbench.sam.model.api.{AdminUpdateUserRequest, SamUser} import org.broadinstitute.dsde.workbench.sam.service._ import org.broadinstitute.dsde.workbench.sam.{Generator, TestSupport} import org.mockito.scalatest.MockitoSugar diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/ManagedGroupRoutesSpec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/ManagedGroupRoutesSpec.scala index 5108715ca..441059c70 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/ManagedGroupRoutesSpec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/ManagedGroupRoutesSpec.scala @@ -14,8 +14,9 @@ import org.broadinstitute.dsde.workbench.openTelemetry.{FakeOpenTelemetryMetrics import org.broadinstitute.dsde.workbench.sam.TestSupport.samRequestContext import org.broadinstitute.dsde.workbench.sam.api.ManagedGroupRoutesSpec._ import org.broadinstitute.dsde.workbench.sam.dataAccess.{MockAccessPolicyDAO, MockDirectoryDAO} -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.SamUser import org.broadinstitute.dsde.workbench.sam.service.ManagedGroupService import org.broadinstitute.dsde.workbench.sam.service.UserService.genRandom import org.scalatest.BeforeAndAfter diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/ManagedGroupRoutesV1Spec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/ManagedGroupRoutesV1Spec.scala index 3d4b9fcc1..210a71d9e 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/ManagedGroupRoutesV1Spec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/ManagedGroupRoutesV1Spec.scala @@ -7,8 +7,9 @@ import akka.http.scaladsl.testkit.ScalatestRouteTest import org.broadinstitute.dsde.workbench.model.WorkbenchIdentityJsonSupport._ import org.broadinstitute.dsde.workbench.model._ import org.broadinstitute.dsde.workbench.sam.api.ManagedGroupRoutesSpec._ -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.SamUser import org.broadinstitute.dsde.workbench.sam.service.ManagedGroupService import org.scalatest.BeforeAndAfter import org.scalatest.concurrent.ScalaFutures diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamRoutes.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamRoutes.scala index 6ce8954cd..5b86a6467 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamRoutes.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamRoutes.scala @@ -62,7 +62,7 @@ abstract class MockSamRoutes( termsOfServiceRoutes ~ withExecutionContext(ExecutionContext.global) { withSamRequestContext { samRequestContext => - pathPrefix("register")(userRoutes(samRequestContext)) ~ + pathPrefix("register")(oldUserRoutes(samRequestContext)) ~ pathPrefix("api") { // IMPORTANT - all routes under /api must have an active user withActiveUser(samRequestContext) { samUser => diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamRoutesBuilder.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamRoutesBuilder.scala index 133000a5c..e076bd0ee 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamRoutesBuilder.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamRoutesBuilder.scala @@ -7,7 +7,7 @@ import akka.stream.Materializer import cats.effect.IO import org.broadinstitute.dsde.workbench.model.{ErrorReportSource, WorkbenchGroup} import org.broadinstitute.dsde.workbench.openTelemetry.OpenTelemetryMetrics -import org.broadinstitute.dsde.workbench.sam.model.SamUser +import org.broadinstitute.dsde.workbench.sam.model.api.SamUser import org.broadinstitute.dsde.workbench.sam.service._ import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamUserDirectives.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamUserDirectives.scala index dd7018e94..9eaa341ea 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamUserDirectives.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamUserDirectives.scala @@ -5,7 +5,7 @@ import akka.http.scaladsl.model.headers.OAuth2BearerToken import akka.http.scaladsl.server.Directive1 import akka.http.scaladsl.server.Directives._ import cats.effect.unsafe.implicits.global -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 /** Created by dvoet on 6/7/17. diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/ResourceRoutesSpec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/ResourceRoutesSpec.scala index 4cf65dd7f..4c9172a9d 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/ResourceRoutesSpec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/ResourceRoutesSpec.scala @@ -9,7 +9,7 @@ import org.broadinstitute.dsde.workbench.model.ErrorReportJsonSupport._ import org.broadinstitute.dsde.workbench.model.WorkbenchIdentityJsonSupport._ import org.broadinstitute.dsde.workbench.model._ import org.broadinstitute.dsde.workbench.sam.dataAccess.{MockAccessPolicyDAO, MockDirectoryDAO} -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._ import org.broadinstitute.dsde.workbench.sam.service._ diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/ResourceRoutesV1Spec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/ResourceRoutesV1Spec.scala index 4e762f805..8a392c69e 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/ResourceRoutesV1Spec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/ResourceRoutesV1Spec.scala @@ -12,7 +12,7 @@ import org.broadinstitute.dsde.workbench.sam.TestSupport._ import org.broadinstitute.dsde.workbench.sam.api.TestSamRoutes.SamResourceActionPatterns import org.broadinstitute.dsde.workbench.sam.dataAccess.{MockAccessPolicyDAO, MockDirectoryDAO} 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._ import org.broadinstitute.dsde.workbench.sam.service._ diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/ResourceRoutesV2Spec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/ResourceRoutesV2Spec.scala index eff039bf9..d1e06e39d 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/ResourceRoutesV2Spec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/ResourceRoutesV2Spec.scala @@ -11,7 +11,7 @@ import org.broadinstitute.dsde.workbench.sam.TestSupport.configResourceTypes import org.broadinstitute.dsde.workbench.sam.api.TestSamRoutes.SamResourceActionPatterns import org.broadinstitute.dsde.workbench.sam.dataAccess.{MockAccessPolicyDAO, MockDirectoryDAO} 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._ import org.broadinstitute.dsde.workbench.sam.service._ diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/RouteSecuritySpec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/RouteSecuritySpec.scala index cc2841fd2..fceea1ec0 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/RouteSecuritySpec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/RouteSecuritySpec.scala @@ -2,7 +2,7 @@ package org.broadinstitute.dsde.workbench.sam.api import akka.http.scaladsl.testkit.ScalatestRouteTest import org.broadinstitute.dsde.workbench.sam.TestSupport -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 import org.mockito.ArgumentMatchers.any import org.mockito.internal.verification.AtLeast diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/StandardSamUserDirectivesSpec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/StandardSamUserDirectivesSpec.scala index d773e69b6..50f535193 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/StandardSamUserDirectivesSpec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/StandardSamUserDirectivesSpec.scala @@ -15,7 +15,7 @@ import org.broadinstitute.dsde.workbench.sam.api.StandardSamUserDirectives._ import org.broadinstitute.dsde.workbench.sam.config.AppConfig.AdminConfig import org.broadinstitute.dsde.workbench.sam.config.{AppConfig, TermsOfServiceConfig} import org.broadinstitute.dsde.workbench.sam.dataAccess.{DirectoryDAO, MockDirectoryDAO} -import org.broadinstitute.dsde.workbench.sam.model.SamUser +import org.broadinstitute.dsde.workbench.sam.model.api.SamUser import org.broadinstitute.dsde.workbench.sam.service.{CloudExtensions, MockUserService, TosService, UserService} import org.scalatest.concurrent.ScalaFutures import org.scalatest.flatspec.AnyFlatSpec diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/TestSamRoutes.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/TestSamRoutes.scala index 9ad9e0af7..276cb96f1 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/TestSamRoutes.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/TestSamRoutes.scala @@ -19,6 +19,7 @@ import org.broadinstitute.dsde.workbench.sam.config.{LiquibaseConfig, TermsOfSer import org.broadinstitute.dsde.workbench.sam.dataAccess._ import org.broadinstitute.dsde.workbench.sam.model.SamResourceActions.{adminAddMember, adminReadPolicies, adminRemoveMember} 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, TestSupport} diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesSpec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesSpec.scala index 89f032aff..ddc1cc315 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesSpec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesSpec.scala @@ -7,8 +7,9 @@ import akka.http.scaladsl.testkit.ScalatestRouteTest import org.broadinstitute.dsde.workbench.google.GoogleDirectoryDAO import org.broadinstitute.dsde.workbench.sam.TestSupport.{genSamDependencies, genSamRoutes} import org.broadinstitute.dsde.workbench.sam.dataAccess.MockDirectoryDAO -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.SamUser import org.broadinstitute.dsde.workbench.sam.service._ import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV1Spec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV1Spec.scala index e3784a0f0..0183403cf 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV1Spec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV1Spec.scala @@ -8,7 +8,7 @@ import org.broadinstitute.dsde.workbench.model._ import org.broadinstitute.dsde.workbench.sam.Generator.genNonPetEmail import org.broadinstitute.dsde.workbench.sam.dataAccess.MockDirectoryDAO import org.broadinstitute.dsde.workbench.sam.model.RootPrimitiveJsonSupport.rootBooleanJsonFormat -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.service.{NoExtensions, StatusService, TosService, UserService} diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2Spec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2Spec.scala index cf6b9b47d..ec66de077 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2Spec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2Spec.scala @@ -5,7 +5,7 @@ import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ import akka.http.scaladsl.model.StatusCodes import org.broadinstitute.dsde.workbench.model._ import org.broadinstitute.dsde.workbench.sam.dataAccess.MockDirectoryDAO -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.service.UserService._ import org.broadinstitute.dsde.workbench.sam.service.{NoExtensions, StatusService, TosService, UserService} diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/azure/AzureRoutesSpec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/azure/AzureRoutesSpec.scala index acbb04c53..5d82b2f1b 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/azure/AzureRoutesSpec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/azure/AzureRoutesSpec.scala @@ -10,8 +10,8 @@ import org.broadinstitute.dsde.workbench.sam.api.TestSamRoutes import org.broadinstitute.dsde.workbench.sam.azure.AzureJsonSupport._ import org.broadinstitute.dsde.workbench.sam.azure.MockCrlService.mockSamSpendProfileResource import org.broadinstitute.dsde.workbench.sam.config.ManagedAppPlan -import org.broadinstitute.dsde.workbench.sam.model.SamJsonSupport._ -import org.broadinstitute.dsde.workbench.sam.model.{SamResourceTypes, SamUser} +import org.broadinstitute.dsde.workbench.sam.model.api.SamJsonSupport._ +import org.broadinstitute.dsde.workbench.sam.model.SamResourceTypes import org.broadinstitute.dsde.workbench.sam.model.api._ import org.broadinstitute.dsde.workbench.sam.service.CloudExtensions import org.broadinstitute.dsde.workbench.sam.{Generator, TestSupport} diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/azure/MockCrlService.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/azure/MockCrlService.scala index 5922809b5..cc61bbbc4 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/azure/MockCrlService.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/azure/MockCrlService.scala @@ -12,7 +12,8 @@ import com.azure.resourcemanager.msi.models.{Identities, Identity} import com.azure.resourcemanager.resources.ResourceManager import com.azure.resourcemanager.resources.models.{ResourceGroup, ResourceGroups} import org.broadinstitute.dsde.workbench.sam.config.ManagedAppPlan -import org.broadinstitute.dsde.workbench.sam.model.{FullyQualifiedResourceId, ResourceId, SamResourceTypes, SamUser} +import org.broadinstitute.dsde.workbench.sam.model.api.SamUser +import org.broadinstitute.dsde.workbench.sam.model.{FullyQualifiedResourceId, ResourceId, SamResourceTypes} import org.mockito.ArgumentMatchers import org.mockito.ArgumentMatchers.anyString import org.mockito.Mockito.{RETURNS_SMART_NULLS, lenient} diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/MockDirectoryDAO.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/MockDirectoryDAO.scala index 689df11cb..5ee12d461 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/MockDirectoryDAO.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/MockDirectoryDAO.scala @@ -9,7 +9,8 @@ import org.broadinstitute.dsde.workbench.model.google.ServiceAccountSubjectId import org.broadinstitute.dsde.workbench.sam._ import org.broadinstitute.dsde.workbench.sam.azure.{ManagedIdentityObjectId, PetManagedIdentity, PetManagedIdentityId} import org.broadinstitute.dsde.workbench.sam.db.tables.TosTable -import org.broadinstitute.dsde.workbench.sam.model.{AccessPolicy, BasicWorkbenchGroup, SamUser, SamUserTos} +import org.broadinstitute.dsde.workbench.sam.model.api.SamUser +import org.broadinstitute.dsde.workbench.sam.model.{AccessPolicy, BasicWorkbenchGroup, SamUserTos} import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext import java.time.Instant diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/MockDirectoryDaoBuilder.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/MockDirectoryDaoBuilder.scala index 5ebbeedc3..9e87c2004 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/MockDirectoryDaoBuilder.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/MockDirectoryDaoBuilder.scala @@ -2,7 +2,8 @@ package org.broadinstitute.dsde.workbench.sam.dataAccess import cats.effect.IO import org.broadinstitute.dsde.workbench.model._ -import org.broadinstitute.dsde.workbench.sam.model.{BasicWorkbenchGroup, SamUser} +import org.broadinstitute.dsde.workbench.sam.model.BasicWorkbenchGroup +import org.broadinstitute.dsde.workbench.sam.model.api.SamUser import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext import org.mockito.ArgumentMatchersSugar.{any, eqTo} import org.mockito.{IdiomaticMockito, Strictness} diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/StatefulMockDirectoryDaoBuilder.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/StatefulMockDirectoryDaoBuilder.scala index a084ab3b9..923605c9f 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/StatefulMockDirectoryDaoBuilder.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/StatefulMockDirectoryDaoBuilder.scala @@ -3,7 +3,8 @@ package org.broadinstitute.dsde.workbench.sam.dataAccess import cats.effect.IO import cats.effect.unsafe.implicits.global import org.broadinstitute.dsde.workbench.model._ -import org.broadinstitute.dsde.workbench.sam.model.{BasicWorkbenchGroup, SamUser} +import org.broadinstitute.dsde.workbench.sam.model.BasicWorkbenchGroup +import org.broadinstitute.dsde.workbench.sam.model.api.SamUser import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext import org.mockito.ArgumentMatchers import org.mockito.IdiomaticMockito.StubbingOps diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/google/GoogleExtensionRoutesSpec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/google/GoogleExtensionRoutesSpec.scala index 3f995f92b..bc05a7bee 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/google/GoogleExtensionRoutesSpec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/google/GoogleExtensionRoutesSpec.scala @@ -17,7 +17,7 @@ import org.broadinstitute.dsde.workbench.sam.TestSupport.{genSamDependencies, ge import org.broadinstitute.dsde.workbench.sam.api.SamRoutes import org.broadinstitute.dsde.workbench.sam.config.GoogleServicesConfig import org.broadinstitute.dsde.workbench.sam.mock.RealKeyMockGoogleIamDAO -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._ import org.broadinstitute.dsde.workbench.sam.service._ diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/google/GoogleExtensionRoutesV1Spec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/google/GoogleExtensionRoutesV1Spec.scala index 2d4bca345..5f1e391cd 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/google/GoogleExtensionRoutesV1Spec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/google/GoogleExtensionRoutesV1Spec.scala @@ -8,7 +8,7 @@ import cats.effect.unsafe.implicits.global import org.broadinstitute.dsde.workbench.model.WorkbenchIdentityJsonSupport._ import org.broadinstitute.dsde.workbench.model._ import org.broadinstitute.dsde.workbench.sam.TestSupport._ -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._ import org.broadinstitute.dsde.workbench.sam.service._ diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/google/GoogleGroupSyncMessageReceiverSpec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/google/GoogleGroupSyncMessageReceiverSpec.scala index 056accba6..a8f11745b 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/google/GoogleGroupSyncMessageReceiverSpec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/google/GoogleGroupSyncMessageReceiverSpec.scala @@ -9,7 +9,7 @@ import com.google.pubsub.v1.PubsubMessage import org.broadinstitute.dsde.workbench.model.WorkbenchIdentityJsonSupport.WorkbenchGroupNameFormat import org.broadinstitute.dsde.workbench.model.{ErrorReport, WorkbenchEmail, WorkbenchExceptionWithErrorReport, WorkbenchGroupName} import org.broadinstitute.dsde.workbench.sam._ -import org.broadinstitute.dsde.workbench.sam.model.SamJsonSupport.FullyQualifiedPolicyIdFormat +import org.broadinstitute.dsde.workbench.sam.model.api.SamJsonSupport.FullyQualifiedPolicyIdFormat import org.broadinstitute.dsde.workbench.sam.model._ import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext import org.mockito.ArgumentMatchers diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/matchers/BeForUserMatcher.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/matchers/BeForUserMatcher.scala index 1aa873224..14d6a775c 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/matchers/BeForUserMatcher.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/matchers/BeForUserMatcher.scala @@ -1,6 +1,7 @@ package org.broadinstitute.dsde.workbench.sam.matchers -import org.broadinstitute.dsde.workbench.sam.model.{SamUser, UserStatus} +import org.broadinstitute.dsde.workbench.sam.model.api.SamUser +import org.broadinstitute.dsde.workbench.sam.model.UserStatus import org.scalatest.matchers.{MatchResult, Matcher} import scala.collection.mutable.ListBuffer diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/matchers/BeSameUserMatcher.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/matchers/BeSameUserMatcher.scala index e3d7d18a8..c8547b920 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/matchers/BeSameUserMatcher.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/matchers/BeSameUserMatcher.scala @@ -1,6 +1,6 @@ package org.broadinstitute.dsde.workbench.sam.matchers -import org.broadinstitute.dsde.workbench.sam.model.SamUser +import org.broadinstitute.dsde.workbench.sam.model.api.SamUser import org.scalatest.matchers.{MatchResult, Matcher} import scala.collection.mutable.ListBuffer diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/model/UserStatusBuilder.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/model/UserStatusBuilder.scala index 8b3ffe03d..38cf105ca 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/model/UserStatusBuilder.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/model/UserStatusBuilder.scala @@ -1,5 +1,7 @@ package org.broadinstitute.dsde.workbench.sam.model +import org.broadinstitute.dsde.workbench.sam.model.api.SamUser + import scala.collection.mutable case class UserStatusBuilder(user: SamUser) { diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/ManagedGroupServiceSpec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/ManagedGroupServiceSpec.scala index e3aba157a..85b90173a 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/ManagedGroupServiceSpec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/ManagedGroupServiceSpec.scala @@ -8,6 +8,7 @@ import org.broadinstitute.dsde.workbench.sam.TestSupport.{databaseEnabled, datab import org.broadinstitute.dsde.workbench.sam.dataAccess.{AccessPolicyDAO, DirectoryDAO, PostgresAccessPolicyDAO, PostgresDirectoryDAO} 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.{Generator, TestSupport} import org.mockito.ArgumentMatchers import org.mockito.Mockito._ diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockCloudExtensionsBuilder.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockCloudExtensionsBuilder.scala index e28c2fdf5..dbba80809 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockCloudExtensionsBuilder.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockCloudExtensionsBuilder.scala @@ -4,7 +4,7 @@ import cats.effect.IO import org.broadinstitute.dsde.workbench.model.google.GoogleProject import org.broadinstitute.dsde.workbench.model.{WorkbenchEmail, WorkbenchGroup, WorkbenchGroupIdentity, WorkbenchUserId} import org.broadinstitute.dsde.workbench.sam.dataAccess.DirectoryDAO -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 import org.broadinstitute.dsde.workbench.util.health.{SubsystemStatus, Subsystems} import org.mockito.ArgumentMatchersSugar.{any, argThat} diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockTosServiceBuilder.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockTosServiceBuilder.scala index e54d1c767..b26620abd 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockTosServiceBuilder.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockTosServiceBuilder.scala @@ -1,7 +1,8 @@ package org.broadinstitute.dsde.workbench.sam.service import cats.effect.IO -import org.broadinstitute.dsde.workbench.sam.model.{SamUser, TermsOfServiceComplianceStatus} +import org.broadinstitute.dsde.workbench.sam.model.TermsOfServiceComplianceStatus +import org.broadinstitute.dsde.workbench.sam.model.api.SamUser import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext import org.mockito.Mockito.{RETURNS_SMART_NULLS, lenient} import org.mockito.invocation.InvocationOnMock diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockUserService.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockUserService.scala index eb949f7c4..06e35cdf2 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockUserService.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockUserService.scala @@ -6,7 +6,8 @@ import org.broadinstitute.dsde.workbench.model.google.ServiceAccountSubjectId import org.broadinstitute.dsde.workbench.openTelemetry.OpenTelemetryMetrics import org.broadinstitute.dsde.workbench.sam.azure.{ManagedIdentityObjectId, PetManagedIdentity, PetManagedIdentityId} import org.broadinstitute.dsde.workbench.sam.dataAccess.{DirectoryDAO, MockDirectoryDAO} -import org.broadinstitute.dsde.workbench.sam.model.{BasicWorkbenchGroup, SamUser} +import org.broadinstitute.dsde.workbench.sam.model.BasicWorkbenchGroup +import org.broadinstitute.dsde.workbench.sam.model.api.SamUser import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext import java.util.Date diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockUserServiceBuilder.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockUserServiceBuilder.scala index 4cb11deff..788bff11d 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockUserServiceBuilder.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockUserServiceBuilder.scala @@ -5,8 +5,8 @@ import cats.effect.IO import org.broadinstitute.dsde.workbench.google.errorReportSource import org.broadinstitute.dsde.workbench.model._ import org.broadinstitute.dsde.workbench.sam.TestSupport.enabledMapNoTosAccepted -import org.broadinstitute.dsde.workbench.sam.model.api.AdminUpdateUserRequest -import org.broadinstitute.dsde.workbench.sam.model.{SamUser, UserStatus, UserStatusDetails} +import org.broadinstitute.dsde.workbench.sam.model.api.{AdminUpdateUserRequest, SamUser} +import org.broadinstitute.dsde.workbench.sam.model.{UserStatus, UserStatusDetails} import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext import org.mockito.ArgumentMatchersSugar.{any, eqTo} import org.mockito.{IdiomaticMockito, Strictness} diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/StatefulMockCloudExtensionsBuilder.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/StatefulMockCloudExtensionsBuilder.scala index d603c2f5b..8cbe8d59b 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/StatefulMockCloudExtensionsBuilder.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/StatefulMockCloudExtensionsBuilder.scala @@ -4,7 +4,7 @@ import cats.effect.IO import cats.effect.unsafe.implicits.global import org.broadinstitute.dsde.workbench.model.{WorkbenchGroup, WorkbenchGroupIdentity, WorkbenchUserId} import org.broadinstitute.dsde.workbench.sam.dataAccess.DirectoryDAO -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 import org.mockito.Mockito.{RETURNS_SMART_NULLS, lenient} import org.mockito.invocation.InvocationOnMock diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/TestUserServiceBuilder.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/TestUserServiceBuilder.scala index f8de89186..089478219 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/TestUserServiceBuilder.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/TestUserServiceBuilder.scala @@ -4,7 +4,7 @@ import cats.effect.IO import org.broadinstitute.dsde.workbench.model.WorkbenchGroup import org.broadinstitute.dsde.workbench.openTelemetry.OpenTelemetryMetrics import org.broadinstitute.dsde.workbench.sam.dataAccess.{DirectoryDAO, StatefulMockDirectoryDaoBuilder} -import org.broadinstitute.dsde.workbench.sam.model.SamUser +import org.broadinstitute.dsde.workbench.sam.model.api.SamUser import scala.collection.mutable import scala.concurrent.ExecutionContext diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpec.scala index 66690e4e7..875528729 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpec.scala @@ -12,6 +12,7 @@ import org.broadinstitute.dsde.workbench.sam.google.GoogleExtensions import org.broadinstitute.dsde.workbench.sam.matchers.BeSameUserMatcher.beSameUserAs import org.broadinstitute.dsde.workbench.sam.matchers.TimeMatchers import org.broadinstitute.dsde.workbench.sam.model._ +import org.broadinstitute.dsde.workbench.sam.model.api.SamUser import org.broadinstitute.dsde.workbench.sam.service.UserServiceSpecs.{CreateUserSpec, GetUserStatusSpec, InviteUserSpec} import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext import org.mockito.Mockito diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/CreateUserSpec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/CreateUserSpec.scala index 9616276dd..12a28e64d 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/CreateUserSpec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/CreateUserSpec.scala @@ -5,7 +5,8 @@ import org.broadinstitute.dsde.workbench.sam.Generator.{genWorkbenchUserAzure, g import org.broadinstitute.dsde.workbench.sam.dataAccess.{DirectoryDAO, MockDirectoryDaoBuilder} import org.broadinstitute.dsde.workbench.sam.matchers.BeEnabledInMatcher.beEnabledIn import org.broadinstitute.dsde.workbench.sam.matchers.BeForUserMatcher.beForUser -import org.broadinstitute.dsde.workbench.sam.model.{BasicWorkbenchGroup, SamUser} +import org.broadinstitute.dsde.workbench.sam.model.BasicWorkbenchGroup +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.mockito.ArgumentMatchersSugar.{any, eqTo} diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/InviteUserSpec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/InviteUserSpec.scala index 2b9d1bd33..c8a06cf3f 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/InviteUserSpec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/InviteUserSpec.scala @@ -2,7 +2,8 @@ package org.broadinstitute.dsde.workbench.sam.service.UserServiceSpecs import org.broadinstitute.dsde.workbench.model.WorkbenchEmail import org.broadinstitute.dsde.workbench.sam.Generator.{genWorkbenchUserBoth, genWorkbenchUserGoogle} -import org.broadinstitute.dsde.workbench.sam.model.{BasicWorkbenchGroup, SamUser} +import org.broadinstitute.dsde.workbench.sam.model.BasicWorkbenchGroup +import org.broadinstitute.dsde.workbench.sam.model.api.SamUser import org.broadinstitute.dsde.workbench.sam.service.GenEmail.genBadChar import org.broadinstitute.dsde.workbench.sam.service.{CloudExtensions, TestUserServiceBuilder} import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext From 8da07d8632e243ac72e5bc468ab59353cf6b5c81 Mon Sep 17 00:00:00 2001 From: tlangs Date: Fri, 13 Oct 2023 09:38:03 -0400 Subject: [PATCH 2/8] endpoints --- src/main/resources/swagger/api-docs.yaml | 86 +++++++++++++++++++ .../dsde/workbench/sam/api/SamRoutes.scala | 6 +- .../dsde/workbench/sam/api/UserRoutesV3.scala | 66 ++++++++++++++ 3 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV3.scala diff --git a/src/main/resources/swagger/api-docs.yaml b/src/main/resources/swagger/api-docs.yaml index c53d56e48..cf28a5ea3 100755 --- a/src/main/resources/swagger/api-docs.yaml +++ b/src/main/resources/swagger/api-docs.yaml @@ -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/SamUser' + 404: + description: user not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorReport' + /api/users/v2/{sam_user_id}: + get: + tags: + - Users + 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/SamUser' + 404: + description: user not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorReport' /register/user/v1: get: tags: @@ -3799,6 +3847,44 @@ components: format: date-time description: User's time of last update description: specification of a User + SamUser: + type: object + required: + - id + - email + - enabled + - 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 + enabled: + type: boolean + description: Whether or not the user is enabled + 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: diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/SamRoutes.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/SamRoutes.scala index 12bd46c2f..b5389b886 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/SamRoutes.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/SamRoutes.scala @@ -55,7 +55,8 @@ abstract class SamRoutes( with ManagedGroupRoutes with AdminRoutes with AzureRoutes - with ServiceAdminRoutes { + with ServiceAdminRoutes + with UserRoutesV3 { def route: server.Route = (logRequestResult & handleExceptions(myExceptionHandler)) { oidcConfig.swaggerRoutes("swagger/api-docs.yaml") ~ @@ -76,7 +77,8 @@ abstract class SamRoutes( extensionRoutes(samUser, samRequestContextWithUser) ~ groupRoutes(samUser, samRequestContextWithUser) ~ apiUserRoutes(samUser, samRequestContextWithUser) ~ - azureRoutes(samUser, samRequestContextWithUser) + azureRoutes(samUser, samRequestContextWithUser) ~ + userRoutesV3(samUser, samRequestContextWithUser) } } } diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV3.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV3.scala new file mode 100644 index 000000000..24675c178 --- /dev/null +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV3.scala @@ -0,0 +1,66 @@ +package org.broadinstitute.dsde.workbench.sam.api + +import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ +import akka.http.scaladsl.model.StatusCodes +import akka.http.scaladsl.model.StatusCodes.{NotFound, OK} +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.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 + +/** Created by tlangs on 10/12/2023. + */ +trait UserRoutesV3 extends SamUserDirectives with SamRequestContextDirectives { + val userService: UserService + + /** Changes a 403 error to a 404 error. Used when `UserInfoDirectives` throws a 403 in the case where a user is not found. In most routes that is appropriate + * but in the user routes it should be a 404. + */ + private val changeForbiddenToNotFound: Directive0 = { + import org.broadinstitute.dsde.workbench.model.ErrorReportJsonSupport._ + + handleExceptions(ExceptionHandler { + case withErrorReport: WorkbenchExceptionWithErrorReport if withErrorReport.errorReport.statusCode.contains(StatusCodes.Forbidden) => + complete((StatusCodes.NotFound, withErrorReport.errorReport.copy(statusCode = Option(StatusCodes.NotFound)))) + }) + } + + def userRoutesV3(samUser: SamUser, samRequestContext: SamRequestContext): server.Route = + pathPrefix("users") { + pathPrefix("v2") { + pathPrefix("self") { + pathEndOrSingleSlash { + get { + complete { + StatusCodes.OK -> samUser + } + } + } + } ~ + pathPrefix(Segment) { samUserId => + pathEndOrSingleSlash { + val workbenchUserId = WorkbenchUserId(samUserId) + if (workbenchUserId.equals(samUser.id)) { + get { + complete { + StatusCodes.OK -> samUser + } + } + } else { + (changeForbiddenToNotFound & asWorkbenchAdmin(samUser)) { + get { + complete { + userService.getUser(WorkbenchUserId(samUserId), samRequestContext).map(user => (if (user.isDefined) OK else NotFound) -> user) + } + } + } + } + } + } + } + } +} From 5682628dc12bcfa8d294efcc510f45ad17bf79b9 Mon Sep 17 00:00:00 2001 From: tlangs Date: Fri, 13 Oct 2023 10:02:24 -0400 Subject: [PATCH 3/8] a wee bit of a refactor --- .../{UserRoutes.scala => OldUserRoutes.scala} | 32 +------------ .../dsde/workbench/sam/api/SamRoutes.scala | 9 ++-- .../dsde/workbench/sam/api/UserRoutesV1.scala | 45 +++++++++++++++++++ ...{UserRoutesV3.scala => UserRoutesV2.scala} | 4 +- .../workbench/sam/api/MockSamRoutes.scala | 5 ++- ...utesSpec.scala => OldUserRoutesSpec.scala} | 4 +- ...V1Spec.scala => OldUserRoutesV1Spec.scala} | 2 +- ...V2Spec.scala => OldUserRoutesV2Spec.scala} | 2 +- 8 files changed, 60 insertions(+), 43 deletions(-) rename src/main/scala/org/broadinstitute/dsde/workbench/sam/api/{UserRoutes.scala => OldUserRoutes.scala} (84%) create mode 100644 src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV1.scala rename src/main/scala/org/broadinstitute/dsde/workbench/sam/api/{UserRoutesV3.scala => UserRoutesV2.scala} (95%) rename src/test/scala/org/broadinstitute/dsde/workbench/sam/api/{UserRoutesSpec.scala => OldUserRoutesSpec.scala} (95%) rename src/test/scala/org/broadinstitute/dsde/workbench/sam/api/{UserRoutesV1Spec.scala => OldUserRoutesV1Spec.scala} (99%) rename src/test/scala/org/broadinstitute/dsde/workbench/sam/api/{UserRoutesV2Spec.scala => OldUserRoutesV2Spec.scala} (98%) diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutes.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/OldUserRoutes.scala similarity index 84% rename from src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutes.scala rename to src/main/scala/org/broadinstitute/dsde/workbench/sam/api/OldUserRoutes.scala index 579d9551c..60e8492c1 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutes.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/OldUserRoutes.scala @@ -8,7 +8,6 @@ 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.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 import spray.json.JsBoolean @@ -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 @@ -151,33 +150,4 @@ trait UserRoutes extends SamUserDirectives with SamRequestContextDirectives { } } } - - def apiUserRoutes(samUser: SamUser, samRequestContext: SamRequestContext): server.Route = pathPrefix("users") { - 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) - } - } - } - } - } - } } diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/SamRoutes.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/SamRoutes.scala index b5389b886..0b2f2d17d 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/SamRoutes.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/SamRoutes.scala @@ -48,7 +48,7 @@ abstract class SamRoutes( val openTelemetry: OpenTelemetryMetrics[IO] ) extends LazyLogging with ResourceRoutes - with UserRoutes + with OldUserRoutes with StatusRoutes with TermsOfServiceRoutes with ExtensionRoutes @@ -56,7 +56,8 @@ abstract class SamRoutes( with AdminRoutes with AzureRoutes with ServiceAdminRoutes - with UserRoutesV3 { + with UserRoutesV1 + with UserRoutesV2 { def route: server.Route = (logRequestResult & handleExceptions(myExceptionHandler)) { oidcConfig.swaggerRoutes("swagger/api-docs.yaml") ~ @@ -76,9 +77,9 @@ abstract class SamRoutes( adminRoutes(samUser, samRequestContextWithUser) ~ extensionRoutes(samUser, samRequestContextWithUser) ~ groupRoutes(samUser, samRequestContextWithUser) ~ - apiUserRoutes(samUser, samRequestContextWithUser) ~ azureRoutes(samUser, samRequestContextWithUser) ~ - userRoutesV3(samUser, samRequestContextWithUser) + userRoutesV1(samUser, samRequestContextWithUser) ~ + userRoutesV2(samUser, samRequestContextWithUser) } } } diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV1.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV1.scala new file mode 100644 index 000000000..fc6da229f --- /dev/null +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV1.scala @@ -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") { + 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) + } + } + } + } + } + } + +} diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV3.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2.scala similarity index 95% rename from src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV3.scala rename to src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2.scala index 24675c178..266cc24c9 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV3.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2.scala @@ -14,7 +14,7 @@ import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext /** Created by tlangs on 10/12/2023. */ -trait UserRoutesV3 extends SamUserDirectives with SamRequestContextDirectives { +trait UserRoutesV2 extends SamUserDirectives with SamRequestContextDirectives { val userService: UserService /** Changes a 403 error to a 404 error. Used when `UserInfoDirectives` throws a 403 in the case where a user is not found. In most routes that is appropriate @@ -29,7 +29,7 @@ trait UserRoutesV3 extends SamUserDirectives with SamRequestContextDirectives { }) } - def userRoutesV3(samUser: SamUser, samRequestContext: SamRequestContext): server.Route = + def userRoutesV2(samUser: SamUser, samRequestContext: SamRequestContext): server.Route = pathPrefix("users") { pathPrefix("v2") { pathPrefix("self") { diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamRoutes.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamRoutes.scala index 5b86a6467..89c24a279 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamRoutes.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamRoutes.scala @@ -47,7 +47,8 @@ abstract class MockSamRoutes( val openTelemetry: OpenTelemetryMetrics[IO] ) extends LazyLogging with ResourceRoutes - with UserRoutes + with OldUserRoutes + with UserRoutesV1 with MockStatusRoutes with TermsOfServiceRoutes with ExtensionRoutes @@ -71,7 +72,7 @@ abstract class MockSamRoutes( adminRoutes(samUser, samRequestContextWithUser) ~ extensionRoutes(samUser, samRequestContextWithUser) ~ groupRoutes(samUser, samRequestContextWithUser) ~ - apiUserRoutes(samUser, samRequestContextWithUser) ~ + userRoutesV1(samUser, samRequestContextWithUser) ~ azureRoutes(samUser, samRequestContextWithUser) } } diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesSpec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/OldUserRoutesSpec.scala similarity index 95% rename from src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesSpec.scala rename to src/test/scala/org/broadinstitute/dsde/workbench/sam/api/OldUserRoutesSpec.scala index ddc1cc315..0c1b04e70 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesSpec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/OldUserRoutesSpec.scala @@ -17,7 +17,7 @@ import org.mockito.scalatest.MockitoSugar /** Created by dvoet on 6/7/17. */ -class UserRoutesSpec extends UserRoutesSpecHelper { +class OldUserRoutesSpec extends OldUserRoutesSpecHelper { "POST /register/user" should "create user" in withDefaultRoutes { samRoutes => Post("/register/user") ~> samRoutes.route ~> check { status shouldEqual StatusCodes.Created @@ -42,7 +42,7 @@ class UserRoutesSpec extends UserRoutesSpecHelper { } } -trait UserRoutesSpecHelper extends AnyFlatSpec with Matchers with ScalatestRouteTest with MockitoSugar with TestSupport { +trait OldUserRoutesSpecHelper extends AnyFlatSpec with Matchers with ScalatestRouteTest with MockitoSugar with TestSupport { val defaultUser = Generator.genWorkbenchUserGoogle.sample.get val defaultUserId = defaultUser.id val defaultUserEmail = defaultUser.email diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV1Spec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/OldUserRoutesV1Spec.scala similarity index 99% rename from src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV1Spec.scala rename to src/test/scala/org/broadinstitute/dsde/workbench/sam/api/OldUserRoutesV1Spec.scala index 0183403cf..c4f641559 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV1Spec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/OldUserRoutesV1Spec.scala @@ -14,7 +14,7 @@ import org.broadinstitute.dsde.workbench.sam.service.{NoExtensions, StatusServic /** Created by dvoet on 6/7/17. */ -class UserRoutesV1Spec extends UserRoutesSpecHelper { +class OldUserRoutesV1Spec extends OldUserRoutesSpecHelper { def withSARoutes[T](testCode: (TestSamRoutes, TestSamRoutes) => T): T = { val directoryDAO = new MockDirectoryDAO() diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2Spec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/OldUserRoutesV2Spec.scala similarity index 98% rename from src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2Spec.scala rename to src/test/scala/org/broadinstitute/dsde/workbench/sam/api/OldUserRoutesV2Spec.scala index ec66de077..c7014f8ae 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2Spec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/OldUserRoutesV2Spec.scala @@ -12,7 +12,7 @@ import org.broadinstitute.dsde.workbench.sam.service.{NoExtensions, StatusServic /** Created by mtalbott on 8/8/18. */ -class UserRoutesV2Spec extends UserRoutesSpecHelper { +class OldUserRoutesV2Spec extends OldUserRoutesSpecHelper { def withSARoutes[T](testCode: (TestSamRoutes, TestSamRoutes) => T): T = { val directoryDAO = new MockDirectoryDAO() From 6cd88379f84369e79c16323d1f2ef092e834c45d Mon Sep 17 00:00:00 2001 From: tlangs Date: Fri, 13 Oct 2023 12:39:47 -0400 Subject: [PATCH 4/8] tests --- .../workbench/sam/api/MockSamRoutes.scala | 2 +- .../workbench/sam/api/UserRoutesV2Spec.scala | 85 +++++++++++++++++++ .../sam/matchers/BeForSamUserMatcher.scala | 41 +++++++++ 3 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2Spec.scala create mode 100644 src/test/scala/org/broadinstitute/dsde/workbench/sam/matchers/BeForSamUserMatcher.scala diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamRoutes.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamRoutes.scala index 89c24a279..e2aefe7ab 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamRoutes.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamRoutes.scala @@ -47,7 +47,7 @@ abstract class MockSamRoutes( val openTelemetry: OpenTelemetryMetrics[IO] ) extends LazyLogging with ResourceRoutes - with OldUserRoutes + with OldUserRoutes with UserRoutesV1 with MockStatusRoutes with TermsOfServiceRoutes diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2Spec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2Spec.scala new file mode 100644 index 000000000..14585f084 --- /dev/null +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2Spec.scala @@ -0,0 +1,85 @@ +package org.broadinstitute.dsde.workbench.sam.api + +import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ +import akka.http.scaladsl.model.StatusCodes +import akka.http.scaladsl.testkit.ScalatestRouteTest +import org.broadinstitute.dsde.workbench.model.{ErrorReport, WorkbenchEmail} +import org.broadinstitute.dsde.workbench.model.ErrorReportJsonSupport._ +import org.broadinstitute.dsde.workbench.sam.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._ +import org.broadinstitute.dsde.workbench.sam.{Generator, TestSupport} +import org.mockito.scalatest.MockitoSugar +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers + +class UserRoutesV2Spec extends AnyFlatSpec with Matchers with ScalatestRouteTest with MockitoSugar with TestSupport { + val defaultUser: SamUser = Generator.genWorkbenchUserGoogle.sample.get + val otherUser: SamUser = Generator.genWorkbenchUserGoogle.sample.get + val adminGroupEmail: WorkbenchEmail = Generator.genFirecloudEmail.sample.get + val allUsersGroup: BasicWorkbenchGroup = BasicWorkbenchGroup(CloudExtensions.allUsersGroupName, Set(), WorkbenchEmail("all_users@fake.com")) + + "GET /api/users/v2/self" should "get the user object of the requesting user" in { + // Arrange + val samRoutes = new MockSamRoutesBuilder(allUsersGroup) + .withEnabledUser(defaultUser) // "persisted/enabled" user we will check the status of + .callAsNonAdminUser() + .build + + // Act and Assert + Get(s"/api/users/v2/self") ~> samRoutes.route ~> check { + status shouldEqual StatusCodes.OK + responseAs[SamUser] should be(defaultUser) + } + } + + "GET /api/users/v2/{sam_user_id}" should "return the regular user if they're getting themselves" in { + // Arrange + val samRoutes = new MockSamRoutesBuilder(allUsersGroup) + .withEnabledUsers(Seq(defaultUser, otherUser)) + .callAsNonAdminUser() + .build + + // Act and Assert + Get(s"/api/users/v2/${defaultUser.id}") ~> samRoutes.route ~> check { + status shouldEqual StatusCodes.OK + responseAs[SamUser] should be(defaultUser) + } + } + + it should "fail with Not Found if a regular user is getting another user" in { + // Arrange + val otherUser = Generator.genWorkbenchUserGoogle.sample.get + val samRoutes = new MockSamRoutesBuilder(allUsersGroup) + .withEnabledUsers(Seq(defaultUser, otherUser)) + .callAsNonAdminUser() + .build + + // Act and Assert + Get(s"/api/users/v2/${otherUser.id}") ~> samRoutes.route ~> check { + status shouldEqual StatusCodes.NotFound + val foo = responseAs[ErrorReport] + foo.message contains "You must be an admin" + } + } + + it should "succeed if an admin user is getting another user" in { + // Arrange + val samRoutes = new MockSamRoutesBuilder(allUsersGroup) + .withEnabledUsers(Seq(defaultUser, otherUser)) + .callAsAdminUser() + .build + + // Act and Assert + Get(s"/api/users/v2/${defaultUser.id}") ~> samRoutes.route ~> check { + status shouldEqual StatusCodes.OK + responseAs[SamUser] should be(defaultUser) + } + + Get(s"/api/users/v2/${otherUser.id}") ~> samRoutes.route ~> check { + status shouldEqual StatusCodes.OK + responseAs[SamUser] should be(otherUser) + } + } +} diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/matchers/BeForSamUserMatcher.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/matchers/BeForSamUserMatcher.scala new file mode 100644 index 000000000..603409abc --- /dev/null +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/matchers/BeForSamUserMatcher.scala @@ -0,0 +1,41 @@ +package org.broadinstitute.dsde.workbench.sam.matchers + +import org.broadinstitute.dsde.workbench.sam.model.api.SamUser +import org.scalatest.matchers.{MatchResult, Matcher} + +import scala.collection.mutable.ListBuffer + +/** Asserts that the passed UserStatus.userInfo matches the passed in SamUser Id and Email + * + * @param expectedUser: + * user to expect + */ +class BeForSamUserMatcher(expectedUser: SamUser) extends Matcher[SamUser] { + def apply(samUser: SamUser): MatchResult = { + val doEmailsMatch = samUser.email == expectedUser.email + val doIdsMatch = samUser.id == expectedUser.id + + val failureMessageList: ListBuffer[String] = ListBuffer.empty + val failureMessageNegatedList: ListBuffer[String] = ListBuffer.empty + + if (!doEmailsMatch) { + failureMessageList += s"""SamUser email ${samUser.email} did not equal ${expectedUser.email}""" + failureMessageNegatedList += s"""SamUser email ${samUser.email} equals ${expectedUser.email}""" + } + + if (!doIdsMatch) { + failureMessageList += s"""SamUser id ${samUser.id} did not equal ${expectedUser.id}""" + failureMessageNegatedList += s"""SamUser id ${samUser.id} equals ${expectedUser.id}""" + } + + MatchResult( + doEmailsMatch && doIdsMatch, + failureMessageList.mkString(" and "), + failureMessageNegatedList.mkString(" and ") + ) + } +} + +object BeForSamUserMatcher { + def beForSamUser(expectedUser: SamUser) = new BeForUserMatcher(expectedUser) +} From 6b3a257c76e061201b34f2268f1068cc641cdbc1 Mon Sep 17 00:00:00 2001 From: tlangs Date: Mon, 16 Oct 2023 14:09:45 -0400 Subject: [PATCH 5/8] tests for endpoints --- src/main/resources/swagger/api-docs.yaml | 12 +-- .../dsde/workbench/sam/api/UserRoutesV2.scala | 58 +++++++++------ .../sam/model/api/SamUserResponse.scala | 37 ++++++++++ .../workbench/sam/service/UserService.scala | 3 + .../sam/api/MockSamRoutesBuilder.scala | 9 +++ .../workbench/sam/api/UserRoutesV2Spec.scala | 19 +++-- .../sam/matchers/BeForSamUserMatcher.scala | 41 ----------- .../BeForSamUserResponseMatcher.scala | 41 +++++++++++ .../sam/service/MockUserServiceBuilder.scala | 14 ++++ .../UserServiceSpecs/AllowedUserSpec.scala | 73 +++++++++++++++++++ 10 files changed, 231 insertions(+), 76 deletions(-) create mode 100644 src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamUserResponse.scala delete mode 100644 src/test/scala/org/broadinstitute/dsde/workbench/sam/matchers/BeForSamUserMatcher.scala create mode 100644 src/test/scala/org/broadinstitute/dsde/workbench/sam/matchers/BeForSamUserResponseMatcher.scala create mode 100644 src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/AllowedUserSpec.scala diff --git a/src/main/resources/swagger/api-docs.yaml b/src/main/resources/swagger/api-docs.yaml index cf28a5ea3..3af9dd12b 100755 --- a/src/main/resources/swagger/api-docs.yaml +++ b/src/main/resources/swagger/api-docs.yaml @@ -2805,7 +2805,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/SamUser' + $ref: '#/components/schemas/SamUserResponse' 404: description: user not found content: @@ -2815,7 +2815,7 @@ paths: /api/users/v2/{sam_user_id}: get: tags: - - Users + - 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. @@ -2834,7 +2834,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/SamUser' + $ref: '#/components/schemas/SamUserResponse' 404: description: user not found content: @@ -3847,7 +3847,7 @@ components: format: date-time description: User's time of last update description: specification of a User - SamUser: + SamUserResponse: type: object required: - id @@ -3869,9 +3869,9 @@ components: azureB2CId: type: string description: User's Azure B2C Id - enabled: + allowed: type: boolean - description: Whether or not the user is enabled + description: Whether or not the user allowed to use the system createdAt: type: string format: date-time diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2.scala index 266cc24c9..9aa766323 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2.scala @@ -5,10 +5,11 @@ import akka.http.scaladsl.model.StatusCodes import akka.http.scaladsl.model.StatusCodes.{NotFound, OK} import akka.http.scaladsl.server import akka.http.scaladsl.server.Directives._ -import akka.http.scaladsl.server.{Directive0, ExceptionHandler} +import akka.http.scaladsl.server.{Directive0, ExceptionHandler, Route} +import cats.effect.IO 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.model.api.SamUserResponse._ +import org.broadinstitute.dsde.workbench.sam.model.api.{SamUser, SamUserResponse} import org.broadinstitute.dsde.workbench.sam.service.UserService import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext @@ -34,33 +35,46 @@ trait UserRoutesV2 extends SamUserDirectives with SamRequestContextDirectives { pathPrefix("v2") { pathPrefix("self") { pathEndOrSingleSlash { - get { - complete { - StatusCodes.OK -> samUser - } - } + getSamUserResponse(samUser, samRequestContext) } } ~ pathPrefix(Segment) { samUserId => pathEndOrSingleSlash { - val workbenchUserId = WorkbenchUserId(samUserId) - if (workbenchUserId.equals(samUser.id)) { - get { - complete { - StatusCodes.OK -> samUser - } - } + if (samUser.id.value.equals(samUserId)) { + getSamUserResponse(samUser, samRequestContext) } else { - (changeForbiddenToNotFound & asWorkbenchAdmin(samUser)) { - get { - complete { - userService.getUser(WorkbenchUserId(samUserId), samRequestContext).map(user => (if (user.isDefined) OK else NotFound) -> user) - } - } - } + getAdminSamUserResponse(samUser, WorkbenchUserId(samUserId), samRequestContext) + } } } } } + + private def getAdminSamUserResponse(callingSamUser: SamUser, samUserId: WorkbenchUserId, samRequestContext: SamRequestContext): Route = + (changeForbiddenToNotFound & asWorkbenchAdmin(callingSamUser)) { + get { + complete { + for { + user <- userService.getUser(samUserId, samRequestContext) + response <- user match { + case Some(value) => samUserResponse(value, samRequestContext).map(Some(_)) + case None => IO(None) + } + } yield (if (response.isDefined) OK else NotFound) -> response + } + } + } + + private def getSamUserResponse(samUser: SamUser, samRequestContext: SamRequestContext): server.Route = + get { + complete { + samUserResponse(samUser, samRequestContext).map(response => StatusCodes.OK -> response) + } + } + private def samUserResponse(samUser: SamUser, samRequestContext: SamRequestContext): IO[SamUserResponse] = + for { + allowed <- userService.userAllowedToUseSystem(samUser, samRequestContext) + } yield SamUserResponse(samUser, allowed) + } diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamUserResponse.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamUserResponse.scala new file mode 100644 index 000000000..924776240 --- /dev/null +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamUserResponse.scala @@ -0,0 +1,37 @@ +package org.broadinstitute.dsde.workbench.sam.model.api + +import org.broadinstitute.dsde.workbench.model.{AzureB2CId, GoogleSubjectId, WorkbenchEmail, WorkbenchUserId} +import spray.json.DefaultJsonProtocol.jsonFormat8 +import spray.json.DefaultJsonProtocol._ +import org.broadinstitute.dsde.workbench.model.WorkbenchIdentityJsonSupport._ +import org.broadinstitute.dsde.workbench.model.google.GoogleModelJsonSupport.InstantFormat +import spray.json.RootJsonFormat + +import java.time.Instant + +object SamUserResponse { + + implicit val SamUserFormat: RootJsonFormat[SamUserResponse] = jsonFormat8(SamUserResponse.apply) + + def apply(samUser: SamUser, allowed: Boolean): SamUserResponse = + SamUserResponse( + samUser.id, + samUser.googleSubjectId, + samUser.email, + samUser.azureB2CId, + allowed = allowed, + samUser.createdAt, + samUser.registeredAt, + samUser.updatedAt + ) +} +final case class SamUserResponse( + id: WorkbenchUserId, + googleSubjectId: Option[GoogleSubjectId], + email: WorkbenchEmail, + azureB2CId: Option[AzureB2CId], + allowed: Boolean, + createdAt: Instant, + registeredAt: Option[Instant], + updatedAt: Instant +) {} diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/UserService.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/UserService.scala index 58806e5ce..aaaefdfb5 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/UserService.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/UserService.scala @@ -427,6 +427,9 @@ class UserService(val directoryDAO: DirectoryDAO, val cloudExtensions: CloudExte case UserService.emailRegex() => IO.unit case _ => IO.raiseError(new WorkbenchExceptionWithErrorReport(ErrorReport(StatusCodes.BadRequest, s"invalid email address [${email.value}]"))) } + + def userAllowedToUseSystem(samUser: SamUser, samRequestContext: SamRequestContext): IO[Boolean] = + tosService.getTosComplianceStatus(samUser, samRequestContext).map(status => samUser.enabled && status.permitsSystemUsage) } object UserService { diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamRoutesBuilder.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamRoutesBuilder.scala index e076bd0ee..5de9001d3 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamRoutesBuilder.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamRoutesBuilder.scala @@ -54,6 +54,15 @@ class MockSamRoutesBuilder(allUsersGroup: WorkbenchGroup)(implicit system: Actor this } + def withAllowedUser(samUser: SamUser): MockSamRoutesBuilder = { + userServiceBuilder.withAllowedUser(samUser) + this + } + def withAllowedUsers(samUsers: Iterable[SamUser]): MockSamRoutesBuilder = { + userServiceBuilder.withAllowedUsers(samUsers) + this + } + def callAsAdminUser(): MockSamRoutesBuilder = { cloudExtensionsBuilder.withAdminUser() this diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2Spec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2Spec.scala index 14585f084..2e70f0de2 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2Spec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2Spec.scala @@ -5,9 +5,9 @@ import akka.http.scaladsl.model.StatusCodes import akka.http.scaladsl.testkit.ScalatestRouteTest import org.broadinstitute.dsde.workbench.model.{ErrorReport, WorkbenchEmail} import org.broadinstitute.dsde.workbench.model.ErrorReportJsonSupport._ +import org.broadinstitute.dsde.workbench.sam.matchers.BeForSamUserResponseMatcher.beForUser import org.broadinstitute.dsde.workbench.sam.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.model.api.{SamUser, SamUserResponse} import org.broadinstitute.dsde.workbench.sam.service._ import org.broadinstitute.dsde.workbench.sam.{Generator, TestSupport} import org.mockito.scalatest.MockitoSugar @@ -24,13 +24,14 @@ class UserRoutesV2Spec extends AnyFlatSpec with Matchers with ScalatestRouteTest // Arrange val samRoutes = new MockSamRoutesBuilder(allUsersGroup) .withEnabledUser(defaultUser) // "persisted/enabled" user we will check the status of + .withAllowedUser(defaultUser) // "allowed" user we will check the status of .callAsNonAdminUser() .build // Act and Assert Get(s"/api/users/v2/self") ~> samRoutes.route ~> check { status shouldEqual StatusCodes.OK - responseAs[SamUser] should be(defaultUser) + responseAs[SamUserResponse] should beForUser(defaultUser) } } @@ -38,21 +39,22 @@ class UserRoutesV2Spec extends AnyFlatSpec with Matchers with ScalatestRouteTest // Arrange val samRoutes = new MockSamRoutesBuilder(allUsersGroup) .withEnabledUsers(Seq(defaultUser, otherUser)) + .withAllowedUsers(Seq(defaultUser, otherUser)) .callAsNonAdminUser() .build // Act and Assert Get(s"/api/users/v2/${defaultUser.id}") ~> samRoutes.route ~> check { status shouldEqual StatusCodes.OK - responseAs[SamUser] should be(defaultUser) + responseAs[SamUserResponse] should beForUser(defaultUser) } } it should "fail with Not Found if a regular user is getting another user" in { // Arrange - val otherUser = Generator.genWorkbenchUserGoogle.sample.get val samRoutes = new MockSamRoutesBuilder(allUsersGroup) .withEnabledUsers(Seq(defaultUser, otherUser)) + .withAllowedUsers(Seq(defaultUser, otherUser)) .callAsNonAdminUser() .build @@ -68,18 +70,21 @@ class UserRoutesV2Spec extends AnyFlatSpec with Matchers with ScalatestRouteTest // Arrange val samRoutes = new MockSamRoutesBuilder(allUsersGroup) .withEnabledUsers(Seq(defaultUser, otherUser)) + .withAllowedUser(defaultUser) .callAsAdminUser() .build // Act and Assert Get(s"/api/users/v2/${defaultUser.id}") ~> samRoutes.route ~> check { status shouldEqual StatusCodes.OK - responseAs[SamUser] should be(defaultUser) + responseAs[SamUserResponse] should beForUser(defaultUser) + responseAs[SamUserResponse].allowed should be(true) } Get(s"/api/users/v2/${otherUser.id}") ~> samRoutes.route ~> check { status shouldEqual StatusCodes.OK - responseAs[SamUser] should be(otherUser) + responseAs[SamUserResponse] should beForUser(otherUser) + responseAs[SamUserResponse].allowed should be(false) } } } diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/matchers/BeForSamUserMatcher.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/matchers/BeForSamUserMatcher.scala deleted file mode 100644 index 603409abc..000000000 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/matchers/BeForSamUserMatcher.scala +++ /dev/null @@ -1,41 +0,0 @@ -package org.broadinstitute.dsde.workbench.sam.matchers - -import org.broadinstitute.dsde.workbench.sam.model.api.SamUser -import org.scalatest.matchers.{MatchResult, Matcher} - -import scala.collection.mutable.ListBuffer - -/** Asserts that the passed UserStatus.userInfo matches the passed in SamUser Id and Email - * - * @param expectedUser: - * user to expect - */ -class BeForSamUserMatcher(expectedUser: SamUser) extends Matcher[SamUser] { - def apply(samUser: SamUser): MatchResult = { - val doEmailsMatch = samUser.email == expectedUser.email - val doIdsMatch = samUser.id == expectedUser.id - - val failureMessageList: ListBuffer[String] = ListBuffer.empty - val failureMessageNegatedList: ListBuffer[String] = ListBuffer.empty - - if (!doEmailsMatch) { - failureMessageList += s"""SamUser email ${samUser.email} did not equal ${expectedUser.email}""" - failureMessageNegatedList += s"""SamUser email ${samUser.email} equals ${expectedUser.email}""" - } - - if (!doIdsMatch) { - failureMessageList += s"""SamUser id ${samUser.id} did not equal ${expectedUser.id}""" - failureMessageNegatedList += s"""SamUser id ${samUser.id} equals ${expectedUser.id}""" - } - - MatchResult( - doEmailsMatch && doIdsMatch, - failureMessageList.mkString(" and "), - failureMessageNegatedList.mkString(" and ") - ) - } -} - -object BeForSamUserMatcher { - def beForSamUser(expectedUser: SamUser) = new BeForUserMatcher(expectedUser) -} diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/matchers/BeForSamUserResponseMatcher.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/matchers/BeForSamUserResponseMatcher.scala new file mode 100644 index 000000000..a7fc08ab7 --- /dev/null +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/matchers/BeForSamUserResponseMatcher.scala @@ -0,0 +1,41 @@ +package org.broadinstitute.dsde.workbench.sam.matchers + +import org.broadinstitute.dsde.workbench.sam.model.api.{SamUser, SamUserResponse} +import org.scalatest.matchers.{MatchResult, Matcher} + +import scala.collection.mutable.ListBuffer + +/** Asserts that the passed UserStatus.userInfo matches the passed in SamUser Id and Email + * + * @param expectedUser: + * user to expect + */ +class BeForSamUserResponseMatcher(expectedUser: SamUser) extends Matcher[SamUserResponse] { + def apply(samUserResponse: SamUserResponse): MatchResult = { + val doEmailsMatch = samUserResponse.email == expectedUser.email + val doIdsMatch = samUserResponse.id == expectedUser.id + + val failureMessageList: ListBuffer[String] = ListBuffer.empty + val failureMessageNegatedList: ListBuffer[String] = ListBuffer.empty + + if (!doEmailsMatch) { + failureMessageList += s"""SamUserResponse email ${samUserResponse.email} did not equal ${expectedUser.email}""" + failureMessageNegatedList += s"""SamUserResponse email ${samUserResponse.email} equals ${expectedUser.email}""" + } + + if (!doIdsMatch) { + failureMessageList += s"""SamUserResponse id ${samUserResponse.id} did not equal ${expectedUser.id}""" + failureMessageNegatedList += s"""SamUserResponse id ${samUserResponse.id} equals ${expectedUser.id}""" + } + + MatchResult( + doEmailsMatch && doIdsMatch, + failureMessageList.mkString(" and "), + failureMessageNegatedList.mkString(" and ") + ) + } +} + +object BeForSamUserResponseMatcher { + def beForUser(expectedUser: SamUser) = new BeForSamUserResponseMatcher(expectedUser) +} diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockUserServiceBuilder.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockUserServiceBuilder.scala index 788bff11d..4810018d6 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockUserServiceBuilder.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockUserServiceBuilder.scala @@ -17,6 +17,7 @@ case class MockUserServiceBuilder() extends IdiomaticMockito { private val enabledUsers: mutable.Set[SamUser] = mutable.Set.empty private val disabledUsers: mutable.Set[SamUser] = mutable.Set.empty + private val allowedUsers: mutable.Set[SamUser] = mutable.Set.empty private var isBadEmail = false private def existingUsers: mutable.Set[SamUser] = @@ -36,6 +37,13 @@ case class MockUserServiceBuilder() extends IdiomaticMockito { this } + def withAllowedUser(samUser: SamUser): MockUserServiceBuilder = withAllowedUsers(Set(samUser)) + + def withAllowedUsers(samUsers: Iterable[SamUser]): MockUserServiceBuilder = { + allowedUsers.addAll(samUsers) + this + } + // TODO: Need to figure out how to have a matcher accept an update user request with a bad email def withBadEmail(): MockUserServiceBuilder = { isBadEmail = true @@ -62,6 +70,8 @@ case class MockUserServiceBuilder() extends IdiomaticMockito { ) returns { IO(Set.empty) } + + mockUserService.userAllowedToUseSystem(any[SamUser], any[SamRequestContext]) returns IO(false) } private def makeUser(samUser: SamUser, mockUserService: UserService): Unit = { @@ -151,6 +161,9 @@ case class MockUserServiceBuilder() extends IdiomaticMockito { IO(Option(UserStatus(UserStatusDetails(samUser.id, samUser.email), enabledMapNoTosAccepted))) } + private def makeUserAppearAllowed(samUser: SamUser, mockUserService: UserService): Unit = + mockUserService.userAllowedToUseSystem(eqTo(samUser), any[SamRequestContext]) returns IO(true) + private def handleMalformedEmail(mockUserService: UserService): Unit = if (isBadEmail) { mockUserService.updateUserCrud(any[WorkbenchUserId], any[AdminUpdateUserRequest], any[SamRequestContext]) returns { @@ -167,6 +180,7 @@ case class MockUserServiceBuilder() extends IdiomaticMockito { makeUsers(existingUsers, mockUserService) enabledUsers.foreach(u => makeUserAppearEnabled(u, mockUserService)) disabledUsers.foreach(u => makeUserAppearDisabled(u, mockUserService)) + allowedUsers.foreach(u => makeUserAppearAllowed(u, mockUserService)) handleMalformedEmail(mockUserService) mockUserService } diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/AllowedUserSpec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/AllowedUserSpec.scala new file mode 100644 index 000000000..4f90e34c3 --- /dev/null +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/AllowedUserSpec.scala @@ -0,0 +1,73 @@ +package org.broadinstitute.dsde.workbench.sam.service.UserServiceSpecs + +import org.broadinstitute.dsde.workbench.model.WorkbenchEmail +import org.broadinstitute.dsde.workbench.sam.Generator.genWorkbenchUserBoth +import org.broadinstitute.dsde.workbench.sam.dataAccess.{DirectoryDAO, MockDirectoryDaoBuilder} +import org.broadinstitute.dsde.workbench.sam.model.BasicWorkbenchGroup +import org.broadinstitute.dsde.workbench.sam.service.{CloudExtensions, MockCloudExtensionsBuilder, MockTosServiceBuilder, TosService, UserService} + +import scala.concurrent.ExecutionContextExecutor + +class AllowedUserSpec extends UserServiceTestTraits { + implicit val ec: ExecutionContextExecutor = scala.concurrent.ExecutionContext.global + + val allUsersGroup: BasicWorkbenchGroup = BasicWorkbenchGroup(CloudExtensions.allUsersGroupName, Set(), WorkbenchEmail("all_users@fake.com")) + + val directoryDAO: DirectoryDAO = MockDirectoryDaoBuilder(allUsersGroup).build + val cloudExtensions: CloudExtensions = MockCloudExtensionsBuilder(allUsersGroup).build + + describe("an enabled user") { + describe("who has accepted the Terms of Service") { + val userWithBothIds = genWorkbenchUserBoth.sample.get.copy(enabled = true) + val tosService: TosService = MockTosServiceBuilder().withAllAccepted().build + val userService: UserService = new UserService(directoryDAO, cloudExtensions, Seq.empty, tosService) + it("should be allowed to use the system") { + // Arrange + // Act + val response = runAndWait(userService.userAllowedToUseSystem(userWithBothIds, samRequestContext)) + + // Assert + assert(response, "The user should be allowed to use the system") + } + } + describe("who has not accepted the Terms of Service") { + val userWithBothIds = genWorkbenchUserBoth.sample.get.copy(enabled = false) + it("should not be allowed to use the system") { + // Arrange + val tosService: TosService = MockTosServiceBuilder().withNoneAccepted().build + val userService: UserService = new UserService(directoryDAO, cloudExtensions, Seq.empty, tosService) + // Act + val response = runAndWait(userService.userAllowedToUseSystem(userWithBothIds, samRequestContext)) + + // Assert + assert(!response, "The user should not be allowed to use the system") + } + } + } + describe("a disabled user") { + val userWithBothIds = genWorkbenchUserBoth.sample.get.copy(enabled = false) + it("should not be able to use the system") { + // Arrange + val tosService: TosService = MockTosServiceBuilder().withNoneAccepted().build + val userService: UserService = new UserService(directoryDAO, cloudExtensions, Seq.empty, tosService) + + // Act + val response = runAndWait(userService.userAllowedToUseSystem(userWithBothIds, samRequestContext)) + + // Assert + assert(!response, "The user should not be allowed to use the system") + } + it("should not be able to use the system even if the Terms of Service permits them to") { + // Arrange + val tosService: TosService = MockTosServiceBuilder().withAllAccepted().build + val userService: UserService = new UserService(directoryDAO, cloudExtensions, Seq.empty, tosService) + + // Act + val response = runAndWait(userService.userAllowedToUseSystem(userWithBothIds, samRequestContext)) + + // Assert + assert(!response, "The user should not be allowed to use the system") + } + } + +} From bfa676d225d8221b5759c3bcfb2a53a60367a339 Mon Sep 17 00:00:00 2001 From: tlangs Date: Mon, 16 Oct 2023 15:05:23 -0400 Subject: [PATCH 6/8] user allowed endpoint --- .../dsde/workbench/sam/api/UserRoutesV2.scala | 88 ++++++++++++++----- .../sam/model/api/SamUserAllowances.scala | 15 ++++ .../workbench/sam/service/UserService.scala | 12 ++- .../workbench/sam/api/UserRoutesV2Spec.scala | 68 +++++++++++++- .../sam/service/MockUserServiceBuilder.scala | 10 ++- .../UserServiceSpecs/AllowedUserSpec.scala | 19 ++-- 6 files changed, 172 insertions(+), 40 deletions(-) create mode 100644 src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamUserAllowances.scala diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2.scala index 9aa766323..265971a58 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2.scala @@ -3,7 +3,6 @@ package org.broadinstitute.dsde.workbench.sam.api import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ import akka.http.scaladsl.model.StatusCodes import akka.http.scaladsl.model.StatusCodes.{NotFound, OK} -import akka.http.scaladsl.server import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.server.{Directive0, ExceptionHandler, Route} import cats.effect.IO @@ -30,43 +29,63 @@ trait UserRoutesV2 extends SamUserDirectives with SamRequestContextDirectives { }) } - def userRoutesV2(samUser: SamUser, samRequestContext: SamRequestContext): server.Route = + def userRoutesV2(samUser: SamUser, samRequestContext: SamRequestContext): Route = pathPrefix("users") { pathPrefix("v2") { pathPrefix("self") { + // api/users/v2/self pathEndOrSingleSlash { getSamUserResponse(samUser, samRequestContext) - } + } ~ + // api/users/v2/self/allowed + pathPrefix("allowed") { + pathEndOrSingleSlash { + getSamUserAllowances(samUser, samRequestContext) + } + } } ~ pathPrefix(Segment) { samUserId => + val workbenchUserId = WorkbenchUserId(samUserId) + // api/users/v2/{sam_user_id} pathEndOrSingleSlash { - if (samUser.id.value.equals(samUserId)) { - getSamUserResponse(samUser, samRequestContext) - } else { - getAdminSamUserResponse(samUser, WorkbenchUserId(samUserId), samRequestContext) - + regularUserOrAdmin(samUser, workbenchUserId, samRequestContext)(getSamUserResponse)(getAdminSamUserResponse) + } ~ + // api/users/v2/{sam_user_id}/allowed + pathPrefix("allowed") { + pathEndOrSingleSlash { + regularUserOrAdmin(samUser, workbenchUserId, samRequestContext)(getSamUserAllowances)(getAdminSamUserAllowances) + } } - } } } } - private def getAdminSamUserResponse(callingSamUser: SamUser, samUserId: WorkbenchUserId, samRequestContext: SamRequestContext): Route = - (changeForbiddenToNotFound & asWorkbenchAdmin(callingSamUser)) { - get { - complete { - for { - user <- userService.getUser(samUserId, samRequestContext) - response <- user match { - case Some(value) => samUserResponse(value, samRequestContext).map(Some(_)) - case None => IO(None) - } - } yield (if (response.isDefined) OK else NotFound) -> response - } + private def regularUserOrAdmin(callingUser: SamUser, requestedUserId: WorkbenchUserId, samRequestContext: SamRequestContext)( + asRegular: (SamUser, SamRequestContext) => Route + )(asAdmin: (WorkbenchUserId, SamRequestContext) => Route): Route = + if (callingUser.id.equals(requestedUserId)) { + asRegular(callingUser, samRequestContext) + } else { + (changeForbiddenToNotFound & asWorkbenchAdmin(callingUser)) { + asAdmin(requestedUserId, samRequestContext) + } + } + + // Get Sam User + private def getAdminSamUserResponse(samUserId: WorkbenchUserId, samRequestContext: SamRequestContext): Route = + get { + complete { + for { + user <- userService.getUser(samUserId, samRequestContext) + response <- user match { + case Some(value) => samUserResponse(value, samRequestContext).map(Some(_)) + case None => IO(None) + } + } yield (if (response.isDefined) OK else NotFound) -> response } } - private def getSamUserResponse(samUser: SamUser, samRequestContext: SamRequestContext): server.Route = + private def getSamUserResponse(samUser: SamUser, samRequestContext: SamRequestContext): Route = get { complete { samUserResponse(samUser, samRequestContext).map(response => StatusCodes.OK -> response) @@ -74,7 +93,28 @@ trait UserRoutesV2 extends SamUserDirectives with SamRequestContextDirectives { } private def samUserResponse(samUser: SamUser, samRequestContext: SamRequestContext): IO[SamUserResponse] = for { - allowed <- userService.userAllowedToUseSystem(samUser, samRequestContext) - } yield SamUserResponse(samUser, allowed) + allowances <- userService.getUserAllowances(samUser, samRequestContext) + } yield SamUserResponse(samUser, allowances.allowed) + + // Get Sam User Allowed + private def getSamUserAllowances(samUser: SamUser, samRequestContext: SamRequestContext): Route = + get { + complete { + userService.getUserAllowances(samUser, samRequestContext).map(StatusCodes.OK -> _) + } + } + + private def getAdminSamUserAllowances(samUserId: WorkbenchUserId, samRequestContext: SamRequestContext): Route = + get { + complete { + for { + user <- userService.getUser(samUserId, samRequestContext) + response <- user match { + case Some(value) => userService.getUserAllowances(value, samRequestContext).map(Some(_)) + case None => IO(None) + } + } yield (if (response.isDefined) OK else NotFound) -> response + } + } } diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamUserAllowances.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamUserAllowances.scala new file mode 100644 index 000000000..a1e38b43c --- /dev/null +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamUserAllowances.scala @@ -0,0 +1,15 @@ +package org.broadinstitute.dsde.workbench.sam.model.api + +import spray.json.DefaultJsonProtocol._ +import spray.json.RootJsonFormat + +object SamUserAllowances { + implicit val SamUserAllowedResponseFormat: RootJsonFormat[SamUserAllowances] = jsonFormat2(SamUserAllowances.apply) + + def apply(allowed: Boolean, enabledInDatabase: Boolean, termsOfService: Boolean): SamUserAllowances = + SamUserAllowances(allowed, Seq("database" -> enabledInDatabase, "termsOfService" -> termsOfService)) +} +final case class SamUserAllowances( + allowed: Boolean, + details: Seq[(String, Boolean)] +) diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/UserService.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/UserService.scala index aaaefdfb5..6b8a87c6c 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/UserService.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/UserService.scala @@ -12,7 +12,7 @@ import org.broadinstitute.dsde.workbench.openTelemetry.OpenTelemetryMetrics import org.broadinstitute.dsde.workbench.sam.azure.ManagedIdentityObjectId import org.broadinstitute.dsde.workbench.sam.dataAccess.DirectoryDAO import org.broadinstitute.dsde.workbench.sam.model._ -import org.broadinstitute.dsde.workbench.sam.model.api.{AdminUpdateUserRequest, SamUser} +import org.broadinstitute.dsde.workbench.sam.model.api.{AdminUpdateUserRequest, SamUser, SamUserAllowances} import org.broadinstitute.dsde.workbench.sam.service.UserService.genWorkbenchUserId import org.broadinstitute.dsde.workbench.sam.util.AsyncLogging.IOWithLogging import org.broadinstitute.dsde.workbench.sam.util.{API_TIMING_DURATION_BUCKET, SamRequestContext} @@ -428,8 +428,14 @@ class UserService(val directoryDAO: DirectoryDAO, val cloudExtensions: CloudExte case _ => IO.raiseError(new WorkbenchExceptionWithErrorReport(ErrorReport(StatusCodes.BadRequest, s"invalid email address [${email.value}]"))) } - def userAllowedToUseSystem(samUser: SamUser, samRequestContext: SamRequestContext): IO[Boolean] = - tosService.getTosComplianceStatus(samUser, samRequestContext).map(status => samUser.enabled && status.permitsSystemUsage) + def getUserAllowances(samUser: SamUser, samRequestContext: SamRequestContext): IO[SamUserAllowances] = + for { + tosStatus <- tosService.getTosComplianceStatus(samUser, samRequestContext) + } yield SamUserAllowances( + allowed = samUser.enabled && tosStatus.permitsSystemUsage, + enabledInDatabase = samUser.enabled, + termsOfService = tosStatus.permitsSystemUsage + ) } object UserService { diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2Spec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2Spec.scala index 2e70f0de2..3382d91d2 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2Spec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2Spec.scala @@ -7,7 +7,7 @@ import org.broadinstitute.dsde.workbench.model.{ErrorReport, WorkbenchEmail} import org.broadinstitute.dsde.workbench.model.ErrorReportJsonSupport._ import org.broadinstitute.dsde.workbench.sam.matchers.BeForSamUserResponseMatcher.beForUser import org.broadinstitute.dsde.workbench.sam.model._ -import org.broadinstitute.dsde.workbench.sam.model.api.{SamUser, SamUserResponse} +import org.broadinstitute.dsde.workbench.sam.model.api.{SamUser, SamUserAllowances, SamUserResponse} import org.broadinstitute.dsde.workbench.sam.service._ import org.broadinstitute.dsde.workbench.sam.{Generator, TestSupport} import org.mockito.scalatest.MockitoSugar @@ -87,4 +87,70 @@ class UserRoutesV2Spec extends AnyFlatSpec with Matchers with ScalatestRouteTest responseAs[SamUserResponse].allowed should be(false) } } + + "GET /api/users/v2/self/allowed" should "get the user allowances of the calling user" in { + // Arrange + val samRoutes = new MockSamRoutesBuilder(allUsersGroup) + .withEnabledUser(defaultUser) // "persisted/enabled" user we will check the status of + .withAllowedUser(defaultUser) // "allowed" user we will check the status of + .callAsNonAdminUser() + .build + + // Act and Assert + Get(s"/api/users/v2/self/allowed") ~> samRoutes.route ~> check { + status shouldEqual StatusCodes.OK + responseAs[SamUserAllowances] should be(SamUserAllowances(allowed = true, enabledInDatabase = true, termsOfService = true)) + } + } + + "GET /api/users/v2/{sam_user_id}/allowed" should "return the allowances of a regular user if they're getting themselves" in { + // Arrange + val samRoutes = new MockSamRoutesBuilder(allUsersGroup) + .withEnabledUsers(Seq(defaultUser, otherUser)) + .withAllowedUsers(Seq(defaultUser, otherUser)) + .callAsNonAdminUser() + .build + + // Act and Assert + Get(s"/api/users/v2/${defaultUser.id}/allowed") ~> samRoutes.route ~> check { + status shouldEqual StatusCodes.OK + responseAs[SamUserAllowances] should be(SamUserAllowances(allowed = true, enabledInDatabase = true, termsOfService = true)) + } + } + + it should "fail with Not Found if a regular user is getting another user" in { + // Arrange + val samRoutes = new MockSamRoutesBuilder(allUsersGroup) + .withEnabledUsers(Seq(defaultUser, otherUser)) + .withAllowedUsers(Seq(defaultUser, otherUser)) + .callAsNonAdminUser() + .build + + // Act and Assert + Get(s"/api/users/v2/${otherUser.id}/allowed") ~> samRoutes.route ~> check { + status shouldEqual StatusCodes.NotFound + val foo = responseAs[ErrorReport] + foo.message contains "You must be an admin" + } + } + + it should "succeed if an admin user is getting another user" in { + // Arrange + val samRoutes = new MockSamRoutesBuilder(allUsersGroup) + .withEnabledUsers(Seq(defaultUser, otherUser)) + .withAllowedUser(defaultUser) + .callAsAdminUser() + .build + + // Act and Assert + Get(s"/api/users/v2/${defaultUser.id}/allowed") ~> samRoutes.route ~> check { + status shouldEqual StatusCodes.OK + responseAs[SamUserAllowances] should be(SamUserAllowances(allowed = true, enabledInDatabase = true, termsOfService = true)) + } + + Get(s"/api/users/v2/${otherUser.id}/allowed") ~> samRoutes.route ~> check { + status shouldEqual StatusCodes.OK + responseAs[SamUserAllowances] should be(SamUserAllowances(allowed = false, enabledInDatabase = false, termsOfService = false)) + } + } } diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockUserServiceBuilder.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockUserServiceBuilder.scala index 4810018d6..2717ddbc8 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockUserServiceBuilder.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockUserServiceBuilder.scala @@ -5,7 +5,7 @@ import cats.effect.IO import org.broadinstitute.dsde.workbench.google.errorReportSource import org.broadinstitute.dsde.workbench.model._ import org.broadinstitute.dsde.workbench.sam.TestSupport.enabledMapNoTosAccepted -import org.broadinstitute.dsde.workbench.sam.model.api.{AdminUpdateUserRequest, SamUser} +import org.broadinstitute.dsde.workbench.sam.model.api.{AdminUpdateUserRequest, SamUser, SamUserAllowances} import org.broadinstitute.dsde.workbench.sam.model.{UserStatus, UserStatusDetails} import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext import org.mockito.ArgumentMatchersSugar.{any, eqTo} @@ -71,7 +71,9 @@ case class MockUserServiceBuilder() extends IdiomaticMockito { IO(Set.empty) } - mockUserService.userAllowedToUseSystem(any[SamUser], any[SamRequestContext]) returns IO(false) + mockUserService.getUserAllowances(any[SamUser], any[SamRequestContext]) returns IO( + SamUserAllowances(allowed = false, enabledInDatabase = false, termsOfService = false) + ) } private def makeUser(samUser: SamUser, mockUserService: UserService): Unit = { @@ -162,7 +164,9 @@ case class MockUserServiceBuilder() extends IdiomaticMockito { } private def makeUserAppearAllowed(samUser: SamUser, mockUserService: UserService): Unit = - mockUserService.userAllowedToUseSystem(eqTo(samUser), any[SamRequestContext]) returns IO(true) + mockUserService.getUserAllowances(eqTo(samUser), any[SamRequestContext]) returns IO( + SamUserAllowances(allowed = true, enabledInDatabase = true, termsOfService = true) + ) private def handleMalformedEmail(mockUserService: UserService): Unit = if (isBadEmail) { diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/AllowedUserSpec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/AllowedUserSpec.scala index 4f90e34c3..ddcbbe8f0 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/AllowedUserSpec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/AllowedUserSpec.scala @@ -4,6 +4,7 @@ import org.broadinstitute.dsde.workbench.model.WorkbenchEmail import org.broadinstitute.dsde.workbench.sam.Generator.genWorkbenchUserBoth import org.broadinstitute.dsde.workbench.sam.dataAccess.{DirectoryDAO, MockDirectoryDaoBuilder} import org.broadinstitute.dsde.workbench.sam.model.BasicWorkbenchGroup +import org.broadinstitute.dsde.workbench.sam.model.api.SamUserAllowances import org.broadinstitute.dsde.workbench.sam.service.{CloudExtensions, MockCloudExtensionsBuilder, MockTosServiceBuilder, TosService, UserService} import scala.concurrent.ExecutionContextExecutor @@ -24,23 +25,23 @@ class AllowedUserSpec extends UserServiceTestTraits { it("should be allowed to use the system") { // Arrange // Act - val response = runAndWait(userService.userAllowedToUseSystem(userWithBothIds, samRequestContext)) + val response = runAndWait(userService.getUserAllowances(userWithBothIds, samRequestContext)) // Assert - assert(response, "The user should be allowed to use the system") + response should be(SamUserAllowances(allowed = true, enabledInDatabase = true, termsOfService = true)) } } describe("who has not accepted the Terms of Service") { - val userWithBothIds = genWorkbenchUserBoth.sample.get.copy(enabled = false) + val userWithBothIds = genWorkbenchUserBoth.sample.get.copy(enabled = true) it("should not be allowed to use the system") { // Arrange val tosService: TosService = MockTosServiceBuilder().withNoneAccepted().build val userService: UserService = new UserService(directoryDAO, cloudExtensions, Seq.empty, tosService) // Act - val response = runAndWait(userService.userAllowedToUseSystem(userWithBothIds, samRequestContext)) + val response = runAndWait(userService.getUserAllowances(userWithBothIds, samRequestContext)) // Assert - assert(!response, "The user should not be allowed to use the system") + response should be(SamUserAllowances(allowed = false, enabledInDatabase = true, termsOfService = false)) } } } @@ -52,10 +53,10 @@ class AllowedUserSpec extends UserServiceTestTraits { val userService: UserService = new UserService(directoryDAO, cloudExtensions, Seq.empty, tosService) // Act - val response = runAndWait(userService.userAllowedToUseSystem(userWithBothIds, samRequestContext)) + val response = runAndWait(userService.getUserAllowances(userWithBothIds, samRequestContext)) // Assert - assert(!response, "The user should not be allowed to use the system") + response should be(SamUserAllowances(allowed = false, enabledInDatabase = false, termsOfService = false)) } it("should not be able to use the system even if the Terms of Service permits them to") { // Arrange @@ -63,10 +64,10 @@ class AllowedUserSpec extends UserServiceTestTraits { val userService: UserService = new UserService(directoryDAO, cloudExtensions, Seq.empty, tosService) // Act - val response = runAndWait(userService.userAllowedToUseSystem(userWithBothIds, samRequestContext)) + val response = runAndWait(userService.getUserAllowances(userWithBothIds, samRequestContext)) // Assert - assert(!response, "The user should not be allowed to use the system") + response should be(SamUserAllowances(allowed = false, enabledInDatabase = false, termsOfService = true)) } } From c04a52f6ea1cbce76058aa864e2d31ffa7a7d18f Mon Sep 17 00:00:00 2001 From: tlangs Date: Wed, 18 Oct 2023 11:45:31 -0400 Subject: [PATCH 7/8] update api doc --- src/main/resources/swagger/api-docs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/swagger/api-docs.yaml b/src/main/resources/swagger/api-docs.yaml index 3af9dd12b..8e1f8ab07 100755 --- a/src/main/resources/swagger/api-docs.yaml +++ b/src/main/resources/swagger/api-docs.yaml @@ -3852,7 +3852,7 @@ components: required: - id - email - - enabled + - allowed - createdAt - updatedAt properties: From 4c5d9c5180d5db9fb4c77c6354b8bb6343ebddd9 Mon Sep 17 00:00:00 2001 From: tlangs Date: Wed, 18 Oct 2023 16:56:20 -0400 Subject: [PATCH 8/8] PR comments and cleanup --- src/main/resources/swagger/api-docs.yaml | 57 +++++++++++++++++++ .../dsde/workbench/sam/api/SamRoutes.scala | 4 +- .../sam/api/StandardSamUserDirectives.scala | 12 ++-- .../dsde/workbench/sam/api/UserRoutesV2.scala | 50 +++++++++------- .../sam/model/api/SamUserAllowances.scala | 13 +++-- .../workbench/sam/service/UserService.scala | 2 +- .../sam/api/MockSamRoutesBuilder.scala | 15 +++-- .../sam/api/MockSamUserDirectives.scala | 2 +- .../api/StandardSamUserDirectivesSpec.scala | 2 +- .../workbench/sam/api/UserRoutesV2Spec.scala | 21 +++---- .../sam/service/MockUserServiceBuilder.scala | 4 +- .../UserServiceSpecs/AllowedUserSpec.scala | 8 +-- 12 files changed, 132 insertions(+), 58 deletions(-) diff --git a/src/main/resources/swagger/api-docs.yaml b/src/main/resources/swagger/api-docs.yaml index 8e1f8ab07..b7242cdb7 100755 --- a/src/main/resources/swagger/api-docs.yaml +++ b/src/main/resources/swagger/api-docs.yaml @@ -2812,6 +2812,25 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorReport' + /api/users/v2/self/allowed: + get: + tags: + - Users + summary: gets the user allowances + operationId: getSamUserSelfAllowances + responses: + 200: + description: user exists + content: + application/json: + schema: + $ref: '#/components/schemas/SamUserAllowances' + 404: + description: user not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorReport' /api/users/v2/{sam_user_id}: get: tags: @@ -2841,6 +2860,35 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorReport' + /api/users/v2/{sam_user_id}/allowed: + get: + tags: + - Admin + summary: gets a user + description: Gets a users allowances 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: getSamUserAllowancesById + 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/SamUserAllowances' + 404: + description: user not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorReport' /register/user/v1: get: tags: @@ -3885,6 +3933,15 @@ components: format: date-time description: User's time of last update description: specification of a User + SamUserAllowances: + type: object + properties: + allowed: + type: boolean + description: is the user allowed to use the system + details: + type: object + description: details of the user's allowances UpdateUserRequest: type: object properties: diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/SamRoutes.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/SamRoutes.scala index 0b2f2d17d..c57a18edb 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/SamRoutes.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/SamRoutes.scala @@ -71,6 +71,7 @@ abstract class SamRoutes( // these routes are for machine to machine authorized requests // the whitelisted service admin account email is in the header of the request serviceAdminRoutes(samRequestContext) ~ + userRoutesV2(samRequestContext) ~ withActiveUser(samRequestContext) { samUser => val samRequestContextWithUser = samRequestContext.copy(samUser = Option(samUser)) resourceRoutes(samUser, samRequestContextWithUser) ~ @@ -78,8 +79,7 @@ abstract class SamRoutes( extensionRoutes(samUser, samRequestContextWithUser) ~ groupRoutes(samUser, samRequestContextWithUser) ~ azureRoutes(samUser, samRequestContextWithUser) ~ - userRoutesV1(samUser, samRequestContextWithUser) ~ - userRoutesV2(samUser, samRequestContextWithUser) + userRoutesV1(samUser, samRequestContextWithUser) } } } diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/StandardSamUserDirectives.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/StandardSamUserDirectives.scala index f468b35d1..36108ff31 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/StandardSamUserDirectives.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/StandardSamUserDirectives.scala @@ -15,7 +15,7 @@ import org.broadinstitute.dsde.workbench.sam.api.StandardSamUserDirectives._ import org.broadinstitute.dsde.workbench.sam.azure.ManagedIdentityObjectId 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.service.UserService import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext import scala.concurrent.ExecutionContext @@ -27,7 +27,7 @@ trait StandardSamUserDirectives extends SamUserDirectives with LazyLogging with def withActiveUser(samRequestContext: SamRequestContext): Directive1[SamUser] = requireOidcHeaders.flatMap { oidcHeaders => onSuccess { - getActiveSamUser(oidcHeaders, userService, tosService, samRequestContext).unsafeToFuture() + getActiveSamUser(oidcHeaders, userService, samRequestContext).unsafeToFuture() }.tmap { samUser => logger.debug(s"Handling request for active Sam User: $samUser") samUser @@ -119,15 +119,15 @@ object StandardSamUserDirectives { loadUserMaybeUpdateAzureB2CId(azureB2CId, oidcHeaders.googleSubjectIdFromAzure, userService, samRequestContext) } - def getActiveSamUser(oidcHeaders: OIDCHeaders, userService: UserService, tosService: TosService, samRequestContext: SamRequestContext): IO[SamUser] = + def getActiveSamUser(oidcHeaders: OIDCHeaders, userService: UserService, samRequestContext: SamRequestContext): IO[SamUser] = for { user <- getSamUser(oidcHeaders, userService, samRequestContext) - tosComplianceDetails <- tosService.getTosComplianceStatus(user, samRequestContext) + allowances <- userService.getUserAllowances(user, samRequestContext) } yield { - if (!tosComplianceDetails.permitsSystemUsage) { + if (!allowances.getTermsOfServiceCompliance) { throw new WorkbenchExceptionWithErrorReport(ErrorReport(StatusCodes.Unauthorized, "User must accept the latest terms of service.")) } - if (!user.enabled) { + if (!allowances.getEnabled) { throw new WorkbenchExceptionWithErrorReport(ErrorReport(StatusCodes.Unauthorized, "User is disabled.")) } diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2.scala index 265971a58..057b9952e 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2.scala @@ -29,34 +29,40 @@ trait UserRoutesV2 extends SamUserDirectives with SamRequestContextDirectives { }) } - def userRoutesV2(samUser: SamUser, samRequestContext: SamRequestContext): Route = - pathPrefix("users") { - pathPrefix("v2") { - pathPrefix("self") { - // api/users/v2/self - pathEndOrSingleSlash { - getSamUserResponse(samUser, samRequestContext) - } ~ - // api/users/v2/self/allowed - pathPrefix("allowed") { - pathEndOrSingleSlash { - getSamUserAllowances(samUser, samRequestContext) - } - } - } ~ - pathPrefix(Segment) { samUserId => - val workbenchUserId = WorkbenchUserId(samUserId) - // api/users/v2/{sam_user_id} + // These routes are wrapped in `withUserAllowInactive` because a user should be able to get info about themselves + // Routes that need the user to be active should be wrapped in a directive, such as `withActiveUser`, to ensure + // that the user is allowed to use the system. + def userRoutesV2(samRequestContextWithoutUser: SamRequestContext): Route = + withUserAllowInactive(samRequestContextWithoutUser) { samUser: SamUser => + val samRequestContext = samRequestContextWithoutUser.copy(samUser = Some(samUser)) + pathPrefix("users") { + pathPrefix("v2") { + pathPrefix("self") { + // api/users/v2/self pathEndOrSingleSlash { - regularUserOrAdmin(samUser, workbenchUserId, samRequestContext)(getSamUserResponse)(getAdminSamUserResponse) + getSamUserResponse(samUser, samRequestContext) } ~ - // api/users/v2/{sam_user_id}/allowed + // api/users/v2/self/allowed pathPrefix("allowed") { pathEndOrSingleSlash { - regularUserOrAdmin(samUser, workbenchUserId, samRequestContext)(getSamUserAllowances)(getAdminSamUserAllowances) + getSamUserAllowances(samUser, samRequestContext) } } - } + } ~ + pathPrefix(Segment) { samUserId => + val workbenchUserId = WorkbenchUserId(samUserId) + // api/users/v2/{sam_user_id} + pathEndOrSingleSlash { + regularUserOrAdmin(samUser, workbenchUserId, samRequestContext)(getSamUserResponse)(getAdminSamUserResponse) + } ~ + // api/users/v2/{sam_user_id}/allowed + pathPrefix("allowed") { + pathEndOrSingleSlash { + regularUserOrAdmin(samUser, workbenchUserId, samRequestContext)(getSamUserAllowances)(getAdminSamUserAllowances) + } + } + } + } } } diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamUserAllowances.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamUserAllowances.scala index a1e38b43c..6cbaf7c9b 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamUserAllowances.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamUserAllowances.scala @@ -6,10 +6,15 @@ import spray.json.RootJsonFormat object SamUserAllowances { implicit val SamUserAllowedResponseFormat: RootJsonFormat[SamUserAllowances] = jsonFormat2(SamUserAllowances.apply) - def apply(allowed: Boolean, enabledInDatabase: Boolean, termsOfService: Boolean): SamUserAllowances = - SamUserAllowances(allowed, Seq("database" -> enabledInDatabase, "termsOfService" -> termsOfService)) + def apply(allowed: Boolean, enabled: Boolean, termsOfService: Boolean): SamUserAllowances = + SamUserAllowances(allowed, Map("enabled" -> enabled, "termsOfService" -> termsOfService)) } final case class SamUserAllowances( allowed: Boolean, - details: Seq[(String, Boolean)] -) + details: Map[String, Boolean] +) { + + def getEnabled: Boolean = details.get("enabled").exists(identity) + def getTermsOfServiceCompliance: Boolean = details.get("termsOfService").exists(identity) + +} diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/UserService.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/UserService.scala index 6b8a87c6c..f00a4442e 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/UserService.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/UserService.scala @@ -433,7 +433,7 @@ class UserService(val directoryDAO: DirectoryDAO, val cloudExtensions: CloudExte tosStatus <- tosService.getTosComplianceStatus(samUser, samRequestContext) } yield SamUserAllowances( allowed = samUser.enabled && tosStatus.permitsSystemUsage, - enabledInDatabase = samUser.enabled, + enabled = samUser.enabled, termsOfService = tosStatus.permitsSystemUsage ) } diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamRoutesBuilder.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamRoutesBuilder.scala index 5de9001d3..04901a65a 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamRoutesBuilder.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamRoutesBuilder.scala @@ -30,6 +30,7 @@ class MockSamRoutesBuilder(allUsersGroup: WorkbenchGroup)(implicit system: Actor private var disabledUser: Option[SamUser] = None private var adminUser: Option[SamUser] = None private var asServiceAdminUser = false + private var callingUser: Option[SamUser] = None // TODO: *sniff sniff* I can't help but notice we're coordinating state between the userService and the // cloudExtensions. Same for other methods too. @@ -63,18 +64,21 @@ class MockSamRoutesBuilder(allUsersGroup: WorkbenchGroup)(implicit system: Actor this } - def callAsAdminUser(): MockSamRoutesBuilder = { + def callAsAdminUser(samUser: Option[SamUser] = None): MockSamRoutesBuilder = { cloudExtensionsBuilder.withAdminUser() + callingUser = samUser this } - def callAsAdminServiceUser(): MockSamRoutesBuilder = { + def callAsAdminServiceUser(samUser: Option[SamUser] = None): MockSamRoutesBuilder = { asServiceAdminUser = true + callingUser = samUser this } - def callAsNonAdminUser(): MockSamRoutesBuilder = { + def callAsNonAdminUser(samUser: Option[SamUser] = None): MockSamRoutesBuilder = { cloudExtensionsBuilder.withNonAdminUser() + callingUser = samUser this } @@ -86,7 +90,8 @@ class MockSamRoutesBuilder(allUsersGroup: WorkbenchGroup)(implicit system: Actor // Can only have 1 active user when making a request. If the adminUser is set, that takes precedence, otherwise try // to get the enabledUser. private def getActiveUser: SamUser = - enabledUser + callingUser + .orElse(enabledUser) .orElse(disabledUser) .getOrElse(throw new Exception("Try building MockSamRoutes .withAdminUser(), .withEnabledUser(), withDisabledUser() first")) @@ -119,7 +124,7 @@ class MockSamRoutesBuilder(allUsersGroup: WorkbenchGroup)(implicit system: Actor } override def withUserAllowInactive(samRequestContext: SamRequestContext): Directive1[SamUser] = onSuccess { - Future.successful(disabledUser.getOrElse(throw new Exception("Try building MockSamRoutes .withDisabledUser() first"))) + Future.successful(getActiveUser) } // We should really not be testing this, the routes should work identically whether the user diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamUserDirectives.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamUserDirectives.scala index 9eaa341ea..3b738b870 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamUserDirectives.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/MockSamUserDirectives.scala @@ -18,7 +18,7 @@ trait MockSamUserDirectives extends SamUserDirectives { OIDCHeaders(OAuth2BearerToken("dummy token"), user.googleSubjectId.toLeft(user.azureB2CId.get), user.email, user.googleSubjectId) override def withActiveUser(samRequestContext: SamRequestContext): Directive1[SamUser] = onSuccess { - StandardSamUserDirectives.getActiveSamUser(fakeOidcHeaders, userService, tosService, samRequestContext).unsafeToFuture() + StandardSamUserDirectives.getActiveSamUser(fakeOidcHeaders, userService, samRequestContext).unsafeToFuture() } override def withUserAllowInactive(samRequestContext: SamRequestContext): Directive1[SamUser] = onSuccess { diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/StandardSamUserDirectivesSpec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/StandardSamUserDirectivesSpec.scala index 50f535193..170c64703 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/StandardSamUserDirectivesSpec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/StandardSamUserDirectivesSpec.scala @@ -35,8 +35,8 @@ class StandardSamUserDirectivesSpec extends AnyFlatSpec with PropertyBasedTestin override implicit val executionContext: ExecutionContext = null override val cloudExtensions: CloudExtensions = null override val termsOfServiceConfig: TermsOfServiceConfig = null - override val userService: UserService = new MockUserService(directoryDAO = dirDAO) override val tosService: TosService = new TosService(dirDAO, tosConfig) + override val userService: UserService = new MockUserService(directoryDAO = dirDAO, tosService = tosService) override val adminConfig: AppConfig.AdminConfig = testAdminConfig } diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2Spec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2Spec.scala index 3382d91d2..9380f39a8 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2Spec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2Spec.scala @@ -17,6 +17,7 @@ import org.scalatest.matchers.should.Matchers class UserRoutesV2Spec extends AnyFlatSpec with Matchers with ScalatestRouteTest with MockitoSugar with TestSupport { val defaultUser: SamUser = Generator.genWorkbenchUserGoogle.sample.get val otherUser: SamUser = Generator.genWorkbenchUserGoogle.sample.get + val thirdUser: SamUser = Generator.genWorkbenchUserGoogle.sample.get val adminGroupEmail: WorkbenchEmail = Generator.genFirecloudEmail.sample.get val allUsersGroup: BasicWorkbenchGroup = BasicWorkbenchGroup(CloudExtensions.allUsersGroupName, Set(), WorkbenchEmail("all_users@fake.com")) @@ -99,7 +100,7 @@ class UserRoutesV2Spec extends AnyFlatSpec with Matchers with ScalatestRouteTest // Act and Assert Get(s"/api/users/v2/self/allowed") ~> samRoutes.route ~> check { status shouldEqual StatusCodes.OK - responseAs[SamUserAllowances] should be(SamUserAllowances(allowed = true, enabledInDatabase = true, termsOfService = true)) + responseAs[SamUserAllowances] should be(SamUserAllowances(allowed = true, enabled = true, termsOfService = true)) } } @@ -114,7 +115,7 @@ class UserRoutesV2Spec extends AnyFlatSpec with Matchers with ScalatestRouteTest // Act and Assert Get(s"/api/users/v2/${defaultUser.id}/allowed") ~> samRoutes.route ~> check { status shouldEqual StatusCodes.OK - responseAs[SamUserAllowances] should be(SamUserAllowances(allowed = true, enabledInDatabase = true, termsOfService = true)) + responseAs[SamUserAllowances] should be(SamUserAllowances(allowed = true, enabled = true, termsOfService = true)) } } @@ -123,7 +124,7 @@ class UserRoutesV2Spec extends AnyFlatSpec with Matchers with ScalatestRouteTest val samRoutes = new MockSamRoutesBuilder(allUsersGroup) .withEnabledUsers(Seq(defaultUser, otherUser)) .withAllowedUsers(Seq(defaultUser, otherUser)) - .callAsNonAdminUser() + .callAsNonAdminUser(Some(defaultUser)) .build // Act and Assert @@ -137,20 +138,20 @@ class UserRoutesV2Spec extends AnyFlatSpec with Matchers with ScalatestRouteTest it should "succeed if an admin user is getting another user" in { // Arrange val samRoutes = new MockSamRoutesBuilder(allUsersGroup) - .withEnabledUsers(Seq(defaultUser, otherUser)) - .withAllowedUser(defaultUser) - .callAsAdminUser() + .withEnabledUsers(Seq(defaultUser, otherUser, thirdUser)) + .withAllowedUser(otherUser) + .callAsAdminUser(Some(defaultUser)) .build // Act and Assert - Get(s"/api/users/v2/${defaultUser.id}/allowed") ~> samRoutes.route ~> check { + Get(s"/api/users/v2/${otherUser.id}/allowed") ~> samRoutes.route ~> check { status shouldEqual StatusCodes.OK - responseAs[SamUserAllowances] should be(SamUserAllowances(allowed = true, enabledInDatabase = true, termsOfService = true)) + responseAs[SamUserAllowances] should be(SamUserAllowances(allowed = true, enabled = true, termsOfService = true)) } - Get(s"/api/users/v2/${otherUser.id}/allowed") ~> samRoutes.route ~> check { + Get(s"/api/users/v2/${thirdUser.id}/allowed") ~> samRoutes.route ~> check { status shouldEqual StatusCodes.OK - responseAs[SamUserAllowances] should be(SamUserAllowances(allowed = false, enabledInDatabase = false, termsOfService = false)) + responseAs[SamUserAllowances] should be(SamUserAllowances(allowed = false, enabled = false, termsOfService = false)) } } } diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockUserServiceBuilder.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockUserServiceBuilder.scala index 2717ddbc8..45294e5b6 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockUserServiceBuilder.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockUserServiceBuilder.scala @@ -72,7 +72,7 @@ case class MockUserServiceBuilder() extends IdiomaticMockito { } mockUserService.getUserAllowances(any[SamUser], any[SamRequestContext]) returns IO( - SamUserAllowances(allowed = false, enabledInDatabase = false, termsOfService = false) + SamUserAllowances(allowed = false, enabled = false, termsOfService = false) ) } @@ -165,7 +165,7 @@ case class MockUserServiceBuilder() extends IdiomaticMockito { private def makeUserAppearAllowed(samUser: SamUser, mockUserService: UserService): Unit = mockUserService.getUserAllowances(eqTo(samUser), any[SamRequestContext]) returns IO( - SamUserAllowances(allowed = true, enabledInDatabase = true, termsOfService = true) + SamUserAllowances(allowed = true, enabled = true, termsOfService = true) ) private def handleMalformedEmail(mockUserService: UserService): Unit = diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/AllowedUserSpec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/AllowedUserSpec.scala index ddcbbe8f0..b6cf56218 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/AllowedUserSpec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/AllowedUserSpec.scala @@ -28,7 +28,7 @@ class AllowedUserSpec extends UserServiceTestTraits { val response = runAndWait(userService.getUserAllowances(userWithBothIds, samRequestContext)) // Assert - response should be(SamUserAllowances(allowed = true, enabledInDatabase = true, termsOfService = true)) + response should be(SamUserAllowances(allowed = true, enabled = true, termsOfService = true)) } } describe("who has not accepted the Terms of Service") { @@ -41,7 +41,7 @@ class AllowedUserSpec extends UserServiceTestTraits { val response = runAndWait(userService.getUserAllowances(userWithBothIds, samRequestContext)) // Assert - response should be(SamUserAllowances(allowed = false, enabledInDatabase = true, termsOfService = false)) + response should be(SamUserAllowances(allowed = false, enabled = true, termsOfService = false)) } } } @@ -56,7 +56,7 @@ class AllowedUserSpec extends UserServiceTestTraits { val response = runAndWait(userService.getUserAllowances(userWithBothIds, samRequestContext)) // Assert - response should be(SamUserAllowances(allowed = false, enabledInDatabase = false, termsOfService = false)) + response should be(SamUserAllowances(allowed = false, enabled = false, termsOfService = false)) } it("should not be able to use the system even if the Terms of Service permits them to") { // Arrange @@ -67,7 +67,7 @@ class AllowedUserSpec extends UserServiceTestTraits { val response = runAndWait(userService.getUserAllowances(userWithBothIds, samRequestContext)) // Assert - response should be(SamUserAllowances(allowed = false, enabledInDatabase = false, termsOfService = true)) + response should be(SamUserAllowances(allowed = false, enabled = false, termsOfService = true)) } }