diff --git a/silhouette/app/com/mohiva/play/silhouette/api/actions/SecuredAction.scala b/silhouette/app/com/mohiva/play/silhouette/api/actions/SecuredAction.scala index 7267ec7a5..11c68a24f 100644 --- a/silhouette/app/com/mohiva/play/silhouette/api/actions/SecuredAction.scala +++ b/silhouette/app/com/mohiva/play/silhouette/api/actions/SecuredAction.scala @@ -29,17 +29,67 @@ import play.api.{ Configuration, Environment => PlayEnv } import scala.concurrent.{ ExecutionContext, Future } +/** + * A request header that only allows access if an identity is authenticated and authorized. + * + * @tparam E The type of the environment. + */ +trait SecuredRequestHeader[E <: Env] extends RequestHeader { + /** + * @return The identity implementation. + */ + def identity: E#I + + /** + * @return The authenticator implementation. + */ + def authenticator: E#A +} + /** * A request that only allows access if an identity is authenticated and authorized. * - * @param identity The identity implementation. - * @param authenticator The authenticator implementation. - * @param request The current request. * @tparam E The type of the environment. * @tparam B The type of the request body. */ -case class SecuredRequest[E <: Env, B](identity: E#I, authenticator: E#A, request: Request[B]) - extends WrappedRequest(request) +trait SecuredRequest[E <: Env, +B] extends Request[B] with SecuredRequestHeader[E] + +object SecuredRequest { + /** + * A request that only allows access if an identity is authenticated and authorized. + * + * @param identity The identity implementation. + * @param authenticator The authenticator implementation. + * @param request The current request. + * @tparam E The type of the environment. + * @tparam B The type of the request body. + */ + def apply[E <: Env, B](identity: E#I, authenticator: E#A, request: Request[B]): SecuredRequest[E, B] = { + new DefaultSecuredRequest(identity, authenticator, request) + } + + /** + * Unapply method for secured request. + * + * @param securedRequest the secured request. + * @tparam E The type of the environment. + * @tparam B The type of the request body. + */ + def unapply[E <: Env, B](securedRequest: SecuredRequest[E, B]): Option[(E#I, E#A, Request[B])] = { + securedRequest match { + case dsr: DefaultSecuredRequest[E, B] => + Some((dsr.identity, dsr.authenticator, dsr.request)) + case sr: SecuredRequest[E, B] => + Some((sr.identity, sr.authenticator, sr)) + } + } +} + +class DefaultSecuredRequest[E <: Env, B]( + val identity: E#I, + val authenticator: E#A, + val request: Request[B] +) extends WrappedRequest(request) with SecuredRequest[E, B] /** * Request handler builder implementation to provide the foundation for secured request handlers. diff --git a/silhouette/app/com/mohiva/play/silhouette/api/actions/UserAwareAction.scala b/silhouette/app/com/mohiva/play/silhouette/api/actions/UserAwareAction.scala index f2c4ba171..87e94fde7 100644 --- a/silhouette/app/com/mohiva/play/silhouette/api/actions/UserAwareAction.scala +++ b/silhouette/app/com/mohiva/play/silhouette/api/actions/UserAwareAction.scala @@ -31,14 +31,62 @@ import scala.concurrent.{ ExecutionContext, Future } /** * A request that adds maybe the identity and maybe the authenticator for the current call. * - * @param identity Some identity implementation if authentication was successful, None otherwise. - * @param authenticator Some authenticator implementation if authentication was successful, None otherwise. - * @param request The current request. * @tparam E The type of the environment. - * @tparam B The type of the request body. */ -case class UserAwareRequest[E <: Env, B](identity: Option[E#I], authenticator: Option[E#A], request: Request[B]) - extends WrappedRequest(request) +trait UserAwareRequestHeader[E <: Env] extends RequestHeader { + /** + * @return Some identity implementation if authentication was successful, None otherwise. + */ + def identity: Option[E#I] + + /** + * @return Some authenticator implementation if authentication was successful, None otherwise. + */ + def authenticator: Option[E#A] +} + +trait UserAwareRequest[E <: Env, +B] extends Request[B] with UserAwareRequestHeader[E] + +object UserAwareRequest { + + /** + * A request that adds maybe the identity and maybe the authenticator for the current call. + * + * @param identity Some identity implementation if authentication was successful, None otherwise. + * @param authenticator Some authenticator implementation if authentication was successful, None otherwise. + * @param request The current request. + * @tparam E The type of the environment. + * @tparam B The type of the request body. + */ + def apply[E <: Env, B]( + identity: Option[E#I], + authenticator: Option[E#A], + request: Request[B]): UserAwareRequest[E, B] = { + new DefaultUserAwareRequest(identity, authenticator, request) + } + + /** + * Unapply method for user aware request. + * + * @param userAwareRequest the user aware request. + * @tparam E The type of the environment. + * @tparam B The type of the request body. + */ + def unapply[E <: Env, B](userAwareRequest: UserAwareRequest[E, B]): Option[(Option[E#I], Option[E#A], Request[B])] = { + userAwareRequest match { + case duar: DefaultUserAwareRequest[E, B] => + Some((duar.identity, duar.authenticator, duar.request)) + case uar: UserAwareRequest[E, B] => + Some((uar.identity, uar.authenticator, uar)) + } + } +} + +class DefaultUserAwareRequest[E <: Env, B]( + val identity: Option[E#I], + val authenticator: Option[E#A], + val request: Request[B] +) extends WrappedRequest(request) with UserAwareRequest[E, B] /** * Request handler builder implementation to provide the foundation for user-aware request handlers.