diff --git a/core/shared/src/main/scala/works/iterative/core/auth/BasicProfile.scala b/core/shared/src/main/scala/works/iterative/core/auth/BasicProfile.scala index 32956d5..04ba961 100644 --- a/core/shared/src/main/scala/works/iterative/core/auth/BasicProfile.scala +++ b/core/shared/src/main/scala/works/iterative/core/auth/BasicProfile.scala @@ -19,4 +19,12 @@ object BasicProfile: def apply(p: UserProfile): BasicProfile = p match case p: BasicProfile => p - case _ => BasicProfile(p.subjectId, p.userName, p.email, p.avatar, p.roles) + case _ => + BasicProfile( + p.subjectId, + p.userName, + p.email, + p.avatar, + p.roles, + p.claims + ) diff --git a/core/shared/src/main/scala/works/iterative/core/auth/BasicProfile.scala b/core/shared/src/main/scala/works/iterative/core/auth/BasicProfile.scala index 32956d5..04ba961 100644 --- a/core/shared/src/main/scala/works/iterative/core/auth/BasicProfile.scala +++ b/core/shared/src/main/scala/works/iterative/core/auth/BasicProfile.scala @@ -19,4 +19,12 @@ object BasicProfile: def apply(p: UserProfile): BasicProfile = p match case p: BasicProfile => p - case _ => BasicProfile(p.subjectId, p.userName, p.email, p.avatar, p.roles) + case _ => + BasicProfile( + p.subjectId, + p.userName, + p.email, + p.avatar, + p.roles, + p.claims + ) diff --git a/core/shared/src/main/scala/works/iterative/core/auth/UserProfile.scala b/core/shared/src/main/scala/works/iterative/core/auth/UserProfile.scala index 379a7da..1f452b0 100644 --- a/core/shared/src/main/scala/works/iterative/core/auth/UserProfile.scala +++ b/core/shared/src/main/scala/works/iterative/core/auth/UserProfile.scala @@ -5,3 +5,4 @@ def userName: Option[UserName] def email: Option[Email] def avatar: Option[Avatar] + def claims: Set[Claim] diff --git a/core/shared/src/main/scala/works/iterative/core/auth/BasicProfile.scala b/core/shared/src/main/scala/works/iterative/core/auth/BasicProfile.scala index 32956d5..04ba961 100644 --- a/core/shared/src/main/scala/works/iterative/core/auth/BasicProfile.scala +++ b/core/shared/src/main/scala/works/iterative/core/auth/BasicProfile.scala @@ -19,4 +19,12 @@ object BasicProfile: def apply(p: UserProfile): BasicProfile = p match case p: BasicProfile => p - case _ => BasicProfile(p.subjectId, p.userName, p.email, p.avatar, p.roles) + case _ => + BasicProfile( + p.subjectId, + p.userName, + p.email, + p.avatar, + p.roles, + p.claims + ) diff --git a/core/shared/src/main/scala/works/iterative/core/auth/UserProfile.scala b/core/shared/src/main/scala/works/iterative/core/auth/UserProfile.scala index 379a7da..1f452b0 100644 --- a/core/shared/src/main/scala/works/iterative/core/auth/UserProfile.scala +++ b/core/shared/src/main/scala/works/iterative/core/auth/UserProfile.scala @@ -5,3 +5,4 @@ def userName: Option[UserName] def email: Option[Email] def avatar: Option[Avatar] + def claims: Set[Claim] diff --git a/server/http/src/main/scala/works/iterative/server/http/impl/blaze/BlazeHttpServer.scala b/server/http/src/main/scala/works/iterative/server/http/impl/blaze/BlazeHttpServer.scala index b1481ae..309f90e 100644 --- a/server/http/src/main/scala/works/iterative/server/http/impl/blaze/BlazeHttpServer.scala +++ b/server/http/src/main/scala/works/iterative/server/http/impl/blaze/BlazeHttpServer.scala @@ -17,14 +17,14 @@ import works.iterative.tapir.BaseUri import org.http4s.server.Router import org.http4s.server.websocket.WebSocketBuilder2 -import com.nimbusds.jwt.JWTClaimsSet -import works.iterative.core.auth.Claim +import org.pac4j.core.profile.CommonProfile +import works.iterative.core.auth.BasicProfile class BlazeHttpServer( config: BlazeServerConfig, pac4jConfig: Pac4jSecurityConfig, baseUri: BaseUri, - gatherClaims: JWTClaimsSet => Set[Claim] = _ => Set.empty + updateProfile: (CommonProfile, BasicProfile) => BasicProfile ) extends HttpServer: override def serve[Env](app: HttpApplication[Env]): URIO[Env, Nothing] = type AppTask[A] = RIO[Env, A] @@ -43,7 +43,7 @@ ) val pac4jSecurity = - Pac4jHttpSecurity[AppTask](pac4jConfig, contextBuilder, gatherClaims) + Pac4jHttpSecurity[AppTask](pac4jConfig, contextBuilder, updateProfile) def provideCurrentUser( routes: HttpRoutes[SecuredTask] @@ -104,12 +104,12 @@ object BlazeHttpServer: def layer( - gatherClaims: JWTClaimsSet => Set[Claim] = _ => Set.empty + updateProfile: (CommonProfile, BasicProfile) => BasicProfile = (_, u) => u ): RLayer[BlazeServerConfig & Pac4jSecurityConfig & BaseUri, HttpServer] = ZLayer { for config <- ZIO.service[BlazeServerConfig] pac4jConfig <- ZIO.service[Pac4jSecurityConfig] baseUri <- ZIO.service[BaseUri] - yield BlazeHttpServer(config, pac4jConfig, baseUri, gatherClaims) + yield BlazeHttpServer(config, pac4jConfig, baseUri, updateProfile) } diff --git a/core/shared/src/main/scala/works/iterative/core/auth/BasicProfile.scala b/core/shared/src/main/scala/works/iterative/core/auth/BasicProfile.scala index 32956d5..04ba961 100644 --- a/core/shared/src/main/scala/works/iterative/core/auth/BasicProfile.scala +++ b/core/shared/src/main/scala/works/iterative/core/auth/BasicProfile.scala @@ -19,4 +19,12 @@ object BasicProfile: def apply(p: UserProfile): BasicProfile = p match case p: BasicProfile => p - case _ => BasicProfile(p.subjectId, p.userName, p.email, p.avatar, p.roles) + case _ => + BasicProfile( + p.subjectId, + p.userName, + p.email, + p.avatar, + p.roles, + p.claims + ) diff --git a/core/shared/src/main/scala/works/iterative/core/auth/UserProfile.scala b/core/shared/src/main/scala/works/iterative/core/auth/UserProfile.scala index 379a7da..1f452b0 100644 --- a/core/shared/src/main/scala/works/iterative/core/auth/UserProfile.scala +++ b/core/shared/src/main/scala/works/iterative/core/auth/UserProfile.scala @@ -5,3 +5,4 @@ def userName: Option[UserName] def email: Option[Email] def avatar: Option[Avatar] + def claims: Set[Claim] diff --git a/server/http/src/main/scala/works/iterative/server/http/impl/blaze/BlazeHttpServer.scala b/server/http/src/main/scala/works/iterative/server/http/impl/blaze/BlazeHttpServer.scala index b1481ae..309f90e 100644 --- a/server/http/src/main/scala/works/iterative/server/http/impl/blaze/BlazeHttpServer.scala +++ b/server/http/src/main/scala/works/iterative/server/http/impl/blaze/BlazeHttpServer.scala @@ -17,14 +17,14 @@ import works.iterative.tapir.BaseUri import org.http4s.server.Router import org.http4s.server.websocket.WebSocketBuilder2 -import com.nimbusds.jwt.JWTClaimsSet -import works.iterative.core.auth.Claim +import org.pac4j.core.profile.CommonProfile +import works.iterative.core.auth.BasicProfile class BlazeHttpServer( config: BlazeServerConfig, pac4jConfig: Pac4jSecurityConfig, baseUri: BaseUri, - gatherClaims: JWTClaimsSet => Set[Claim] = _ => Set.empty + updateProfile: (CommonProfile, BasicProfile) => BasicProfile ) extends HttpServer: override def serve[Env](app: HttpApplication[Env]): URIO[Env, Nothing] = type AppTask[A] = RIO[Env, A] @@ -43,7 +43,7 @@ ) val pac4jSecurity = - Pac4jHttpSecurity[AppTask](pac4jConfig, contextBuilder, gatherClaims) + Pac4jHttpSecurity[AppTask](pac4jConfig, contextBuilder, updateProfile) def provideCurrentUser( routes: HttpRoutes[SecuredTask] @@ -104,12 +104,12 @@ object BlazeHttpServer: def layer( - gatherClaims: JWTClaimsSet => Set[Claim] = _ => Set.empty + updateProfile: (CommonProfile, BasicProfile) => BasicProfile = (_, u) => u ): RLayer[BlazeServerConfig & Pac4jSecurityConfig & BaseUri, HttpServer] = ZLayer { for config <- ZIO.service[BlazeServerConfig] pac4jConfig <- ZIO.service[Pac4jSecurityConfig] baseUri <- ZIO.service[BaseUri] - yield BlazeHttpServer(config, pac4jConfig, baseUri, gatherClaims) + yield BlazeHttpServer(config, pac4jConfig, baseUri, updateProfile) } diff --git a/server/http/src/main/scala/works/iterative/server/http/impl/pac4j/Pac4jHttpSecurity.scala b/server/http/src/main/scala/works/iterative/server/http/impl/pac4j/Pac4jHttpSecurity.scala index 177f8d0..c091805 100644 --- a/server/http/src/main/scala/works/iterative/server/http/impl/pac4j/Pac4jHttpSecurity.scala +++ b/server/http/src/main/scala/works/iterative/server/http/impl/pac4j/Pac4jHttpSecurity.scala @@ -19,15 +19,13 @@ import works.iterative.core.Email import works.iterative.core.Avatar import works.iterative.core.auth.* -import org.pac4j.oidc.profile.OidcProfile -import com.nimbusds.jwt.JWTClaimsSet trait HttpSecurity class Pac4jHttpSecurity[F[_] <: AnyRef: Sync]( config: Pac4jSecurityConfig, contextBuilder: (Request[F], Config) => Http4sWebContext[F], - gatherClaims: JWTClaimsSet => Set[Claim] = _ => Set.empty + updateProfile: (CommonProfile, BasicProfile) => BasicProfile ) extends HttpSecurity: protected val dsl: Http4sDsl[F] = new Http4sDsl[F] {} import dsl.* @@ -79,19 +77,18 @@ def loggedInUser(p: CommonProfile): CurrentUser = import scala.jdk.CollectionConverters.* CurrentUser( - BasicProfile( - UserId.unsafe(p.getUsername()), - Option(p.getDisplayName()).flatMap(UserName(_).toOption), - Option(p.getEmail()).flatMap(Email(_).toOption), - Option(p.getPictureUrl()).flatMap(Avatar(_).toOption), - Option(p.getRoles()) - .map(_.asScala.toSet) - .getOrElse(Set.empty) - .flatMap(UserRole(_).toOption), - p match - case o: OidcProfile => - gatherClaims(o.getIdToken().getJWTClaimsSet()) - case _ => Set.empty + updateProfile( + p, + BasicProfile( + UserId.unsafe(p.getUsername()), + Option(p.getDisplayName()).flatMap(UserName(_).toOption), + Option(p.getEmail()).flatMap(Email(_).toOption), + Option(p.getPictureUrl()).flatMap(Avatar(_).toOption), + Option(p.getRoles()) + .map(_.asScala.toSet) + .getOrElse(Set.empty) + .flatMap(UserRole(_).toOption) + ) ) ) r.context match {