2024-03-20 10:18:46 +00:00
|
|
|
package oidc
|
|
|
|
|
|
|
|
import (
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
2024-05-16 05:07:56 +00:00
|
|
|
"golang.org/x/text/language"
|
2024-03-20 10:18:46 +00:00
|
|
|
|
|
|
|
"github.com/zitadel/zitadel/internal/domain"
|
|
|
|
"github.com/zitadel/zitadel/internal/query"
|
|
|
|
)
|
|
|
|
|
|
|
|
type exchangeToken struct {
|
2024-05-16 05:07:56 +00:00
|
|
|
tokenType oidc.TokenType
|
|
|
|
userID string
|
|
|
|
issuer string
|
|
|
|
resourceOwner string
|
|
|
|
authTime time.Time
|
|
|
|
authMethods []domain.UserAuthMethodType
|
|
|
|
actor *domain.TokenActor
|
|
|
|
audience []string
|
|
|
|
scopes []string
|
|
|
|
preferredLanguage *language.Tag
|
2024-03-20 10:18:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (et *exchangeToken) nestedActor() *domain.TokenActor {
|
|
|
|
return &domain.TokenActor{
|
|
|
|
Actor: et.actor,
|
|
|
|
UserID: et.userID,
|
|
|
|
Issuer: et.issuer,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func accessToExchangeToken(token *accessToken, issuer string) *exchangeToken {
|
|
|
|
return &exchangeToken{
|
2024-05-16 05:07:56 +00:00
|
|
|
tokenType: oidc.AccessTokenType,
|
|
|
|
userID: token.userID,
|
|
|
|
issuer: issuer,
|
|
|
|
resourceOwner: token.resourceOwner,
|
|
|
|
authMethods: token.authMethods,
|
|
|
|
actor: token.actor,
|
|
|
|
audience: token.audience,
|
|
|
|
scopes: token.scope,
|
|
|
|
preferredLanguage: token.preferredLanguage,
|
2024-03-20 10:18:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func idTokenClaimsToExchangeToken(claims *oidc.IDTokenClaims, resourceOwner string) *exchangeToken {
|
2024-05-16 05:07:56 +00:00
|
|
|
var preferredLanguage *language.Tag
|
|
|
|
if tag := claims.Locale.Tag(); !tag.IsRoot() {
|
|
|
|
preferredLanguage = &tag
|
|
|
|
}
|
2024-03-20 10:18:46 +00:00
|
|
|
return &exchangeToken{
|
2024-05-16 05:07:56 +00:00
|
|
|
tokenType: oidc.IDTokenType,
|
|
|
|
userID: claims.Subject,
|
|
|
|
issuer: claims.Issuer,
|
|
|
|
resourceOwner: resourceOwner,
|
|
|
|
authTime: claims.GetAuthTime(),
|
|
|
|
authMethods: AMRToAuthMethodTypes(claims.AuthenticationMethodsReferences),
|
|
|
|
actor: actorClaimsToDomain(claims.Actor),
|
|
|
|
audience: claims.Audience,
|
|
|
|
preferredLanguage: preferredLanguage,
|
2024-03-20 10:18:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func actorClaimsToDomain(actor *oidc.ActorClaims) *domain.TokenActor {
|
|
|
|
if actor == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return &domain.TokenActor{
|
|
|
|
Actor: actorClaimsToDomain(actor.Actor),
|
|
|
|
UserID: actor.Subject,
|
|
|
|
Issuer: actor.Issuer,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func actorDomainToClaims(actor *domain.TokenActor) *oidc.ActorClaims {
|
|
|
|
if actor == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return &oidc.ActorClaims{
|
|
|
|
Actor: actorDomainToClaims(actor.Actor),
|
|
|
|
Subject: actor.UserID,
|
|
|
|
Issuer: actor.Issuer,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-16 05:07:56 +00:00
|
|
|
func jwtToExchangeToken(jwt *oidc.JWTTokenRequest, resourceOwner string, preferredLanguage *language.Tag) *exchangeToken {
|
2024-03-20 10:18:46 +00:00
|
|
|
return &exchangeToken{
|
|
|
|
tokenType: oidc.JWTTokenType,
|
|
|
|
userID: jwt.Subject,
|
|
|
|
issuer: jwt.Issuer,
|
|
|
|
resourceOwner: resourceOwner,
|
|
|
|
scopes: jwt.Scopes,
|
|
|
|
authTime: jwt.IssuedAt.AsTime(),
|
|
|
|
// audience omitted as we don't thrust audiences not signed by us
|
2024-05-16 05:07:56 +00:00
|
|
|
preferredLanguage: preferredLanguage,
|
2024-03-20 10:18:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func userToExchangeToken(user *query.User) *exchangeToken {
|
|
|
|
return &exchangeToken{
|
|
|
|
tokenType: UserIDTokenType,
|
|
|
|
userID: user.ID,
|
|
|
|
resourceOwner: user.ResourceOwner,
|
|
|
|
}
|
|
|
|
}
|