diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9be8d56..464a1ec 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -49,6 +49,9 @@ jobs: # verbose: true - name: Run tests run: STRIPE_CLIENT_ID=${{secrets.STRIPE_CLIENT_ID}} STRIPE_API_KEY=${{secrets.STRIPE_API_KEY}} sbt clean test + env: + STRIPE_CLIENT_ID: ${{secrets.STRIPE_CLIENT_ID}} + STRIPE_API_KEY: ${{secrets.STRIPE_API_KEY}} # Optional: This step uploads information to the GitHub dependency graph and unblocking Dependabot alerts for the repository # - name: Upload dependency graph # uses: scalacenter/sbt-dependency-submission@ab086b50c947c9774b70f39fc7f6e20ca2706c91 diff --git a/api/build.sbt b/api/build.sbt index 3b157b4..9875977 100644 --- a/api/build.sbt +++ b/api/build.sbt @@ -27,5 +27,5 @@ organization := "app.softnetwork.payment" name := "softpay-api" libraryDependencies ++= Seq( - "app.softnetwork.notification" %% "notification-api" % Versions.notification + "app.softnetwork.scheduler" %% "scheduler-api" % Versions.scheduler ) diff --git a/build.sbt b/build.sbt index 6fe9639..00e3dfc 100644 --- a/build.sbt +++ b/build.sbt @@ -12,10 +12,17 @@ ThisBuild / javacOptions ++= Seq("-source", "1.8", "-target", "1.8", "-Xlint") ThisBuild / resolvers ++= Seq( "Softnetwork Server" at "https://softnetwork.jfrog.io/artifactory/releases/", + "Softnetwork snapshots" at "https://softnetwork.jfrog.io/artifactory/snapshots/", "Maven Central Server" at "https://repo1.maven.org/maven2", "Typesafe Server" at "https://repo.typesafe.com/typesafe/releases" ) +ThisBuild / libraryDependencySchemes ++= Seq( + "app.softnetwork.notification" %% "notification-common" % VersionScheme.Always, + "app.softnetwork.notification" %% "notification-core" % VersionScheme.Always, + "app.softnetwork.notification" %% "notification-testkit" % VersionScheme.Always +) + ThisBuild / versionScheme := Some("early-semver") val scalatest = Seq( diff --git a/core/build.sbt b/core/build.sbt index 8877f62..950e776 100644 --- a/core/build.sbt +++ b/core/build.sbt @@ -8,6 +8,9 @@ Compile / PB.protoSources := Seq(sourceDirectory.value / ".." / ".." / "client/s libraryDependencies ++= Seq( "app.softnetwork.persistence" %% "persistence-kv" % Versions.genericPersistence, - "app.softnetwork.account" %% "account-core" % Versions.account, + "app.softnetwork.account" %% "account-core" % Versions.account excludeAll( + ExclusionRule(organization = "app.softnetwork.notification") + ), + "app.softnetwork.notification" %% "notification-common" % Versions.notification, "app.softnetwork.session" %% "session-core" % Versions.genericPersistence ) diff --git a/core/src/main/scala/app/softnetwork/payment/persistence/typed/SoftPayAccountBehavior.scala b/core/src/main/scala/app/softnetwork/payment/persistence/typed/SoftPayAccountBehavior.scala index 07c9433..140ec35 100644 --- a/core/src/main/scala/app/softnetwork/payment/persistence/typed/SoftPayAccountBehavior.scala +++ b/core/src/main/scala/app/softnetwork/payment/persistence/typed/SoftPayAccountBehavior.scala @@ -288,9 +288,13 @@ trait SoftPayAccountBehavior extends AccountBehavior[SoftPayAccount, BasicAccoun } case _ => - Effect.none.thenRun { _ => - AccountMessages.ClientNotFound ~> replyTo - } + super.handleCommand( + entityId, + state, + RefreshAccessToken(refreshToken), + replyTo, + timers + ) } case Some(account) if !account.status.isActive => diff --git a/core/src/main/scala/app/softnetwork/payment/service/SoftPayAccountServiceEndpoints.scala b/core/src/main/scala/app/softnetwork/payment/service/SoftPayAccountServiceEndpoints.scala index 17feef1..e3b5455 100644 --- a/core/src/main/scala/app/softnetwork/payment/service/SoftPayAccountServiceEndpoints.scala +++ b/core/src/main/scala/app/softnetwork/payment/service/SoftPayAccountServiceEndpoints.scala @@ -26,7 +26,6 @@ trait SoftPayAccountServiceEndpoints[SD <: SessionData with SessionDataDecorator : List[ServerEndpoint[AkkaStreams with capabilities.WebSockets, Future]] = List( signUp, - basic, login, signIn, activate, diff --git a/core/src/main/scala/app/softnetwork/payment/service/SoftPayOAuthService.scala b/core/src/main/scala/app/softnetwork/payment/service/SoftPayOAuthService.scala index 75bbb42..599a919 100644 --- a/core/src/main/scala/app/softnetwork/payment/service/SoftPayOAuthService.scala +++ b/core/src/main/scala/app/softnetwork/payment/service/SoftPayOAuthService.scala @@ -8,6 +8,7 @@ import app.softnetwork.account.message.{ AccessTokenGenerated, AccessTokenRefreshed, AccountErrorMessage, + GenerateAccessToken, Tokens } import app.softnetwork.account.service.OAuthService @@ -32,7 +33,7 @@ trait SoftPayOAuthService[SD <: SessionData with SessionDataDecorator[SD]] override val route: Route = { pathPrefix(AccountSettings.OAuthPath) { - concat(token ~ me :: (signin ++ backup).toList: _*) + concat(token ~ client :: (signin ++ callback).toList: _*) } } @@ -40,65 +41,81 @@ trait SoftPayOAuthService[SD <: SessionData with SessionDataDecorator[SD]] path("token") { post { formField("grant_type") { - case "client_credentials" => - formField("credentials") { credentials => - val httpCredentials = BasicHttpCredentials(credentials) - val clientId = httpCredentials.username - val clientSecret = httpCredentials.password - run(clientId, GenerateClientToken(clientId, clientSecret)) completeWith { - case r: AccessTokenGenerated => - complete( - StatusCodes.OK, - Tokens( - r.accessToken.token, - r.accessToken.tokenType.toLowerCase(), - r.accessToken.expiresIn, - r.accessToken.refreshToken, - r.accessToken.refreshExpiresIn - ) - ) - case error: AccountErrorMessage => - complete( - StatusCodes.BadRequest, - Map( - "error" -> "access_denied", - "error_description" -> error.message - ) - ) - case _ => complete(StatusCodes.BadRequest) - } - } - case "refresh_token" => - formField("refresh_token") { refreshToken => - run(refreshToken, RefreshClientToken(refreshToken)) completeWith { - case r: AccessTokenRefreshed => - complete( - StatusCodes.OK, - Tokens( - r.accessToken.token, - r.accessToken.tokenType.toLowerCase(), - r.accessToken.expiresIn, - r.accessToken.refreshToken, - r.accessToken.refreshExpiresIn - ) - ) - case error: AccountErrorMessage => - complete( - StatusCodes.BadRequest, - Map( - "error" -> "access_denied", - "error_description" -> error.message - ) - ) - case _ => complete(StatusCodes.BadRequest) - } - } - case _ => complete(StatusCodes.BadRequest) + handlGrantType } } } - override lazy val me: Route = path("me") { + protected def handlGrantType(grantType: String): Route = { + grantType match { + case "client_credentials" => + handleClientCredentialsGrantType + case "refresh_token" => + handleRefreshTokenGrantType + case _ => complete(StatusCodes.BadRequest) + } + } + + private def handleRefreshTokenGrantType: Route = { + formField("refresh_token") { refreshToken => + run(refreshToken, RefreshClientToken(refreshToken)) completeWith { + case r: AccessTokenRefreshed => + complete( + StatusCodes.OK, + Tokens( + r.accessToken.token, + r.accessToken.tokenType.toLowerCase(), + r.accessToken.expiresIn, + r.accessToken.refreshToken, + r.accessToken.refreshExpiresIn + ) + ) + case error: AccountErrorMessage => + complete( + StatusCodes.BadRequest, + Map( + "error" -> "access_denied", + "error_description" -> error.message + ) + ) + case _ => complete(StatusCodes.BadRequest) + } + } + } + + private def handleClientCredentialsGrantType: Route = { + formField("credentials") { credentials => + val httpCredentials = BasicHttpCredentials(credentials) + val clientId = httpCredentials.username + val clientSecret = httpCredentials.password + run(clientId, GenerateClientToken(clientId, clientSecret)) completeWith { + case r: AccessTokenGenerated => + complete( + StatusCodes.OK, + Tokens( + r.accessToken.token, + r.accessToken.tokenType.toLowerCase(), + r.accessToken.expiresIn, + r.accessToken.refreshToken, + r.accessToken.refreshExpiresIn + ) + ) + case error: AccountErrorMessage => + complete( + StatusCodes.BadRequest, + Map( + "error" -> "access_denied", + "error_description" -> error.message + ) + ) + case _ => complete(StatusCodes.BadRequest) + } + } + } + + val pmClient: String = "me" + + lazy val client: Route = path(pmClient) { get { handleRejections( RejectionHandler diff --git a/core/src/main/scala/app/softnetwork/payment/service/SoftPayOAuthServiceEndpoints.scala b/core/src/main/scala/app/softnetwork/payment/service/SoftPayOAuthServiceEndpoints.scala index 252613a..c4764cb 100644 --- a/core/src/main/scala/app/softnetwork/payment/service/SoftPayOAuthServiceEndpoints.scala +++ b/core/src/main/scala/app/softnetwork/payment/service/SoftPayOAuthServiceEndpoints.scala @@ -7,6 +7,7 @@ import app.softnetwork.account.message.{ AccessTokenRefreshed, AccountErrorMessage, BearerAuthenticationFailed, + GenerateAccessToken, Tokens } import app.softnetwork.account.service.OAuthServiceEndpoints @@ -49,8 +50,8 @@ trait SoftPayOAuthServiceEndpoints[SD <: SessionData with SessionDataDecorator[S : List[ServerEndpoint[AkkaStreams with capabilities.WebSockets, Future]] = List( token, - me - ) ++ services.map(signin) ++ services.map(backup) + client + ) ++ services.map(signin) ++ services.map(callback) override val token: ServerEndpoint[Any with AkkaStreams, Future] = endpoint.post @@ -78,54 +79,74 @@ trait SoftPayOAuthServiceEndpoints[SD <: SessionData with SessionDataDecorator[S ) ) .out(jsonBody[Tokens]) - .serverLogic { - case tokenRequest: ClientCredentials => - import tokenRequest._ - val httpCredentials = BasicHttpCredentials(credentials) - val clientId = httpCredentials.username - val clientSecret = httpCredentials.password - run(clientId, GenerateClientToken(clientId, clientSecret)) map { - case r: AccessTokenGenerated => - Right( - Tokens( - r.accessToken.token, - r.accessToken.tokenType.toLowerCase(), - r.accessToken.expiresIn, - r.accessToken.refreshToken, - r.accessToken.refreshExpiresIn - ) - ) - case error: AccountErrorMessage => - Left(ApiErrors.BadRequest(error.message)) - case _ => Left(ApiErrors.BadRequest("Unknown")) - } - case tokenRequest: RefreshToken => - import tokenRequest._ - run(refreshToken, RefreshClientToken(refreshToken)) map { - case r: AccessTokenRefreshed => - Right( - Tokens( - r.accessToken.token, - r.accessToken.tokenType.toLowerCase(), - r.accessToken.expiresIn, - r.accessToken.refreshToken, - r.accessToken.refreshExpiresIn - ) - ) - case error: AccountErrorMessage => - Left(ApiErrors.BadRequest(error.message)) - case _ => Left(ApiErrors.BadRequest("Unknown")) - } - case tokenRequest: UnsupportedGrantType => - Future.successful( - Left(ApiErrors.BadRequest(s"Unknown grant_type ${tokenRequest.grantType}")) - ) + .serverLogic { case tokenRequest: ClientTokenRequest => + handleGrantType(tokenRequest) } - override val me: ServerEndpoint[Any with AkkaStreams, Future] = + protected def handleGrantType( + tokenRequest: ClientTokenRequest + ): Future[Either[ApiErrors.BadRequest, Tokens]] = { + tokenRequest match { + case tokenRequest: ClientCredentials => + handleClientCredentialsGrantType(tokenRequest) + case tokenRequest: RefreshToken => + handleRefreshTokenGrantType(tokenRequest) + case tokenRequest: UnsupportedGrantType => + Future.successful( + Left(ApiErrors.BadRequest(s"Unknown grant_type ${tokenRequest.grantType}")) + ) + } + } + + private def handleRefreshTokenGrantType( + tokenRequest: RefreshToken + ): Future[Either[ApiErrors.BadRequest, Tokens]] = { + run(tokenRequest.refreshToken, RefreshClientToken(tokenRequest.refreshToken)) map { + case r: AccessTokenRefreshed => + Right( + Tokens( + r.accessToken.token, + r.accessToken.tokenType.toLowerCase(), + r.accessToken.expiresIn, + r.accessToken.refreshToken, + r.accessToken.refreshExpiresIn + ) + ) + case error: AccountErrorMessage => + Left(ApiErrors.BadRequest(error.message)) + case _ => Left(ApiErrors.BadRequest("Unknown")) + } + } + + private def handleClientCredentialsGrantType( + tokenRequest: ClientCredentials + ): Future[Either[ApiErrors.BadRequest, Tokens]] = { + val httpCredentials = BasicHttpCredentials(tokenRequest.credentials) + val clientId = httpCredentials.username + val clientSecret = httpCredentials.password + run(clientId, GenerateClientToken(clientId, clientSecret)) map { + case r: AccessTokenGenerated => + Right( + Tokens( + r.accessToken.token, + r.accessToken.tokenType.toLowerCase(), + r.accessToken.expiresIn, + r.accessToken.refreshToken, + r.accessToken.refreshExpiresIn + ) + ) + case error: AccountErrorMessage => + Left(ApiErrors.BadRequest(error.message)) + case _ => Left(ApiErrors.BadRequest("Unknown")) + } + } + + val pmClient: String = "me" + + lazy val client: ServerEndpoint[Any with AkkaStreams, Future] = endpoint.get - .in(AccountSettings.OAuthPath / "me") - .description("OAuth2 me endpoint") + .in(AccountSettings.OAuthPath / pmClient) + .description("OAuth2 client endpoint") .securityIn(auth.bearer[String](WWWAuthenticateChallenge.bearer(AccountSettings.Realm))) .errorOut(ApiErrors.oneOfApiErrors) .out(setCookieOpt(clientCookieName)) @@ -162,6 +183,21 @@ sealed trait ClientTokenRequest { def asMap(): Map[String, String] } +case class AuthorizationCodeRequest( + grant_type: String, + code: String, + redirect_uri: Option[String], + client_id: String +) extends ClientTokenRequest { + override def asMap(): Map[String, String] = + Map( + "grant_type" -> grant_type, + "code" -> code, + "redirect_uri" -> redirect_uri.getOrElse(""), + "client_id" -> client_id + ) +} + case class ClientCredentials(credentials: String, scope: Option[String] = None) extends ClientTokenRequest { override def asMap(): Map[String, String] = @@ -190,6 +226,13 @@ case class UnsupportedGrantType(grantType: String) extends ClientTokenRequest { object ClientTokenRequest { def decode(form: Map[String, String]): ClientTokenRequest = { form.getOrElse("grant_type", "") match { + case "authorization_code" => + AuthorizationCodeRequest( + "authorization_code", + form.getOrElse("code", ""), + form.get("redirect_uri"), + form.getOrElse("client_id", "") + ) case "client_credentials" => ClientCredentials( form("credentials"), diff --git a/project/Versions.scala b/project/Versions.scala index 1f2d54a..dbd7018 100644 --- a/project/Versions.scala +++ b/project/Versions.scala @@ -4,9 +4,9 @@ object Versions { val scheduler = "0.6.3" - val notification = "0.6.3" + val notification = "0.8.0-SNAPSHOT" - val account = "0.6.2.1" + val account = "0.6.4-SNAPSHOT" val scalatest = "3.2.16" @@ -16,5 +16,5 @@ object Versions { val scalate = "1.9.8" - val selenium = "4.13.0" + val selenium = "4.23.0" } diff --git a/project/plugins.sbt b/project/plugins.sbt index 783e6a5..173b732 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -4,7 +4,8 @@ libraryDependencySchemes += "org.scala-lang.modules" %% "scala-xml" % VersionSch resolvers ++= Seq( "Typesafe repository" at "https://repo.typesafe.com/typesafe/releases/", - "Softnetwork releases" at "https://softnetwork.jfrog.io/artifactory/releases/" + "Softnetwork releases" at "https://softnetwork.jfrog.io/artifactory/releases/", + "Softnetwork snapshots" at "https://softnetwork.jfrog.io/artifactory/snapshots/" ) addSbtPlugin("app.softnetwork.sbt-softnetwork" % "sbt-softnetwork-git" % "0.1.7") @@ -19,6 +20,6 @@ addSbtPlugin("com.tapad" % "sbt-docker-compose" % "1.0.34") addDependencyTreePlugin -//addSbtPlugin("com.typesafe.sbt" % "sbt-multi-jvm" % "0.4.0") +addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.9.2") addSbtPlugin("org.scoverage" % "sbt-scoverage" % "2.0.8") diff --git a/testkit/build.sbt b/testkit/build.sbt index 07ce05e..572e007 100644 --- a/testkit/build.sbt +++ b/testkit/build.sbt @@ -9,8 +9,9 @@ libraryDependencies ++= Seq( "app.softnetwork.api" %% "generic-server-api-testkit" % Versions.genericPersistence, "app.softnetwork.session" %% "session-testkit" % Versions.genericPersistence, "app.softnetwork.persistence" %% "persistence-core-testkit" % Versions.genericPersistence, - "app.softnetwork.account" %% "account-testkit" % Versions.account, + "app.softnetwork.account" %% "account-testkit" % Versions.account excludeAll(ExclusionRule(organization = "app.softnetwork.notification")), + "app.softnetwork.notification" %% "notification-testkit" % Versions.notification, "org.scalatest" %% "scalatest" % Versions.scalatest, "org.seleniumhq.selenium" % "selenium-java" % Versions.selenium, - "org.seleniumhq.selenium" % "htmlunit-driver" % Versions.selenium + "org.seleniumhq.selenium" % "htmlunit3-driver" % Versions.selenium ) diff --git a/testkit/src/main/scala/app/softnetwork/payment/data/package.scala b/testkit/src/main/scala/app/softnetwork/payment/data/package.scala index fb98f89..2c8b92a 100644 --- a/testkit/src/main/scala/app/softnetwork/payment/data/package.scala +++ b/testkit/src/main/scala/app/softnetwork/payment/data/package.scala @@ -56,6 +56,8 @@ package object data { .withEmail(email) .withPhone(phone) .withBusiness(business) + .withNationality("FR") + .withCountryOfResidence("FR") /** bank account */ var sellerBankAccountId: String = _ diff --git a/testkit/src/test/scala/app/softnetwork/payment/service/PaymentServiceSpec.scala b/testkit/src/main/scala/app/softnetwork/payment/scalatest/PaymentRouteSpec.scala similarity index 99% rename from testkit/src/test/scala/app/softnetwork/payment/service/PaymentServiceSpec.scala rename to testkit/src/main/scala/app/softnetwork/payment/scalatest/PaymentRouteSpec.scala index 01bd254..177e37e 100644 --- a/testkit/src/test/scala/app/softnetwork/payment/service/PaymentServiceSpec.scala +++ b/testkit/src/main/scala/app/softnetwork/payment/scalatest/PaymentRouteSpec.scala @@ -1,20 +1,19 @@ -package app.softnetwork.payment.service +package app.softnetwork.payment.scalatest -import akka.http.scaladsl.model.{RemoteAddress, StatusCodes} import akka.http.scaladsl.model.headers.{`User-Agent`, `X-Forwarded-For`} +import akka.http.scaladsl.model.{RemoteAddress, StatusCodes} import app.softnetwork.api.server.ApiRoutes import app.softnetwork.api.server.config.ServerSettings.RootPath -import app.softnetwork.payment.data._ import app.softnetwork.payment.config.PaymentSettings import app.softnetwork.payment.config.PaymentSettings.PaymentConfig._ +import app.softnetwork.payment.data._ import app.softnetwork.payment.message.PaymentMessages._ import app.softnetwork.payment.model.SoftPayAccount.Client.Provider import app.softnetwork.payment.model._ -import app.softnetwork.payment.scalatest.PaymentRouteTestKit -import app.softnetwork.time._ import app.softnetwork.persistence.now import app.softnetwork.session.model.{SessionData, SessionDataDecorator} import app.softnetwork.session.service.SessionMaterials +import app.softnetwork.time._ import org.scalatest.wordspec.AnyWordSpecLike import org.slf4j.{Logger, LoggerFactory} @@ -23,7 +22,7 @@ import java.time.LocalDate import scala.language.implicitConversions import scala.util.{Failure, Success} -trait PaymentServiceSpec[SD <: SessionData with SessionDataDecorator[SD]] +trait PaymentRouteSpec[SD <: SessionData with SessionDataDecorator[SD]] extends AnyWordSpecLike with PaymentRouteTestKit[SD] { _: ApiRoutes with SessionMaterials[SD] => diff --git a/testkit/src/main/scala/app/softnetwork/payment/scalatest/SoftPayAccountRouteSpec.scala b/testkit/src/main/scala/app/softnetwork/payment/scalatest/SoftPayAccountRouteSpec.scala new file mode 100644 index 0000000..dd01e91 --- /dev/null +++ b/testkit/src/main/scala/app/softnetwork/payment/scalatest/SoftPayAccountRouteSpec.scala @@ -0,0 +1,43 @@ +package app.softnetwork.payment.scalatest + +import app.softnetwork.account.message.{BasicAccountSignUp, SignUp} +import app.softnetwork.account.model._ +import app.softnetwork.account.scalatest.AccountRouteSpec +import app.softnetwork.api.server.ApiRoutes +import app.softnetwork.payment.message.AccountMessages.SoftPaySignUp +import app.softnetwork.payment.model.SoftPayAccount +import app.softnetwork.persistence.ManifestWrapper +import app.softnetwork.session.model.{SessionData, SessionDataDecorator} +import app.softnetwork.session.service.SessionMaterials +import org.slf4j.{Logger, LoggerFactory} + +trait SoftPayAccountRouteSpec[SD <: SessionData with SessionDataDecorator[SD]] + extends AccountRouteSpec[ + SoftPayAccount, + BasicAccountProfile, + DefaultProfileView, + DefaultAccountDetailsView, + DefaultAccountView[DefaultProfileView, DefaultAccountDetailsView], + SD + ] + with SoftPayRouteTestKit[SD] + with ManifestWrapper[DefaultAccountView[DefaultProfileView, DefaultAccountDetailsView]] { + _: ApiRoutes with SessionMaterials[SD] => + + override protected val manifestWrapper: ManifestW = ManifestW() + + lazy val log: Logger = LoggerFactory getLogger getClass.getName + + override val profile: BasicAccountProfile = + BasicAccountProfile.defaultInstance + .withName("name") + .withType(ProfileType.CUSTOMER) + .withFirstName(firstName) + .withLastName(lastName) + + override implicit def lppToSignUp: ((String, String, Option[BasicAccountProfile])) => SignUp = { + case (login, password, profile) => + SoftPaySignUp(login, password, provider = provider, profile = profile) + } + +} diff --git a/testkit/src/main/scala/app/softnetwork/payment/scalatest/SoftPayEndpointsTestKit.scala b/testkit/src/main/scala/app/softnetwork/payment/scalatest/SoftPayEndpointsTestKit.scala index 7254635..bbbb09b 100644 --- a/testkit/src/main/scala/app/softnetwork/payment/scalatest/SoftPayEndpointsTestKit.scala +++ b/testkit/src/main/scala/app/softnetwork/payment/scalatest/SoftPayEndpointsTestKit.scala @@ -10,11 +10,18 @@ import app.softnetwork.payment.service.{ MockSoftPayOAuthServiceEndpoints } import app.softnetwork.persistence.schema.SchemaProvider -import app.softnetwork.session.scalatest.SessionTestKit -import app.softnetwork.session.CsrfCheck +import app.softnetwork.session.scalatest.{ + OneOffCookieSessionEndpointsTestKit, + OneOffHeaderSessionEndpointsTestKit, + RefreshableCookieSessionEndpointsTestKit, + RefreshableHeaderSessionEndpointsTestKit, + SessionTestKit +} +import app.softnetwork.session.{CsrfCheck, CsrfCheckHeader} import app.softnetwork.session.model.{SessionData, SessionDataCompanion, SessionDataDecorator} import app.softnetwork.session.service.SessionMaterials import com.softwaremill.session.{RefreshTokenStorage, SessionConfig, SessionManager} +import org.scalatest.Suite import org.slf4j.{Logger, LoggerFactory} import org.softnetwork.session.model.Session @@ -62,3 +69,29 @@ trait SoftPayEndpointsTestKit[SD <: SessionData with SessionDataDecorator[SD]] override implicit def companion: SessionDataCompanion[SD] = self.companion } } + +trait SoftPayEndpointsWithOneOfCookieSessionTestKit[SD <: SessionData with SessionDataDecorator[SD]] + extends SoftPayRouteTestKit[SD] + with OneOffCookieSessionEndpointsTestKit[SD] + with SoftPayEndpointsTestKit[SD] + with CsrfCheckHeader { self: Suite with SessionMaterials[SD] => } + +trait SoftPayEndpointsWithOneOfHeaderSessionTestKit[SD <: SessionData with SessionDataDecorator[SD]] + extends SoftPayRouteTestKit[SD] + with OneOffHeaderSessionEndpointsTestKit[SD] + with SoftPayEndpointsTestKit[SD] + with CsrfCheckHeader { self: Suite with SessionMaterials[SD] => } + +trait SoftPayEndpointsWithRefreshableCookieSessionTestKit[ + SD <: SessionData with SessionDataDecorator[SD] +] extends SoftPayRouteTestKit[SD] + with RefreshableCookieSessionEndpointsTestKit[SD] + with SoftPayEndpointsTestKit[SD] + with CsrfCheckHeader { self: Suite with SessionMaterials[SD] => } + +trait SoftPayEndpointsWithRefreshableHeaderSessionTestKit[ + SD <: SessionData with SessionDataDecorator[SD] +] extends SoftPayRouteTestKit[SD] + with RefreshableHeaderSessionEndpointsTestKit[SD] + with SoftPayEndpointsTestKit[SD] + with CsrfCheckHeader { self: Suite with SessionMaterials[SD] => } diff --git a/testkit/src/main/scala/app/softnetwork/payment/scalatest/SoftPayRoutesTestKit.scala b/testkit/src/main/scala/app/softnetwork/payment/scalatest/SoftPayRoutesTestKit.scala index af03d98..99024f9 100644 --- a/testkit/src/main/scala/app/softnetwork/payment/scalatest/SoftPayRoutesTestKit.scala +++ b/testkit/src/main/scala/app/softnetwork/payment/scalatest/SoftPayRoutesTestKit.scala @@ -11,10 +11,18 @@ import app.softnetwork.payment.handlers.{MockSoftPayAccountDao, SoftPayAccountDa import app.softnetwork.payment.launch.SoftPayRoutes import app.softnetwork.payment.service.{MockSoftPayAccountService, MockSoftPayOAuthService} import app.softnetwork.persistence.schema.SchemaProvider +import app.softnetwork.session.CsrfCheckHeader import app.softnetwork.session.model.{SessionData, SessionDataCompanion, SessionDataDecorator} -import app.softnetwork.session.scalatest.SessionTestKit +import app.softnetwork.session.scalatest.{ + OneOffCookieSessionServiceTestKit, + OneOffHeaderSessionServiceTestKit, + RefreshableCookieSessionServiceTestKit, + RefreshableHeaderSessionServiceTestKit, + SessionTestKit +} import app.softnetwork.session.service.SessionMaterials import com.softwaremill.session.{RefreshTokenStorage, SessionConfig, SessionManager} +import org.scalatest.Suite import org.slf4j.{Logger, LoggerFactory} import org.softnetwork.session.model.Session @@ -64,3 +72,29 @@ trait SoftPayRoutesTestKit[SD <: SessionData with SessionDataDecorator[SD]] } } + +trait SoftPayRoutesWithOneOfCookieSessionTestKit[SD <: SessionData with SessionDataDecorator[SD]] + extends SoftPayRouteTestKit[SD] + with OneOffCookieSessionServiceTestKit[SD] + with SoftPayRoutesTestKit[SD] + with CsrfCheckHeader { self: Suite with SessionMaterials[SD] => } + +trait SoftPayRoutesWithOneOfHeaderSessionTestKit[SD <: SessionData with SessionDataDecorator[SD]] + extends SoftPayRouteTestKit[SD] + with OneOffHeaderSessionServiceTestKit[SD] + with SoftPayRoutesTestKit[SD] + with CsrfCheckHeader { self: Suite with SessionMaterials[SD] => } + +trait SoftPayRoutesWithRefreshableCookieSessionTestKit[SD <: SessionData with SessionDataDecorator[ + SD +]] extends SoftPayRouteTestKit[SD] + with RefreshableCookieSessionServiceTestKit[SD] + with SoftPayRoutesTestKit[SD] + with CsrfCheckHeader { self: Suite with SessionMaterials[SD] => } + +trait SoftPayRoutesWithRefreshableHeaderSessionTestKit[SD <: SessionData with SessionDataDecorator[ + SD +]] extends SoftPayRouteTestKit[SD] + with RefreshableHeaderSessionServiceTestKit[SD] + with SoftPayRoutesTestKit[SD] + with CsrfCheckHeader { self: Suite with SessionMaterials[SD] => } diff --git a/testkit/src/main/scala/app/softnetwork/payment/service/MockSoftPayAccountService.scala b/testkit/src/main/scala/app/softnetwork/payment/service/MockSoftPayAccountService.scala index 08ee16a..668a1c5 100644 --- a/testkit/src/main/scala/app/softnetwork/payment/service/MockSoftPayAccountService.scala +++ b/testkit/src/main/scala/app/softnetwork/payment/service/MockSoftPayAccountService.scala @@ -1,5 +1,7 @@ package app.softnetwork.payment.service +import akka.http.scaladsl.server.Route +import app.softnetwork.account.config.AccountSettings import app.softnetwork.payment.handlers.MockSoftPayAccountTypeKey import app.softnetwork.session.model.{SessionData, SessionDataDecorator} import app.softnetwork.session.service.SessionMaterials @@ -9,4 +11,21 @@ trait MockSoftPayAccountService[SD <: SessionData with SessionDataDecorator[SD]] with MockSoftPayAccountTypeKey { _: SessionMaterials[SD] => + override val route: Route = { + pathPrefix(AccountSettings.Path) { + anonymous ~ // for testing purposes + signUp ~ + principal ~ // for testing purposes + basic ~ // for testing purposes + login ~ + activate ~ + logout ~ + verificationCode ~ + resetPasswordToken ~ + resetPassword ~ + unsubscribe ~ + device ~ + password + } + } } diff --git a/testkit/src/main/scala/app/softnetwork/payment/service/MockSoftPayAccountServiceEndpoints.scala b/testkit/src/main/scala/app/softnetwork/payment/service/MockSoftPayAccountServiceEndpoints.scala index dccb47f..1ea2b80 100644 --- a/testkit/src/main/scala/app/softnetwork/payment/service/MockSoftPayAccountServiceEndpoints.scala +++ b/testkit/src/main/scala/app/softnetwork/payment/service/MockSoftPayAccountServiceEndpoints.scala @@ -3,7 +3,35 @@ package app.softnetwork.payment.service import app.softnetwork.payment.handlers.MockSoftPayAccountTypeKey import app.softnetwork.session.model.{SessionData, SessionDataDecorator} import app.softnetwork.session.service.SessionMaterials +import sttp.capabilities +import sttp.capabilities.akka.AkkaStreams +import sttp.tapir.server.ServerEndpoint + +import scala.concurrent.Future trait MockSoftPayAccountServiceEndpoints[SD <: SessionData with SessionDataDecorator[SD]] extends SoftPayAccountServiceEndpoints[SD] - with MockSoftPayAccountTypeKey { _: SessionMaterials[SD] => } + with MockSoftPayAccountTypeKey { _: SessionMaterials[SD] => + override lazy val endpoints + : List[ServerEndpoint[AkkaStreams with capabilities.WebSockets, Future]] = { + List( + anonymous, // for testing purposes + signUp, + principal, // for testing purposes + basic, // for testing purposes + login, + signIn, + activate, + logout, + signOut, + sendVerificationCode, + sendResetPasswordToken, + checkResetPasswordToken, + resetPassword, + unsubscribe, + registerDevice, + unregisterDevice, + updatePassword + ) + } +} diff --git a/testkit/src/main/scala/app/softnetwork/payment/service/MockSoftPayOAuthService.scala b/testkit/src/main/scala/app/softnetwork/payment/service/MockSoftPayOAuthService.scala index 4e37db4..6879b43 100644 --- a/testkit/src/main/scala/app/softnetwork/payment/service/MockSoftPayOAuthService.scala +++ b/testkit/src/main/scala/app/softnetwork/payment/service/MockSoftPayOAuthService.scala @@ -1,5 +1,9 @@ package app.softnetwork.payment.service +import akka.http.scaladsl.model.StatusCodes +import akka.http.scaladsl.server.Route +import app.softnetwork.account.config.AccountSettings +import app.softnetwork.account.message.{AccessTokenGenerated, AccountErrorMessage, GenerateAccessToken, Tokens} import app.softnetwork.account.spi.OAuth2Service import app.softnetwork.payment.handlers.MockSoftPayAccountTypeKey import app.softnetwork.session.model.{SessionData, SessionDataDecorator} @@ -14,4 +18,53 @@ trait MockSoftPayOAuthService[SD <: SessionData with SessionDataDecorator[SD]] Seq( new DummyApiService() ) + + override val pmClient: String = "client" + + override val route: Route = { + pathPrefix(AccountSettings.OAuthPath) { + concat( + authorize ~ // for testing purposes + token ~ + me ~ // for testing purposes + client :: (signin ++ callback).toList: _* + ) + } + } + + override protected def handlGrantType(grantType: String): Route = { + grantType match { + case "authorization_code" => + handleAuthorizationCodeGrantType // for testing purposes + case _ => super.handlGrantType(grantType) + } + } + + private def handleAuthorizationCodeGrantType: Route = { + formFields("code", "redirect_uri".?, "client_id") { (code, redirectUri, clientId) => + run(code, GenerateAccessToken(clientId, code, redirectUri)) completeWith { + case r: AccessTokenGenerated => + complete( + StatusCodes.OK, + Tokens( + r.accessToken.token, + r.accessToken.tokenType.toLowerCase(), + r.accessToken.expiresIn, + r.accessToken.refreshToken, + r.accessToken.refreshExpiresIn + ) + ) + case error: AccountErrorMessage => + complete( + StatusCodes.BadRequest, + Map( + "error" -> "access_denied", + "error_description" -> error.message + ) + ) + case _ => complete(StatusCodes.BadRequest) + } + } + } + } diff --git a/testkit/src/main/scala/app/softnetwork/payment/service/MockSoftPayOAuthServiceEndpoints.scala b/testkit/src/main/scala/app/softnetwork/payment/service/MockSoftPayOAuthServiceEndpoints.scala index 9db8e00..7dd45b2 100644 --- a/testkit/src/main/scala/app/softnetwork/payment/service/MockSoftPayOAuthServiceEndpoints.scala +++ b/testkit/src/main/scala/app/softnetwork/payment/service/MockSoftPayOAuthServiceEndpoints.scala @@ -1,10 +1,22 @@ package app.softnetwork.payment.service +import app.softnetwork.account.message.{ + AccessTokenGenerated, + AccountErrorMessage, + GenerateAccessToken, + Tokens +} import app.softnetwork.account.spi.OAuth2Service +import app.softnetwork.api.server.ApiErrors import app.softnetwork.payment.handlers.MockSoftPayAccountTypeKey import app.softnetwork.session.model.{SessionData, SessionDataDecorator} import app.softnetwork.session.service.SessionMaterials import com.github.scribejava.core.oauth.DummyApiService +import sttp.capabilities +import sttp.capabilities.akka.AkkaStreams +import sttp.tapir.server.ServerEndpoint + +import scala.concurrent.Future trait MockSoftPayOAuthServiceEndpoints[SD <: SessionData with SessionDataDecorator[SD]] extends SoftPayOAuthServiceEndpoints[SD] @@ -14,4 +26,48 @@ trait MockSoftPayOAuthServiceEndpoints[SD <: SessionData with SessionDataDecorat Seq( new DummyApiService() ) + + override val pmClient: String = "client" + + override lazy val endpoints + : List[ServerEndpoint[AkkaStreams with capabilities.WebSockets, Future]] = + List( + authorize, // for testing purposes + token, + me, // for testing purposes + client + ) ++ services.map(signin) ++ services.map(callback) + + override protected def handleGrantType( + tokenRequest: ClientTokenRequest + ): Future[Either[ApiErrors.BadRequest, Tokens]] = { + tokenRequest match { + case tokenRequest: AuthorizationCodeRequest => + handleAuthorizationCodeGrantType(tokenRequest) // for testing purposes + case other => + super.handleGrantType(other) + } + } + + private def handleAuthorizationCodeGrantType( + tokenRequest: AuthorizationCodeRequest + ): Future[Either[ApiErrors.BadRequest, Tokens]] = { + import tokenRequest._ + run(code, GenerateAccessToken(client_id, code, redirect_uri)) map { + case r: AccessTokenGenerated => + Right( + Tokens( + r.accessToken.token, + r.accessToken.tokenType.toLowerCase(), + r.accessToken.expiresIn, + r.accessToken.refreshToken, + r.accessToken.refreshExpiresIn + ) + ) + case error: AccountErrorMessage => + Left(ApiErrors.BadRequest(error.message)) + case _ => Left(ApiErrors.BadRequest("Unknown")) + } + } + } diff --git a/testkit/src/test/scala/app/softnetwork/payment/service/PaymentEndpointsWithOneOffCookieSessionSpec.scala b/testkit/src/test/scala/app/softnetwork/payment/service/PaymentEndpointsWithOneOffCookieSessionSpec.scala index 7bca170..73720b0 100644 --- a/testkit/src/test/scala/app/softnetwork/payment/service/PaymentEndpointsWithOneOffCookieSessionSpec.scala +++ b/testkit/src/test/scala/app/softnetwork/payment/service/PaymentEndpointsWithOneOffCookieSessionSpec.scala @@ -1,8 +1,11 @@ package app.softnetwork.payment.service -import app.softnetwork.payment.scalatest.PaymentEndpointsWithOneOffCookieSessionSpecTestKit +import app.softnetwork.payment.scalatest.{ + PaymentEndpointsWithOneOffCookieSessionSpecTestKit, + PaymentRouteSpec +} import org.softnetwork.session.model.JwtClaims class PaymentEndpointsWithOneOffCookieSessionSpec - extends PaymentServiceSpec[JwtClaims] + extends PaymentRouteSpec[JwtClaims] with PaymentEndpointsWithOneOffCookieSessionSpecTestKit diff --git a/testkit/src/test/scala/app/softnetwork/payment/service/PaymentEndpointsWithOneOffHeaderSessionSpec.scala b/testkit/src/test/scala/app/softnetwork/payment/service/PaymentEndpointsWithOneOffHeaderSessionSpec.scala index db38a5e..ee4ea32 100644 --- a/testkit/src/test/scala/app/softnetwork/payment/service/PaymentEndpointsWithOneOffHeaderSessionSpec.scala +++ b/testkit/src/test/scala/app/softnetwork/payment/service/PaymentEndpointsWithOneOffHeaderSessionSpec.scala @@ -1,8 +1,11 @@ package app.softnetwork.payment.service -import app.softnetwork.payment.scalatest.PaymentEndpointsWithOneOffHeaderSessionSpecTestKit +import app.softnetwork.payment.scalatest.{ + PaymentEndpointsWithOneOffHeaderSessionSpecTestKit, + PaymentRouteSpec +} import org.softnetwork.session.model.JwtClaims class PaymentEndpointsWithOneOffHeaderSessionSpec - extends PaymentServiceSpec[JwtClaims] + extends PaymentRouteSpec[JwtClaims] with PaymentEndpointsWithOneOffHeaderSessionSpecTestKit diff --git a/testkit/src/test/scala/app/softnetwork/payment/service/PaymentEndpointsWithRefreshableCookieSessionSpec.scala b/testkit/src/test/scala/app/softnetwork/payment/service/PaymentEndpointsWithRefreshableCookieSessionSpec.scala index 0df090a..cbf06b5 100644 --- a/testkit/src/test/scala/app/softnetwork/payment/service/PaymentEndpointsWithRefreshableCookieSessionSpec.scala +++ b/testkit/src/test/scala/app/softnetwork/payment/service/PaymentEndpointsWithRefreshableCookieSessionSpec.scala @@ -1,8 +1,11 @@ package app.softnetwork.payment.service -import app.softnetwork.payment.scalatest.PaymentEndpointsWithRefreshableCookieSessionSpecTestKit +import app.softnetwork.payment.scalatest.{ + PaymentEndpointsWithRefreshableCookieSessionSpecTestKit, + PaymentRouteSpec +} import org.softnetwork.session.model.JwtClaims class PaymentEndpointsWithRefreshableCookieSessionSpec - extends PaymentServiceSpec[JwtClaims] + extends PaymentRouteSpec[JwtClaims] with PaymentEndpointsWithRefreshableCookieSessionSpecTestKit diff --git a/testkit/src/test/scala/app/softnetwork/payment/service/PaymentEndpointsWithRefreshableHeaderSessionSpec.scala b/testkit/src/test/scala/app/softnetwork/payment/service/PaymentEndpointsWithRefreshableHeaderSessionSpec.scala index 2fff99f..9f55971 100644 --- a/testkit/src/test/scala/app/softnetwork/payment/service/PaymentEndpointsWithRefreshableHeaderSessionSpec.scala +++ b/testkit/src/test/scala/app/softnetwork/payment/service/PaymentEndpointsWithRefreshableHeaderSessionSpec.scala @@ -1,8 +1,11 @@ package app.softnetwork.payment.service -import app.softnetwork.payment.scalatest.PaymentEndpointsWithRefreshableHeaderSessionSpecTestKit +import app.softnetwork.payment.scalatest.{ + PaymentEndpointsWithRefreshableHeaderSessionSpecTestKit, + PaymentRouteSpec +} import org.softnetwork.session.model.JwtClaims class PaymentEndpointsWithRefreshableHeaderSessionSpec - extends PaymentServiceSpec[JwtClaims] + extends PaymentRouteSpec[JwtClaims] with PaymentEndpointsWithRefreshableHeaderSessionSpecTestKit diff --git a/testkit/src/test/scala/app/softnetwork/payment/service/PaymentRoutesWithOneOffCookieSessionSpec.scala b/testkit/src/test/scala/app/softnetwork/payment/service/PaymentRoutesWithOneOffCookieSessionSpec.scala index f2317ce..2fa8865 100644 --- a/testkit/src/test/scala/app/softnetwork/payment/service/PaymentRoutesWithOneOffCookieSessionSpec.scala +++ b/testkit/src/test/scala/app/softnetwork/payment/service/PaymentRoutesWithOneOffCookieSessionSpec.scala @@ -1,8 +1,11 @@ package app.softnetwork.payment.service -import app.softnetwork.payment.scalatest.PaymentRoutesWithOneOffCookieSessionSpecTestKit +import app.softnetwork.payment.scalatest.{ + PaymentRouteSpec, + PaymentRoutesWithOneOffCookieSessionSpecTestKit +} import org.softnetwork.session.model.JwtClaims class PaymentRoutesWithOneOffCookieSessionSpec - extends PaymentServiceSpec[JwtClaims] + extends PaymentRouteSpec[JwtClaims] with PaymentRoutesWithOneOffCookieSessionSpecTestKit diff --git a/testkit/src/test/scala/app/softnetwork/payment/service/PaymentRoutesWithOneOffHeaderSessionSpec.scala b/testkit/src/test/scala/app/softnetwork/payment/service/PaymentRoutesWithOneOffHeaderSessionSpec.scala index 9af0dd1..46200ba 100644 --- a/testkit/src/test/scala/app/softnetwork/payment/service/PaymentRoutesWithOneOffHeaderSessionSpec.scala +++ b/testkit/src/test/scala/app/softnetwork/payment/service/PaymentRoutesWithOneOffHeaderSessionSpec.scala @@ -1,8 +1,11 @@ package app.softnetwork.payment.service -import app.softnetwork.payment.scalatest.PaymentRoutesWithOneOffHeaderSessionSpecTestKit +import app.softnetwork.payment.scalatest.{ + PaymentRouteSpec, + PaymentRoutesWithOneOffHeaderSessionSpecTestKit +} import org.softnetwork.session.model.JwtClaims class PaymentRoutesWithOneOffHeaderSessionSpec - extends PaymentServiceSpec[JwtClaims] + extends PaymentRouteSpec[JwtClaims] with PaymentRoutesWithOneOffHeaderSessionSpecTestKit diff --git a/testkit/src/test/scala/app/softnetwork/payment/service/PaymentRoutesWithRefreshableCookieSessionSpec.scala b/testkit/src/test/scala/app/softnetwork/payment/service/PaymentRoutesWithRefreshableCookieSessionSpec.scala index 08a72e1..0f40131 100644 --- a/testkit/src/test/scala/app/softnetwork/payment/service/PaymentRoutesWithRefreshableCookieSessionSpec.scala +++ b/testkit/src/test/scala/app/softnetwork/payment/service/PaymentRoutesWithRefreshableCookieSessionSpec.scala @@ -1,8 +1,11 @@ package app.softnetwork.payment.service -import app.softnetwork.payment.scalatest.PaymentRoutesWithRefreshableCookieSessionSpecTestKit +import app.softnetwork.payment.scalatest.{ + PaymentRouteSpec, + PaymentRoutesWithRefreshableCookieSessionSpecTestKit +} import org.softnetwork.session.model.JwtClaims class PaymentRoutesWithRefreshableCookieSessionSpec - extends PaymentServiceSpec[JwtClaims] + extends PaymentRouteSpec[JwtClaims] with PaymentRoutesWithRefreshableCookieSessionSpecTestKit diff --git a/testkit/src/test/scala/app/softnetwork/payment/service/PaymentRoutesWithRefreshableHeaderSessionSpec.scala b/testkit/src/test/scala/app/softnetwork/payment/service/PaymentRoutesWithRefreshableHeaderSessionSpec.scala index c942ce5..5b08511 100644 --- a/testkit/src/test/scala/app/softnetwork/payment/service/PaymentRoutesWithRefreshableHeaderSessionSpec.scala +++ b/testkit/src/test/scala/app/softnetwork/payment/service/PaymentRoutesWithRefreshableHeaderSessionSpec.scala @@ -1,8 +1,11 @@ package app.softnetwork.payment.service -import app.softnetwork.payment.scalatest.PaymentRoutesWithRefreshableHeaderSessionSpecTestKit +import app.softnetwork.payment.scalatest.{ + PaymentRouteSpec, + PaymentRoutesWithRefreshableHeaderSessionSpecTestKit +} import org.softnetwork.session.model.JwtClaims class PaymentRoutesWithRefreshableHeaderSessionSpec - extends PaymentServiceSpec[JwtClaims] + extends PaymentRouteSpec[JwtClaims] with PaymentRoutesWithRefreshableHeaderSessionSpecTestKit diff --git a/testkit/src/test/scala/app/softnetwork/payment/service/SoftPayAccount.scala b/testkit/src/test/scala/app/softnetwork/payment/service/SoftPayAccount.scala new file mode 100644 index 0000000..9141718 --- /dev/null +++ b/testkit/src/test/scala/app/softnetwork/payment/service/SoftPayAccount.scala @@ -0,0 +1,253 @@ +package app.softnetwork.payment.service + +import app.softnetwork.payment.scalatest.SoftPayAccountRouteSpec +import app.softnetwork.session.handlers.{JwtClaimsRefreshTokenDao, SessionRefreshTokenDao} +import app.softnetwork.session.model.SessionDataCompanion +import app.softnetwork.session.service.{BasicSessionMaterials, JwtSessionMaterials} +import com.softwaremill.session.RefreshTokenStorage +import org.softnetwork.session.model.{JwtClaims, Session} + +package SoftPayAccount { + package Directives { + package OneOff { + package Cookie { + + import app.softnetwork.payment.scalatest.SoftPayRoutesWithOneOfCookieSessionTestKit + + class SoftPayAccountRoutesWithOneOffCookieBasicSessionSpec + extends SoftPayAccountRouteSpec[Session] + with SoftPayRoutesWithOneOfCookieSessionTestKit[Session] + with BasicSessionMaterials[Session] { + + override implicit def refreshTokenStorage: RefreshTokenStorage[Session] = + SessionRefreshTokenDao(ts) + + override implicit def companion: SessionDataCompanion[Session] = Session + + } + + class SoftPayAccountRoutesWithOneOffCookieJwtSessionSpec + extends SoftPayAccountRouteSpec[JwtClaims] + with SoftPayRoutesWithOneOfCookieSessionTestKit[JwtClaims] + with JwtSessionMaterials[JwtClaims] { + + override implicit def refreshTokenStorage: RefreshTokenStorage[JwtClaims] = + JwtClaimsRefreshTokenDao(ts) + + override implicit def companion: SessionDataCompanion[JwtClaims] = JwtClaims + + } + } + + package Header { + + import app.softnetwork.payment.scalatest.SoftPayRoutesWithOneOfHeaderSessionTestKit + + class SoftPayAccountRoutesWithOneOffHeaderBasicSessionSpec + extends SoftPayAccountRouteSpec[Session] + with SoftPayRoutesWithOneOfHeaderSessionTestKit[Session] + with BasicSessionMaterials[Session] { + + override implicit def refreshTokenStorage: RefreshTokenStorage[Session] = + SessionRefreshTokenDao(ts) + + override implicit def companion: SessionDataCompanion[Session] = Session + + } + + class SoftPayAccountRoutesWithOneOffHeaderJwtSessionSpec + extends SoftPayAccountRouteSpec[JwtClaims] + with SoftPayRoutesWithOneOfHeaderSessionTestKit[JwtClaims] + with JwtSessionMaterials[JwtClaims] { + + override implicit def refreshTokenStorage: RefreshTokenStorage[JwtClaims] = + JwtClaimsRefreshTokenDao(ts) + + override implicit def companion: SessionDataCompanion[JwtClaims] = JwtClaims + + } + } + } + + package Refreshable { + package Cookie { + + import app.softnetwork.payment.scalatest.SoftPayRoutesWithRefreshableCookieSessionTestKit + + class SoftPayAccountRoutesWithRefreshableCookieBasicSessionSpec + extends SoftPayAccountRouteSpec[Session] + with SoftPayRoutesWithRefreshableCookieSessionTestKit[Session] + with BasicSessionMaterials[Session] { + + override implicit def refreshTokenStorage: RefreshTokenStorage[Session] = + SessionRefreshTokenDao(ts) + + override implicit def companion: SessionDataCompanion[Session] = Session + + } + + class SoftPayAccountRoutesWithRefreshableCookieJwtSessionSpec + extends SoftPayAccountRouteSpec[JwtClaims] + with SoftPayRoutesWithRefreshableCookieSessionTestKit[JwtClaims] + with JwtSessionMaterials[JwtClaims] { + + override implicit def refreshTokenStorage: RefreshTokenStorage[JwtClaims] = + JwtClaimsRefreshTokenDao(ts) + + override implicit def companion: SessionDataCompanion[JwtClaims] = JwtClaims + + } + } + + package Header { + + import app.softnetwork.payment.scalatest.SoftPayRoutesWithRefreshableHeaderSessionTestKit + + class SoftPayAccountRoutesWithRefreshableHeaderBasicSessionSpec + extends SoftPayAccountRouteSpec[Session] + with SoftPayRoutesWithRefreshableHeaderSessionTestKit[Session] + with BasicSessionMaterials[Session] { + + override implicit def refreshTokenStorage: RefreshTokenStorage[Session] = + SessionRefreshTokenDao(ts) + + override implicit def companion: SessionDataCompanion[Session] = Session + + } + + class SoftPayAccountRoutesWithRefreshableHeaderJwtSessionSpec + extends SoftPayAccountRouteSpec[JwtClaims] + with SoftPayRoutesWithRefreshableHeaderSessionTestKit[JwtClaims] + with JwtSessionMaterials[JwtClaims] { + + override implicit def refreshTokenStorage: RefreshTokenStorage[JwtClaims] = + JwtClaimsRefreshTokenDao(ts) + + override implicit def companion: SessionDataCompanion[JwtClaims] = JwtClaims + + } + } + } + } + package Endpoints { + package OneOff { + package Cookie { + + import app.softnetwork.payment.scalatest.SoftPayEndpointsWithOneOfCookieSessionTestKit + + class SoftPayAccountEndpointsWithOneOffCookieBasicSessionSpec + extends SoftPayAccountRouteSpec[Session] + with SoftPayEndpointsWithOneOfCookieSessionTestKit[Session] + with BasicSessionMaterials[Session] { + + override implicit def refreshTokenStorage: RefreshTokenStorage[Session] = + SessionRefreshTokenDao(ts) + + override implicit def companion: SessionDataCompanion[Session] = Session + + } + + class SoftPayAccountEndpointsWithOneOffCookieJwtSessionSpec + extends SoftPayAccountRouteSpec[JwtClaims] + with SoftPayEndpointsWithOneOfCookieSessionTestKit[JwtClaims] + with JwtSessionMaterials[JwtClaims] { + + override implicit def refreshTokenStorage: RefreshTokenStorage[JwtClaims] = + JwtClaimsRefreshTokenDao(ts) + + override implicit def companion: SessionDataCompanion[JwtClaims] = JwtClaims + + } + } + + package Header { + + import app.softnetwork.payment.scalatest.SoftPayEndpointsWithOneOfHeaderSessionTestKit + + class SoftPayAccountEndpointsWithOneOffHeaderBasicSessionSpec + extends SoftPayAccountRouteSpec[Session] + with SoftPayEndpointsWithOneOfHeaderSessionTestKit[Session] + with BasicSessionMaterials[Session] { + + override implicit def refreshTokenStorage: RefreshTokenStorage[Session] = + SessionRefreshTokenDao(ts) + + override implicit def companion: SessionDataCompanion[Session] = Session + + } + + class SoftPayAccountEndpointsWithOneOffHeaderJwtSessionSpec + extends SoftPayAccountRouteSpec[JwtClaims] + with SoftPayEndpointsWithOneOfHeaderSessionTestKit[JwtClaims] + with JwtSessionMaterials[JwtClaims] { + + override implicit def refreshTokenStorage: RefreshTokenStorage[JwtClaims] = + JwtClaimsRefreshTokenDao(ts) + + override implicit def companion: SessionDataCompanion[JwtClaims] = JwtClaims + + } + } + } + + package Refreshable { + package Cookie { + + import app.softnetwork.payment.scalatest.SoftPayEndpointsWithRefreshableCookieSessionTestKit + + class SoftPayAccountEndpointsWithRefreshableCookieBasicSessionSpec + extends SoftPayAccountRouteSpec[Session] + with SoftPayEndpointsWithRefreshableCookieSessionTestKit[Session] + with BasicSessionMaterials[Session] { + + override implicit def refreshTokenStorage: RefreshTokenStorage[Session] = + SessionRefreshTokenDao(ts) + + override implicit def companion: SessionDataCompanion[Session] = Session + + } + + class SoftPayAccountEndpointsWithRefreshableCookieJwtSessionSpec + extends SoftPayAccountRouteSpec[JwtClaims] + with SoftPayEndpointsWithRefreshableCookieSessionTestKit[JwtClaims] + with JwtSessionMaterials[JwtClaims] { + + override implicit def refreshTokenStorage: RefreshTokenStorage[JwtClaims] = + JwtClaimsRefreshTokenDao(ts) + + override implicit def companion: SessionDataCompanion[JwtClaims] = JwtClaims + + } + } + + package Header { + + import app.softnetwork.payment.scalatest.SoftPayEndpointsWithRefreshableHeaderSessionTestKit + + class SoftPayAccountEndpointsWithRefreshableHeaderBasicSessionSpec + extends SoftPayAccountRouteSpec[Session] + with SoftPayEndpointsWithRefreshableHeaderSessionTestKit[Session] + with BasicSessionMaterials[Session] { + + override implicit def refreshTokenStorage: RefreshTokenStorage[Session] = + SessionRefreshTokenDao(ts) + + override implicit def companion: SessionDataCompanion[Session] = Session + + } + + class SoftPayAccountEndpointsWithRefreshableHeaderJwtSessionSpec + extends SoftPayAccountRouteSpec[JwtClaims] + with SoftPayEndpointsWithRefreshableHeaderSessionTestKit[JwtClaims] + with JwtSessionMaterials[JwtClaims] { + + override implicit def refreshTokenStorage: RefreshTokenStorage[JwtClaims] = + JwtClaimsRefreshTokenDao(ts) + + override implicit def companion: SessionDataCompanion[JwtClaims] = JwtClaims + + } + } + } + } +}