mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-23 02:16:48 +00:00
store project ID in the access token
This commit is contained in:
27
cmd/setup/26.go
Normal file
27
cmd/setup/26.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package setup
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/database"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
)
|
||||
|
||||
var (
|
||||
//go:embed 26.sql
|
||||
addTokenProjectID string
|
||||
)
|
||||
|
||||
type AddProjectIDToAuthTokens struct {
|
||||
dbClient *database.DB
|
||||
}
|
||||
|
||||
func (mig *AddProjectIDToAuthTokens) Execute(ctx context.Context, _ eventstore.Event) error {
|
||||
_, err := mig.dbClient.ExecContext(ctx, addTokenProjectID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (mig *AddProjectIDToAuthTokens) String() string {
|
||||
return "26_add_project_id_col_to_auth_tokens"
|
||||
}
|
||||
1
cmd/setup/26.sql
Normal file
1
cmd/setup/26.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE auth.tokens ADD COLUMN project_id varchar null;
|
||||
@@ -104,6 +104,7 @@ type Steps struct {
|
||||
s23CorrectGlobalUniqueConstraints *CorrectGlobalUniqueConstraints
|
||||
s24AddActorToAuthTokens *AddActorToAuthTokens
|
||||
s25User11AddLowerFieldsToVerifiedEmail *User11AddLowerFieldsToVerifiedEmail
|
||||
s26AddProjectIDToAuthTokens *AddProjectIDToAuthTokens
|
||||
}
|
||||
|
||||
func MustNewSteps(v *viper.Viper) *Steps {
|
||||
|
||||
@@ -138,6 +138,7 @@ func Setup(config *Config, steps *Steps, masterKey string) {
|
||||
steps.s23CorrectGlobalUniqueConstraints = &CorrectGlobalUniqueConstraints{dbClient: esPusherDBClient}
|
||||
steps.s24AddActorToAuthTokens = &AddActorToAuthTokens{dbClient: queryDBClient}
|
||||
steps.s25User11AddLowerFieldsToVerifiedEmail = &User11AddLowerFieldsToVerifiedEmail{dbClient: esPusherDBClient}
|
||||
steps.s26AddProjectIDToAuthTokens = &AddProjectIDToAuthTokens{dbClient: queryDBClient}
|
||||
|
||||
err = projection.Create(ctx, projectionDBClient, eventstoreClient, config.Projections, nil, nil, nil)
|
||||
logging.OnError(err).Fatal("unable to start projections")
|
||||
@@ -175,6 +176,7 @@ func Setup(config *Config, steps *Steps, masterKey string) {
|
||||
steps.s22ActiveInstancesIndex,
|
||||
steps.s23CorrectGlobalUniqueConstraints,
|
||||
steps.s24AddActorToAuthTokens,
|
||||
steps.s26AddProjectIDToAuthTokens,
|
||||
} {
|
||||
mustExecuteMigration(ctx, eventstoreClient, step, "migration failed")
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ type accessToken struct {
|
||||
resourceOwner string
|
||||
subject string
|
||||
clientID string
|
||||
projectID string
|
||||
audience []string
|
||||
scope []string
|
||||
authMethods []domain.UserAuthMethodType
|
||||
@@ -75,6 +76,7 @@ func accessTokenV1(tokenID, subject string, token *model.TokenView) *accessToken
|
||||
resourceOwner: token.ResourceOwner,
|
||||
subject: subject,
|
||||
clientID: token.ApplicationID,
|
||||
projectID: token.ProjectID,
|
||||
audience: token.Audience,
|
||||
scope: token.Scopes,
|
||||
tokenCreation: token.CreationDate,
|
||||
@@ -91,6 +93,7 @@ func accessTokenV2(tokenID, subject string, token *query.OIDCSessionAccessTokenR
|
||||
resourceOwner: token.ResourceOwner,
|
||||
subject: subject,
|
||||
clientID: token.ClientID,
|
||||
projectID: token.ProjectID,
|
||||
audience: token.Audience,
|
||||
scope: token.Scope,
|
||||
authMethods: token.AuthMethods,
|
||||
|
||||
@@ -218,7 +218,7 @@ func (o *OPStorage) CreateAccessToken(ctx context.Context, req op.TokenRequest)
|
||||
}()
|
||||
if authReq, ok := req.(*AuthRequestV2); ok {
|
||||
activity.Trigger(ctx, "", authReq.CurrentAuthRequest.UserID, activity.OIDCAccessToken, o.eventstore.FilterToQueryReducer)
|
||||
return o.command.AddOIDCSessionAccessToken(setContextUserSystem(ctx), authReq.GetID())
|
||||
return o.command.AddOIDCSessionAccessToken(setContextUserSystem(ctx), authReq.GetID(), "")
|
||||
}
|
||||
|
||||
userAgentID, applicationID, userOrgID, authTime, amr, reason, actor := getInfoFromRequest(req)
|
||||
@@ -227,7 +227,7 @@ func (o *OPStorage) CreateAccessToken(ctx context.Context, req op.TokenRequest)
|
||||
return "", time.Time{}, err
|
||||
}
|
||||
|
||||
resp, err := o.command.AddUserToken(setContextUserSystem(ctx), userOrgID, userAgentID, applicationID, req.GetSubject(), req.GetAudience(), req.GetScopes(), amr, accessTokenLifetime, authTime, reason, actor)
|
||||
resp, err := o.command.AddUserToken(setContextUserSystem(ctx), userOrgID, userAgentID, applicationID, "", req.GetSubject(), req.GetAudience(), req.GetScopes(), amr, accessTokenLifetime, authTime, reason, actor)
|
||||
if err != nil {
|
||||
return "", time.Time{}, err
|
||||
}
|
||||
@@ -249,7 +249,7 @@ func (o *OPStorage) CreateAccessAndRefreshTokens(ctx context.Context, req op.Tok
|
||||
case *AuthRequestV2:
|
||||
// trigger activity log for authentication for user
|
||||
activity.Trigger(ctx, "", tokenReq.GetSubject(), activity.OIDCRefreshToken, o.eventstore.FilterToQueryReducer)
|
||||
return o.command.AddOIDCSessionRefreshAndAccessToken(setContextUserSystem(ctx), tokenReq.GetID())
|
||||
return o.command.AddOIDCSessionRefreshAndAccessToken(setContextUserSystem(ctx), tokenReq.GetID(), "")
|
||||
case *RefreshTokenRequestV2:
|
||||
// trigger activity log for authentication for user
|
||||
activity.Trigger(ctx, "", tokenReq.GetSubject(), activity.OIDCRefreshToken, o.eventstore.FilterToQueryReducer)
|
||||
@@ -270,7 +270,7 @@ func (o *OPStorage) CreateAccessAndRefreshTokens(ctx context.Context, req op.Tok
|
||||
return "", "", time.Time{}, err
|
||||
}
|
||||
|
||||
resp, token, err := o.command.AddAccessAndRefreshToken(setContextUserSystem(ctx), userOrgID, userAgentID, applicationID, req.GetSubject(),
|
||||
resp, token, err := o.command.AddAccessAndRefreshToken(setContextUserSystem(ctx), userOrgID, userAgentID, applicationID, "", req.GetSubject(),
|
||||
refreshToken, req.GetAudience(), scopes, authMethodsReferences, accessTokenLifetime,
|
||||
refreshTokenIdleExpiration, refreshTokenExpiration, authTime, reason, actor) //PLANNED: lifetime from client
|
||||
if err != nil {
|
||||
|
||||
@@ -249,7 +249,7 @@ func (s *Server) createExchangeTokens(ctx context.Context, tokenType oidc.TokenT
|
||||
resp.IssuedTokenType = oidc.JWTTokenType
|
||||
|
||||
case oidc.IDTokenType:
|
||||
resp.AccessToken, resp.ExpiresIn, err = s.createExchangeIDToken(ctx, signingKey, client, subjectToken.userID, "", audience, userInfo, actorToken.authMethods, actorToken.authTime, reason, actor)
|
||||
resp.AccessToken, resp.ExpiresIn, err = s.createExchangeIDToken(ctx, signingKey, client, subjectToken.userID, "", audience, userInfo, actorToken.authMethods, actorToken.authTime, actor)
|
||||
resp.TokenType = TokenTypeNA
|
||||
resp.IssuedTokenType = oidc.IDTokenType
|
||||
case oidc.RefreshTokenType, UserIDTokenType:
|
||||
@@ -262,7 +262,7 @@ func (s *Server) createExchangeTokens(ctx context.Context, tokenType oidc.TokenT
|
||||
}
|
||||
|
||||
if slices.Contains(scopes, oidc.ScopeOpenID) && tokenType != oidc.IDTokenType {
|
||||
resp.IDToken, _, err = s.createExchangeIDToken(ctx, signingKey, client, subjectToken.userID, resp.AccessToken, audience, userInfo, actorToken.authMethods, actorToken.authTime, reason, actor)
|
||||
resp.IDToken, _, err = s.createExchangeIDToken(ctx, signingKey, client, subjectToken.userID, resp.AccessToken, audience, userInfo, actorToken.authMethods, actorToken.authTime, actor)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -306,7 +306,7 @@ func (s *Server) createExchangeJWT(ctx context.Context, signingKey op.SigningKey
|
||||
return accessToken, refreshToken, timeToOIDCExpiresIn(expTime), nil
|
||||
}
|
||||
|
||||
func (s *Server) createExchangeIDToken(ctx context.Context, signingKey op.SigningKey, client *Client, userID, accessToken string, audience []string, userInfo *oidc.UserInfo, authMethods []domain.UserAuthMethodType, authTime time.Time, reason domain.TokenReason, actor *domain.TokenActor) (idToken string, exp uint64, err error) {
|
||||
func (s *Server) createExchangeIDToken(ctx context.Context, signingKey op.SigningKey, client *Client, userID, accessToken string, audience []string, userInfo *oidc.UserInfo, authMethods []domain.UserAuthMethodType, authTime time.Time, actor *domain.TokenActor) (idToken string, exp uint64, err error) {
|
||||
expTime := time.Now().Add(client.IDTokenLifetime()).Add(client.ClockSkew())
|
||||
claims := oidc.NewIDTokenClaims(op.IssuerFromContext(ctx), userID, audience, expTime, authTime, "", "", AuthMethodTypesToAMR(authMethods), client.GetID(), client.ClockSkew())
|
||||
claims.Actor = actorDomainToClaims(actor)
|
||||
@@ -333,15 +333,14 @@ func (s *Server) createAccessTokenCommands(ctx context.Context, client *Client,
|
||||
settings := client.client.Settings
|
||||
if slices.Contains(scopes, oidc.ScopeOfflineAccess) {
|
||||
return s.command.AddAccessAndRefreshToken(
|
||||
ctx, resourceOwner, "", client.GetID(), userID, "", audience, scopes, AuthMethodTypesToAMR(authMethods),
|
||||
settings.AccessTokenLifetime, settings.RefreshTokenIdleExpiration, settings.RefreshTokenExpiration,
|
||||
authTime, reason, actor,
|
||||
ctx, resourceOwner, "", client.GetID(), client.client.ProjectID, userID, "", audience, scopes,
|
||||
AuthMethodTypesToAMR(authMethods), settings.AccessTokenLifetime, settings.RefreshTokenIdleExpiration,
|
||||
settings.RefreshTokenExpiration, authTime, reason, actor,
|
||||
)
|
||||
}
|
||||
tokenInfo, err = s.command.AddUserToken(
|
||||
ctx, resourceOwner, "", client.GetID(), userID, audience, scopes, AuthMethodTypesToAMR(authMethods),
|
||||
settings.AccessTokenLifetime,
|
||||
authTime, reason, actor,
|
||||
ctx, resourceOwner, "", client.GetID(), client.client.ProjectID, userID, audience, scopes,
|
||||
AuthMethodTypesToAMR(authMethods), settings.AccessTokenLifetime, authTime, reason, actor,
|
||||
)
|
||||
return tokenInfo, "", err
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ func (s *Server) UserInfo(ctx context.Context, r *op.Request[oidc.UserInfoReques
|
||||
if err != nil {
|
||||
return nil, op.NewStatusError(oidc.ErrAccessDenied().WithDescription("access token invalid").WithParent(err), http.StatusUnauthorized)
|
||||
}
|
||||
userInfo, err := s.userInfo(ctx, token.userID, "", token.scope, token.audience)
|
||||
userInfo, err := s.userInfo(ctx, token.userID, token.projectID, token.scope, token.audience)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -30,13 +30,13 @@ const (
|
||||
|
||||
// AddOIDCSessionAccessToken creates a new OIDC Session, creates an access token and returns its id and expiration.
|
||||
// If the underlying [AuthRequest] is a OIDC Auth Code Flow, it will set the code as exchanged.
|
||||
func (c *Commands) AddOIDCSessionAccessToken(ctx context.Context, authRequestID string) (string, time.Time, error) {
|
||||
func (c *Commands) AddOIDCSessionAccessToken(ctx context.Context, authRequestID, projectID string) (string, time.Time, error) {
|
||||
cmd, err := c.newOIDCSessionAddEvents(ctx, authRequestID)
|
||||
if err != nil {
|
||||
return "", time.Time{}, err
|
||||
}
|
||||
cmd.AddSession(ctx)
|
||||
if err = cmd.AddAccessToken(ctx, cmd.authRequestWriteModel.Scope, domain.TokenReasonAuthRequest, nil); err != nil {
|
||||
cmd.AddSession(ctx, projectID)
|
||||
if err = cmd.AddAccessToken(ctx, projectID, cmd.authRequestWriteModel.Scope, domain.TokenReasonAuthRequest, nil); err != nil {
|
||||
return "", time.Time{}, err
|
||||
}
|
||||
cmd.SetAuthRequestSuccessful(ctx)
|
||||
@@ -47,13 +47,13 @@ func (c *Commands) AddOIDCSessionAccessToken(ctx context.Context, authRequestID
|
||||
// AddOIDCSessionRefreshAndAccessToken creates a new OIDC Session, creates an access token and refresh token.
|
||||
// It returns the access token id, expiration and the refresh token.
|
||||
// If the underlying [AuthRequest] is a OIDC Auth Code Flow, it will set the code as exchanged.
|
||||
func (c *Commands) AddOIDCSessionRefreshAndAccessToken(ctx context.Context, authRequestID string) (tokenID, refreshToken string, tokenExpiration time.Time, err error) {
|
||||
func (c *Commands) AddOIDCSessionRefreshAndAccessToken(ctx context.Context, authRequestID, projectID string) (tokenID, refreshToken string, tokenExpiration time.Time, err error) {
|
||||
cmd, err := c.newOIDCSessionAddEvents(ctx, authRequestID)
|
||||
if err != nil {
|
||||
return "", "", time.Time{}, err
|
||||
}
|
||||
cmd.AddSession(ctx)
|
||||
if err = cmd.AddAccessToken(ctx, cmd.authRequestWriteModel.Scope, domain.TokenReasonAuthRequest, nil); err != nil {
|
||||
cmd.AddSession(ctx, projectID)
|
||||
if err = cmd.AddAccessToken(ctx, projectID, cmd.authRequestWriteModel.Scope, domain.TokenReasonAuthRequest, nil); err != nil {
|
||||
return "", "", time.Time{}, err
|
||||
}
|
||||
if err = cmd.AddRefreshToken(ctx); err != nil {
|
||||
@@ -70,7 +70,7 @@ func (c *Commands) ExchangeOIDCSessionRefreshAndAccessToken(ctx context.Context,
|
||||
if err != nil {
|
||||
return "", "", time.Time{}, err
|
||||
}
|
||||
if err = cmd.AddAccessToken(ctx, scope, domain.TokenReasonRefresh, nil); err != nil {
|
||||
if err = cmd.AddAccessToken(ctx, cmd.oidcSessionWriteModel.ProjectID, scope, domain.TokenReasonRefresh, nil); err != nil {
|
||||
return "", "", time.Time{}, err
|
||||
}
|
||||
if err = cmd.RenewRefreshToken(ctx); err != nil {
|
||||
@@ -273,7 +273,7 @@ type OIDCSessionEvents struct {
|
||||
refreshToken string
|
||||
}
|
||||
|
||||
func (c *OIDCSessionEvents) AddSession(ctx context.Context) {
|
||||
func (c *OIDCSessionEvents) AddSession(ctx context.Context, projectID string) {
|
||||
c.events = append(c.events, oidcsession.NewAddedEvent(
|
||||
ctx,
|
||||
c.oidcSessionWriteModel.aggregate,
|
||||
@@ -291,13 +291,13 @@ func (c *OIDCSessionEvents) SetAuthRequestSuccessful(ctx context.Context) {
|
||||
c.events = append(c.events, authrequest.NewSucceededEvent(ctx, c.authRequestWriteModel.aggregate))
|
||||
}
|
||||
|
||||
func (c *OIDCSessionEvents) AddAccessToken(ctx context.Context, scope []string, reason domain.TokenReason, actor *domain.TokenActor) error {
|
||||
func (c *OIDCSessionEvents) AddAccessToken(ctx context.Context, projectID string, scope []string, reason domain.TokenReason, actor *domain.TokenActor) error {
|
||||
accessTokenID, err := c.idGenerator.Next()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.accessTokenID = AccessTokenPrefix + accessTokenID
|
||||
c.events = append(c.events, oidcsession.NewAccessTokenAddedEvent(ctx, c.oidcSessionWriteModel.aggregate, c.accessTokenID, scope, c.accessTokenLifetime, reason, actor))
|
||||
c.events = append(c.events, oidcsession.NewAccessTokenAddedEvent(ctx, c.oidcSessionWriteModel.aggregate, c.accessTokenID, projectID, scope, c.accessTokenLifetime, reason, actor))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ type OIDCSessionWriteModel struct {
|
||||
UserID string
|
||||
SessionID string
|
||||
ClientID string
|
||||
ProjectID string
|
||||
Audience []string
|
||||
Scope []string
|
||||
AuthMethods []domain.UserAuthMethodType
|
||||
@@ -101,6 +102,7 @@ func (wm *OIDCSessionWriteModel) reduceAdded(e *oidcsession.AddedEvent) {
|
||||
|
||||
func (wm *OIDCSessionWriteModel) reduceAccessTokenAdded(e *oidcsession.AccessTokenAddedEvent) {
|
||||
wm.AccessTokenID = e.ID
|
||||
wm.ProjectID = e.ProjectID
|
||||
wm.AccessTokenExpiration = e.CreationDate().Add(e.Lifetime)
|
||||
wm.AccessTokenReason = e.Reason
|
||||
wm.AccessTokenActor = e.Actor
|
||||
|
||||
@@ -196,7 +196,7 @@ func TestCommands_AddOIDCSessionAccessToken(t *testing.T) {
|
||||
oidcsession.NewAddedEvent(context.Background(), &oidcsession.NewAggregate("V2_oidcSessionID", "org1").Aggregate,
|
||||
"userID", "sessionID", "clientID", []string{"audience"}, []string{"openid"}, []domain.UserAuthMethodType{domain.UserAuthMethodTypePassword}, testNow),
|
||||
oidcsession.NewAccessTokenAddedEvent(context.Background(), &oidcsession.NewAggregate("V2_oidcSessionID", "org1").Aggregate,
|
||||
"at_accessTokenID", []string{"openid"}, time.Hour, domain.TokenReasonAuthRequest, nil),
|
||||
"at_accessTokenID", "projectID", []string{"openid"}, time.Hour, domain.TokenReasonAuthRequest, nil),
|
||||
authrequest.NewSucceededEvent(context.Background(), &authrequest.NewAggregate("V2_authRequestID", "instanceID").Aggregate),
|
||||
),
|
||||
),
|
||||
@@ -223,7 +223,7 @@ func TestCommands_AddOIDCSessionAccessToken(t *testing.T) {
|
||||
defaultRefreshTokenIdleLifetime: tt.fields.defaultRefreshTokenIdleLifetime,
|
||||
keyAlgorithm: tt.fields.keyAlgorithm,
|
||||
}
|
||||
gotID, gotExpiration, err := c.AddOIDCSessionAccessToken(tt.args.ctx, tt.args.authRequestID)
|
||||
gotID, gotExpiration, err := c.AddOIDCSessionAccessToken(tt.args.ctx, tt.args.authRequestID, "projectID")
|
||||
assert.Equal(t, tt.res.id, gotID)
|
||||
assert.Equal(t, tt.res.expiration, gotExpiration)
|
||||
assert.ErrorIs(t, err, tt.res.err)
|
||||
@@ -397,7 +397,7 @@ func TestCommands_AddOIDCSessionRefreshAndAccessToken(t *testing.T) {
|
||||
oidcsession.NewAddedEvent(context.Background(), &oidcsession.NewAggregate("V2_oidcSessionID", "org1").Aggregate,
|
||||
"userID", "sessionID", "clientID", []string{"audience"}, []string{"openid", "offline_access"}, []domain.UserAuthMethodType{domain.UserAuthMethodTypePassword}, testNow),
|
||||
oidcsession.NewAccessTokenAddedEvent(context.Background(), &oidcsession.NewAggregate("V2_oidcSessionID", "org1").Aggregate,
|
||||
"at_accessTokenID", []string{"openid", "offline_access"}, time.Hour, domain.TokenReasonAuthRequest, nil),
|
||||
"at_accessTokenID", "projectID", []string{"openid", "offline_access"}, time.Hour, domain.TokenReasonAuthRequest, nil),
|
||||
oidcsession.NewRefreshTokenAddedEvent(context.Background(), &oidcsession.NewAggregate("V2_oidcSessionID", "org1").Aggregate,
|
||||
"rt_refreshTokenID", 7*24*time.Hour, 24*time.Hour),
|
||||
authrequest.NewSucceededEvent(context.Background(), &authrequest.NewAggregate("V2_authRequestID", "instanceID").Aggregate),
|
||||
@@ -430,7 +430,7 @@ func TestCommands_AddOIDCSessionRefreshAndAccessToken(t *testing.T) {
|
||||
defaultRefreshTokenIdleLifetime: tt.fields.defaultRefreshTokenIdleLifetime,
|
||||
keyAlgorithm: tt.fields.keyAlgorithm,
|
||||
}
|
||||
gotID, gotRefreshToken, gotExpiration, err := c.AddOIDCSessionRefreshAndAccessToken(tt.args.ctx, tt.args.authRequestID)
|
||||
gotID, gotRefreshToken, gotExpiration, err := c.AddOIDCSessionRefreshAndAccessToken(tt.args.ctx, tt.args.authRequestID, "projectID")
|
||||
assert.Equal(t, tt.res.id, gotID)
|
||||
assert.Equal(t, tt.res.refreshToken, gotRefreshToken)
|
||||
assert.Equal(t, tt.res.expiration, gotExpiration)
|
||||
@@ -509,7 +509,7 @@ func TestCommands_ExchangeOIDCSessionRefreshAndAccessToken(t *testing.T) {
|
||||
),
|
||||
eventFromEventPusher(
|
||||
oidcsession.NewAccessTokenAddedEvent(context.Background(), &oidcsession.NewAggregate("V2_oidcSessionID", "org1").Aggregate,
|
||||
"accessTokenID", []string{"openid", "profile", "offline_access"}, time.Hour, domain.TokenReasonAuthRequest, nil),
|
||||
"accessTokenID", "projectID", []string{"openid", "profile", "offline_access"}, time.Hour, domain.TokenReasonAuthRequest, nil),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -535,7 +535,7 @@ func TestCommands_ExchangeOIDCSessionRefreshAndAccessToken(t *testing.T) {
|
||||
),
|
||||
eventFromEventPusher(
|
||||
oidcsession.NewAccessTokenAddedEvent(context.Background(), &oidcsession.NewAggregate("V2_oidcSessionID", "org1").Aggregate,
|
||||
"at_accessTokenID", []string{"openid", "profile", "offline_access"}, time.Hour, domain.TokenReasonAuthRequest, nil),
|
||||
"at_accessTokenID", "projectID", []string{"openid", "profile", "offline_access"}, time.Hour, domain.TokenReasonAuthRequest, nil),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
oidcsession.NewRefreshTokenAddedEvent(context.Background(), &oidcsession.NewAggregate("V2_oidcSessionID", "org1").Aggregate,
|
||||
@@ -565,7 +565,7 @@ func TestCommands_ExchangeOIDCSessionRefreshAndAccessToken(t *testing.T) {
|
||||
),
|
||||
eventFromEventPusherWithCreationDateNow(
|
||||
oidcsession.NewAccessTokenAddedEvent(context.Background(), &oidcsession.NewAggregate("V2_oidcSessionID", "org1").Aggregate,
|
||||
"at_accessTokenID", []string{"openid", "profile", "offline_access"}, time.Hour, domain.TokenReasonAuthRequest, nil),
|
||||
"at_accessTokenID", "projectID", []string{"openid", "profile", "offline_access"}, time.Hour, domain.TokenReasonAuthRequest, nil),
|
||||
),
|
||||
eventFromEventPusherWithCreationDateNow(
|
||||
oidcsession.NewRefreshTokenAddedEvent(context.Background(), &oidcsession.NewAggregate("V2_oidcSessionID", "org1").Aggregate,
|
||||
@@ -575,7 +575,7 @@ func TestCommands_ExchangeOIDCSessionRefreshAndAccessToken(t *testing.T) {
|
||||
expectFilter(), // token lifetime
|
||||
expectPush(
|
||||
oidcsession.NewAccessTokenAddedEvent(context.Background(), &oidcsession.NewAggregate("V2_oidcSessionID", "org1").Aggregate,
|
||||
"at_accessTokenID", []string{"openid", "offline_access"}, time.Hour, domain.TokenReasonRefresh, nil),
|
||||
"at_accessTokenID", "projectID", []string{"openid", "offline_access"}, time.Hour, domain.TokenReasonRefresh, nil),
|
||||
oidcsession.NewRefreshTokenRenewedEvent(context.Background(), &oidcsession.NewAggregate("V2_oidcSessionID", "org1").Aggregate,
|
||||
"rt_refreshTokenID2", 24*time.Hour),
|
||||
),
|
||||
@@ -682,7 +682,7 @@ func TestCommands_OIDCSessionByRefreshToken(t *testing.T) {
|
||||
),
|
||||
eventFromEventPusher(
|
||||
oidcsession.NewAccessTokenAddedEvent(context.Background(), &oidcsession.NewAggregate("V2_oidcSessionID", "org1").Aggregate,
|
||||
"at_accessTokenID", []string{"openid", "profile", "offline_access"}, time.Hour, domain.TokenReasonAuthRequest, nil),
|
||||
"at_accessTokenID", "projectID", []string{"openid", "profile", "offline_access"}, time.Hour, domain.TokenReasonAuthRequest, nil),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -707,7 +707,7 @@ func TestCommands_OIDCSessionByRefreshToken(t *testing.T) {
|
||||
),
|
||||
eventFromEventPusher(
|
||||
oidcsession.NewAccessTokenAddedEvent(context.Background(), &oidcsession.NewAggregate("V2_oidcSessionID", "org1").Aggregate,
|
||||
"at_accessTokenID", []string{"openid", "profile", "offline_access"}, time.Hour, domain.TokenReasonAuthRequest, nil),
|
||||
"at_accessTokenID", "projectID", []string{"openid", "profile", "offline_access"}, time.Hour, domain.TokenReasonAuthRequest, nil),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
oidcsession.NewRefreshTokenAddedEvent(context.Background(), &oidcsession.NewAggregate("V2_oidcSessionID", "org1").Aggregate,
|
||||
@@ -736,7 +736,7 @@ func TestCommands_OIDCSessionByRefreshToken(t *testing.T) {
|
||||
),
|
||||
eventFromEventPusherWithCreationDateNow(
|
||||
oidcsession.NewAccessTokenAddedEvent(context.Background(), &oidcsession.NewAggregate("V2_oidcSessionID", "org1").Aggregate,
|
||||
"at_accessTokenID", []string{"openid", "profile", "offline_access"}, time.Hour, domain.TokenReasonAuthRequest, nil),
|
||||
"at_accessTokenID", "projectID", []string{"openid", "profile", "offline_access"}, time.Hour, domain.TokenReasonAuthRequest, nil),
|
||||
),
|
||||
eventFromEventPusherWithCreationDateNow(
|
||||
oidcsession.NewRefreshTokenAddedEvent(context.Background(), &oidcsession.NewAggregate("V2_oidcSessionID", "org1").Aggregate,
|
||||
@@ -892,7 +892,7 @@ func TestCommands_RevokeOIDCSessionToken(t *testing.T) {
|
||||
),
|
||||
eventFromEventPusherWithCreationDateNow(
|
||||
oidcsession.NewAccessTokenAddedEvent(context.Background(), &oidcsession.NewAggregate("V2_oidcSessionID", "org1").Aggregate,
|
||||
"at_accessTokenID", []string{"openid", "profile", "offline_access"}, time.Hour, domain.TokenReasonAuthRequest, nil),
|
||||
"at_accessTokenID", "projectID", []string{"openid", "profile", "offline_access"}, time.Hour, domain.TokenReasonAuthRequest, nil),
|
||||
),
|
||||
eventFromEventPusherWithCreationDateNow(
|
||||
oidcsession.NewRefreshTokenAddedEvent(context.Background(), &oidcsession.NewAggregate("V2_oidcSessionID", "org1").Aggregate,
|
||||
@@ -969,7 +969,7 @@ func TestCommands_RevokeOIDCSessionToken(t *testing.T) {
|
||||
),
|
||||
eventFromEventPusherWithCreationDateNow(
|
||||
oidcsession.NewAccessTokenAddedEvent(context.Background(), &oidcsession.NewAggregate("V2_oidcSessionID", "org1").Aggregate,
|
||||
"at_accessTokenID", []string{"openid", "profile", "offline_access"}, time.Hour, domain.TokenReasonAuthRequest, nil),
|
||||
"at_accessTokenID", "projectID", []string{"openid", "profile", "offline_access"}, time.Hour, domain.TokenReasonAuthRequest, nil),
|
||||
),
|
||||
eventFromEventPusherWithCreationDateNow(
|
||||
oidcsession.NewRefreshTokenAddedEvent(context.Background(), &oidcsession.NewAggregate("V2_oidcSessionID", "org1").Aggregate,
|
||||
|
||||
@@ -237,6 +237,7 @@ func (c *Commands) AddUserToken(
|
||||
orgID,
|
||||
agentID,
|
||||
clientID,
|
||||
projectID,
|
||||
userID string,
|
||||
audience,
|
||||
scopes,
|
||||
@@ -250,7 +251,7 @@ func (c *Commands) AddUserToken(
|
||||
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-Dbge4", "Errors.IDMissing")
|
||||
}
|
||||
userWriteModel := NewUserWriteModel(userID, orgID)
|
||||
cmds, accessToken, err := c.addUserToken(ctx, userWriteModel, agentID, clientID, "", audience, scopes, authMethodsReferences, lifetime, authTime, reason, actor)
|
||||
cmds, accessToken, err := c.addUserToken(ctx, userWriteModel, agentID, clientID, projectID, "", audience, scopes, authMethodsReferences, lifetime, authTime, reason, actor)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -277,7 +278,7 @@ func (c *Commands) RevokeAccessToken(ctx context.Context, userID, orgID, tokenID
|
||||
return writeModelToObjectDetails(&accessTokenWriteModel.WriteModel), nil
|
||||
}
|
||||
|
||||
func (c *Commands) addUserToken(ctx context.Context, userWriteModel *UserWriteModel, agentID, clientID, refreshTokenID string, audience, scopes, authMethodsReferences []string, lifetime time.Duration, authTime time.Time, reason domain.TokenReason, actor *domain.TokenActor) ([]eventstore.Command, *domain.Token, error) {
|
||||
func (c *Commands) addUserToken(ctx context.Context, userWriteModel *UserWriteModel, agentID, clientID, projectID, refreshTokenID string, audience, scopes, authMethodsReferences []string, lifetime time.Duration, authTime time.Time, reason domain.TokenReason, actor *domain.TokenActor) ([]eventstore.Command, *domain.Token, error) {
|
||||
err := c.eventstore.FilterToQueryReducer(ctx, userWriteModel)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -312,7 +313,7 @@ func (c *Commands) addUserToken(ctx context.Context, userWriteModel *UserWriteMo
|
||||
}
|
||||
|
||||
cmds = append(cmds,
|
||||
user.NewUserTokenAddedEvent(ctx, userAgg, tokenID, clientID, agentID, preferredLanguage, refreshTokenID, audience, scopes, authMethodsReferences, authTime, expiration, reason, actor),
|
||||
user.NewUserTokenAddedEvent(ctx, userAgg, tokenID, clientID, projectID, agentID, preferredLanguage, refreshTokenID, audience, scopes, authMethodsReferences, authTime, expiration, reason, actor),
|
||||
)
|
||||
|
||||
return cmds, &domain.Token{
|
||||
|
||||
@@ -13,6 +13,7 @@ type UserAccessTokenWriteModel struct {
|
||||
|
||||
TokenID string
|
||||
ApplicationID string
|
||||
ProjectID string
|
||||
UserAgentID string
|
||||
Audience []string
|
||||
Scopes []string
|
||||
@@ -66,6 +67,7 @@ func (wm *UserAccessTokenWriteModel) Reduce() error {
|
||||
case *user.UserTokenAddedEvent:
|
||||
wm.TokenID = e.TokenID
|
||||
wm.ApplicationID = e.ApplicationID
|
||||
wm.ProjectID = e.ProjectID
|
||||
wm.UserAgentID = e.UserAgentID
|
||||
wm.Audience = e.Audience
|
||||
wm.Scopes = e.Scopes
|
||||
|
||||
@@ -15,6 +15,7 @@ func (c *Commands) AddAccessAndRefreshToken(
|
||||
orgID,
|
||||
agentID,
|
||||
clientID,
|
||||
projectID,
|
||||
userID,
|
||||
refreshToken string,
|
||||
audience,
|
||||
@@ -28,9 +29,9 @@ func (c *Commands) AddAccessAndRefreshToken(
|
||||
actor *domain.TokenActor,
|
||||
) (accessToken *domain.Token, newRefreshToken string, err error) {
|
||||
if refreshToken == "" {
|
||||
return c.AddNewRefreshTokenAndAccessToken(ctx, userID, orgID, agentID, clientID, audience, scopes, authMethodsReferences, refreshExpiration, accessLifetime, refreshIdleExpiration, authTime, reason, actor)
|
||||
return c.AddNewRefreshTokenAndAccessToken(ctx, userID, orgID, agentID, clientID, projectID, audience, scopes, authMethodsReferences, refreshExpiration, accessLifetime, refreshIdleExpiration, authTime, reason, actor)
|
||||
}
|
||||
return c.RenewRefreshTokenAndAccessToken(ctx, userID, orgID, refreshToken, agentID, clientID, audience, scopes, refreshIdleExpiration, accessLifetime, actor)
|
||||
return c.RenewRefreshTokenAndAccessToken(ctx, userID, orgID, refreshToken, agentID, clientID, projectID, audience, scopes, refreshIdleExpiration, accessLifetime, actor)
|
||||
}
|
||||
|
||||
func (c *Commands) AddNewRefreshTokenAndAccessToken(
|
||||
@@ -38,7 +39,8 @@ func (c *Commands) AddNewRefreshTokenAndAccessToken(
|
||||
userID,
|
||||
orgID,
|
||||
agentID,
|
||||
clientID string,
|
||||
clientID,
|
||||
projectID string,
|
||||
audience,
|
||||
scopes,
|
||||
authMethodsReferences []string,
|
||||
@@ -57,7 +59,7 @@ func (c *Commands) AddNewRefreshTokenAndAccessToken(
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
cmds, accessToken, err := c.addUserToken(ctx, userWriteModel, agentID, clientID, refreshTokenID, audience, scopes, authMethodsReferences, accessLifetime, authTime, reason, actor)
|
||||
cmds, accessToken, err := c.addUserToken(ctx, userWriteModel, agentID, clientID, projectID, refreshTokenID, audience, scopes, authMethodsReferences, accessLifetime, authTime, reason, actor)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
@@ -79,7 +81,8 @@ func (c *Commands) RenewRefreshTokenAndAccessToken(
|
||||
orgID,
|
||||
refreshToken,
|
||||
agentID,
|
||||
clientID string,
|
||||
clientID,
|
||||
projectID string,
|
||||
audience,
|
||||
scopes []string,
|
||||
idleExpiration,
|
||||
@@ -91,7 +94,7 @@ func (c *Commands) RenewRefreshTokenAndAccessToken(
|
||||
return nil, "", err
|
||||
}
|
||||
userWriteModel := NewUserWriteModel(userID, orgID)
|
||||
cmds, accessToken, err := c.addUserToken(ctx, userWriteModel, agentID, clientID, renewed.tokenID, audience, scopes, renewed.authMethodsReferences, accessLifetime, renewed.authTime, domain.TokenReasonRefresh, actor)
|
||||
cmds, accessToken, err := c.addUserToken(ctx, userWriteModel, agentID, clientID, projectID, renewed.tokenID, audience, scopes, renewed.authMethodsReferences, accessLifetime, renewed.authTime, domain.TokenReasonRefresh, actor)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
@@ -296,7 +296,7 @@ func TestCommands_AddAccessAndRefreshToken(t *testing.T) {
|
||||
idGenerator: tt.fields.idGenerator,
|
||||
keyAlgorithm: tt.fields.keyAlgorithm,
|
||||
}
|
||||
got, gotRefresh, err := c.AddAccessAndRefreshToken(tt.args.ctx, tt.args.orgID, tt.args.agentID, tt.args.clientID, tt.args.userID, tt.args.refreshToken,
|
||||
got, gotRefresh, err := c.AddAccessAndRefreshToken(tt.args.ctx, tt.args.orgID, tt.args.agentID, tt.args.clientID, "projectID", tt.args.userID, tt.args.refreshToken,
|
||||
tt.args.audience, tt.args.scopes, tt.args.authMethodsReferences, tt.args.lifetime, tt.args.refreshIdleExpiration, tt.args.refreshExpiration, tt.args.authTime, tt.args.reason, tt.args.actor)
|
||||
if tt.res.err == nil {
|
||||
assert.NoError(t, err)
|
||||
|
||||
@@ -1504,7 +1504,7 @@ func TestCommandSide_AddUserToken(t *testing.T) {
|
||||
eventstore: tt.fields.eventstore,
|
||||
idGenerator: tt.fields.idGenerator,
|
||||
}
|
||||
got, err := r.AddUserToken(tt.args.ctx, tt.args.orgID, tt.args.agentID, tt.args.clientID, tt.args.userID, tt.args.audience, tt.args.scopes, tt.args.authMethodsReferences, tt.args.lifetime, tt.args.authTime, tt.args.reason, tt.args.actor)
|
||||
got, err := r.AddUserToken(tt.args.ctx, tt.args.orgID, tt.args.agentID, tt.args.clientID, "projectID", tt.args.userID, tt.args.audience, tt.args.scopes, tt.args.authMethodsReferences, tt.args.lifetime, tt.args.authTime, tt.args.reason, tt.args.actor)
|
||||
if tt.res.err == nil {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
@@ -1564,6 +1564,7 @@ func TestCommands_RevokeAccessToken(t *testing.T) {
|
||||
&user.NewAggregate("userID", "orgID").Aggregate,
|
||||
"tokenID",
|
||||
"clientID",
|
||||
"projectID",
|
||||
"agentID",
|
||||
"de",
|
||||
"refreshTokenID",
|
||||
@@ -1600,6 +1601,7 @@ func TestCommands_RevokeAccessToken(t *testing.T) {
|
||||
&user.NewAggregate("userID", "orgID").Aggregate,
|
||||
"tokenID",
|
||||
"clientID",
|
||||
"projectID",
|
||||
"agentID",
|
||||
"de",
|
||||
"refreshTokenID",
|
||||
|
||||
@@ -20,6 +20,7 @@ type OIDCSessionAccessTokenReadModel struct {
|
||||
UserID string
|
||||
SessionID string
|
||||
ClientID string
|
||||
ProjectID string
|
||||
Audience []string
|
||||
Scope []string
|
||||
AuthMethods []domain.UserAuthMethodType
|
||||
@@ -84,6 +85,7 @@ func (wm *OIDCSessionAccessTokenReadModel) reduceAdded(e *oidcsession.AddedEvent
|
||||
|
||||
func (wm *OIDCSessionAccessTokenReadModel) reduceAccessTokenAdded(e *oidcsession.AccessTokenAddedEvent) {
|
||||
wm.AccessTokenID = e.ID
|
||||
wm.ProjectID = e.ProjectID
|
||||
wm.AccessTokenCreation = e.CreationDate()
|
||||
wm.AccessTokenExpiration = e.CreationDate().Add(e.Lifetime)
|
||||
wm.Reason = e.Reason
|
||||
|
||||
@@ -24,6 +24,7 @@ type AddedEvent struct {
|
||||
|
||||
LoginClient string `json:"login_client"`
|
||||
ClientID string `json:"client_id"`
|
||||
ProjectID string `json:"project_id"`
|
||||
RedirectURI string `json:"redirect_uri"`
|
||||
State string `json:"state,omitempty"`
|
||||
Nonce string `json:"nonce,omitempty"`
|
||||
|
||||
@@ -22,7 +22,7 @@ type AddedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
|
||||
UserID string `json:"userID"`
|
||||
SessionID string `json:"sessionID"`
|
||||
SessionID string `json:"sessionID,omitempty"`
|
||||
ClientID string `json:"clientID"`
|
||||
Audience []string `json:"audience"`
|
||||
Scope []string `json:"scope"`
|
||||
@@ -71,11 +71,12 @@ func NewAddedEvent(ctx context.Context,
|
||||
type AccessTokenAddedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
|
||||
ID string `json:"id,omitempty"`
|
||||
Scope []string `json:"scope,omitempty"`
|
||||
Lifetime time.Duration `json:"lifetime,omitempty"`
|
||||
Reason domain.TokenReason `json:"reason,omitempty"`
|
||||
Actor *domain.TokenActor `json:"actor,omitempty"`
|
||||
ID string `json:"id,omitempty"`
|
||||
ProjectID string `json:"project_id,omitempty"`
|
||||
Scope []string `json:"scope,omitempty"`
|
||||
Lifetime time.Duration `json:"lifetime,omitempty"`
|
||||
Reason domain.TokenReason `json:"reason,omitempty"`
|
||||
Actor *domain.TokenActor `json:"actor,omitempty"`
|
||||
}
|
||||
|
||||
func (e *AccessTokenAddedEvent) Payload() interface{} {
|
||||
@@ -93,7 +94,8 @@ func (e *AccessTokenAddedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||
func NewAccessTokenAddedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
id string,
|
||||
id,
|
||||
projectID string,
|
||||
scope []string,
|
||||
lifetime time.Duration,
|
||||
reason domain.TokenReason,
|
||||
@@ -105,11 +107,12 @@ func NewAccessTokenAddedEvent(
|
||||
aggregate,
|
||||
AccessTokenAddedType,
|
||||
),
|
||||
ID: id,
|
||||
Scope: scope,
|
||||
Lifetime: lifetime,
|
||||
Reason: reason,
|
||||
Actor: actor,
|
||||
ID: id,
|
||||
ProjectID: projectID,
|
||||
Scope: scope,
|
||||
Lifetime: lifetime,
|
||||
Reason: reason,
|
||||
Actor: actor,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -212,6 +212,7 @@ type UserTokenAddedEvent struct {
|
||||
|
||||
TokenID string `json:"tokenId,omitempty"`
|
||||
ApplicationID string `json:"applicationId,omitempty"`
|
||||
ProjectID string `json:"projectID,omitempty"`
|
||||
UserAgentID string `json:"userAgentId,omitempty"`
|
||||
RefreshTokenID string `json:"refreshTokenID,omitempty"`
|
||||
Audience []string `json:"audience,omitempty"`
|
||||
@@ -237,6 +238,7 @@ func NewUserTokenAddedEvent(
|
||||
aggregate *eventstore.Aggregate,
|
||||
tokenID,
|
||||
applicationID,
|
||||
projectID,
|
||||
userAgentID,
|
||||
preferredLanguage,
|
||||
refreshTokenID string,
|
||||
@@ -256,6 +258,7 @@ func NewUserTokenAddedEvent(
|
||||
),
|
||||
TokenID: tokenID,
|
||||
ApplicationID: applicationID,
|
||||
ProjectID: projectID,
|
||||
UserAgentID: userAgentID,
|
||||
RefreshTokenID: refreshTokenID,
|
||||
Audience: audience,
|
||||
|
||||
@@ -14,6 +14,7 @@ type TokenView struct {
|
||||
ResourceOwner string
|
||||
UserID string
|
||||
ApplicationID string
|
||||
ProjectID string
|
||||
UserAgentID string
|
||||
Audience []string
|
||||
Expiration time.Time
|
||||
|
||||
@@ -33,6 +33,7 @@ type TokenView struct {
|
||||
ResourceOwner string `json:"-" gorm:"column:resource_owner"`
|
||||
UserID string `json:"-" gorm:"column:user_id"`
|
||||
ApplicationID string `json:"applicationId" gorm:"column:application_id"`
|
||||
ProjectID string `json:"projectID" gorm:"column:project_id"`
|
||||
UserAgentID string `json:"userAgentId" gorm:"column:user_agent_id"`
|
||||
Audience database.TextArray[string] `json:"audience" gorm:"column:audience"`
|
||||
Scopes database.TextArray[string] `json:"scopes" gorm:"column:scopes"`
|
||||
@@ -87,6 +88,7 @@ func TokenViewToModel(token *TokenView) *usr_model.TokenView {
|
||||
ResourceOwner: token.ResourceOwner,
|
||||
UserID: token.UserID,
|
||||
ApplicationID: token.ApplicationID,
|
||||
ProjectID: token.ProjectID,
|
||||
UserAgentID: token.UserAgentID,
|
||||
Audience: token.Audience,
|
||||
Scopes: token.Scopes,
|
||||
|
||||
Reference in New Issue
Block a user