mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 19:07:30 +00:00
feat: allow session deletion without session token (#6889)
* fix: add resource owner of user and change the one of session to instance * use user resource owner from session projection * fix session permission check * integration tests and fixes * update api docs
This commit is contained in:
@@ -55,12 +55,12 @@ func (c *Commands) NewSessionCommands(cmds []SessionCommand, session *SessionWri
|
||||
}
|
||||
|
||||
// CheckUser defines a user check to be executed for a session update
|
||||
func CheckUser(id string) SessionCommand {
|
||||
func CheckUser(id string, resourceOwner string) SessionCommand {
|
||||
return func(ctx context.Context, cmd *SessionCommands) error {
|
||||
if cmd.sessionWriteModel.UserID != "" && id != "" && cmd.sessionWriteModel.UserID != id {
|
||||
return caos_errs.ThrowInvalidArgument(nil, "", "user change not possible")
|
||||
}
|
||||
return cmd.UserChecked(ctx, id, cmd.now())
|
||||
return cmd.UserChecked(ctx, id, resourceOwner, cmd.now())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,10 +170,11 @@ func (s *SessionCommands) Start(ctx context.Context, userAgent *domain.UserAgent
|
||||
s.eventCommands = append(s.eventCommands, session.NewAddedEvent(ctx, s.sessionWriteModel.aggregate, userAgent))
|
||||
}
|
||||
|
||||
func (s *SessionCommands) UserChecked(ctx context.Context, userID string, checkedAt time.Time) error {
|
||||
s.eventCommands = append(s.eventCommands, session.NewUserCheckedEvent(ctx, s.sessionWriteModel.aggregate, userID, checkedAt))
|
||||
func (s *SessionCommands) UserChecked(ctx context.Context, userID, resourceOwner string, checkedAt time.Time) error {
|
||||
s.eventCommands = append(s.eventCommands, session.NewUserCheckedEvent(ctx, s.sessionWriteModel.aggregate, userID, resourceOwner, checkedAt))
|
||||
// set the userID so other checks can use it
|
||||
s.sessionWriteModel.UserID = userID
|
||||
s.sessionWriteModel.UserResourceOwner = resourceOwner
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -267,7 +268,7 @@ func (s *SessionCommands) gethumanWriteModel(ctx context.Context) (*HumanWriteMo
|
||||
if s.sessionWriteModel.UserID == "" {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-eeR2e", "Errors.User.UserIDMissing")
|
||||
}
|
||||
humanWriteModel := NewHumanWriteModel(s.sessionWriteModel.UserID, "")
|
||||
humanWriteModel := NewHumanWriteModel(s.sessionWriteModel.UserID, s.sessionWriteModel.UserResourceOwner)
|
||||
err := s.eventstore.FilterToQueryReducer(ctx, humanWriteModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -296,7 +297,7 @@ func (c *Commands) CreateSession(ctx context.Context, cmds []SessionCommand, met
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sessionWriteModel := NewSessionWriteModel(sessionID, authz.GetCtxData(ctx).OrgID)
|
||||
sessionWriteModel := NewSessionWriteModel(sessionID, authz.GetInstance(ctx).InstanceID())
|
||||
err = c.eventstore.FilterToQueryReducer(ctx, sessionWriteModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -307,12 +308,12 @@ func (c *Commands) CreateSession(ctx context.Context, cmds []SessionCommand, met
|
||||
}
|
||||
|
||||
func (c *Commands) UpdateSession(ctx context.Context, sessionID, sessionToken string, cmds []SessionCommand, metadata map[string][]byte, lifetime time.Duration) (set *SessionChanged, err error) {
|
||||
sessionWriteModel := NewSessionWriteModel(sessionID, authz.GetCtxData(ctx).OrgID)
|
||||
sessionWriteModel := NewSessionWriteModel(sessionID, authz.GetInstance(ctx).InstanceID())
|
||||
err = c.eventstore.FilterToQueryReducer(ctx, sessionWriteModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := c.sessionPermission(ctx, sessionWriteModel, sessionToken, domain.PermissionSessionWrite); err != nil {
|
||||
if err := c.sessionTokenVerifier(ctx, sessionToken, sessionWriteModel.AggregateID, sessionWriteModel.TokenID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmd := c.NewSessionCommands(cmds, sessionWriteModel)
|
||||
@@ -328,12 +329,12 @@ func (c *Commands) TerminateSessionWithoutTokenCheck(ctx context.Context, sessio
|
||||
}
|
||||
|
||||
func (c *Commands) terminateSession(ctx context.Context, sessionID, sessionToken string, mustCheckToken bool) (*domain.ObjectDetails, error) {
|
||||
sessionWriteModel := NewSessionWriteModel(sessionID, "")
|
||||
sessionWriteModel := NewSessionWriteModel(sessionID, authz.GetInstance(ctx).InstanceID())
|
||||
if err := c.eventstore.FilterToQueryReducer(ctx, sessionWriteModel); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if mustCheckToken {
|
||||
if err := c.sessionPermission(ctx, sessionWriteModel, sessionToken, domain.PermissionSessionDelete); err != nil {
|
||||
if err := c.checkSessionTerminationPermission(ctx, sessionWriteModel, sessionToken); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -386,13 +387,17 @@ func (c *Commands) updateSession(ctx context.Context, checks *SessionCommands, m
|
||||
return changed, nil
|
||||
}
|
||||
|
||||
// sessionPermission will check that the provided sessionToken is correct or
|
||||
// if empty, check that the caller is granted the necessary permission
|
||||
func (c *Commands) sessionPermission(ctx context.Context, sessionWriteModel *SessionWriteModel, sessionToken, permission string) (err error) {
|
||||
if sessionToken == "" {
|
||||
return c.checkPermission(ctx, permission, authz.GetCtxData(ctx).OrgID, sessionWriteModel.AggregateID)
|
||||
// checkSessionTerminationPermission will check that the provided sessionToken is correct or
|
||||
// if empty, check that the caller is either terminating the own session or
|
||||
// is granted the "session.delete" permission on the resource owner of the authenticated user.
|
||||
func (c *Commands) checkSessionTerminationPermission(ctx context.Context, model *SessionWriteModel, token string) error {
|
||||
if token != "" {
|
||||
return c.sessionTokenVerifier(ctx, token, model.AggregateID, model.TokenID)
|
||||
}
|
||||
return c.sessionTokenVerifier(ctx, sessionToken, sessionWriteModel.AggregateID, sessionWriteModel.TokenID)
|
||||
if model.UserID != "" && model.UserID == authz.GetCtxData(ctx).UserID {
|
||||
return nil
|
||||
}
|
||||
return c.checkPermission(ctx, domain.PermissionSessionDelete, model.UserResourceOwner, model.UserID)
|
||||
}
|
||||
|
||||
func sessionTokenCreator(idGenerator id.Generator, sessionAlg crypto.EncryptionAlgorithm) func(sessionID string) (id string, token string, err error) {
|
||||
|
Reference in New Issue
Block a user