feat: on logout we terminate all sessions from agent (#288)

* feat: on logout we terminate all sessions from agent

* Update eventstore.go

Co-authored-by: Livio Amstutz <livio.a@gmail.com>
This commit is contained in:
Fabi
2020-06-29 09:49:40 +02:00
committed by GitHub
parent 509a993d31
commit 79eff2795f
5 changed files with 40 additions and 20 deletions

View File

@@ -227,8 +227,16 @@ func (repo *UserRepo) SetPassword(ctx context.Context, userID, code, password st
return repo.UserEvents.SetPassword(ctx, policy, userID, code, password) return repo.UserEvents.SetPassword(ctx, policy, userID, code, password)
} }
func (repo *UserRepo) SignOut(ctx context.Context, agentID, userID string) error { func (repo *UserRepo) SignOut(ctx context.Context, agentID string) error {
return repo.UserEvents.SignOut(ctx, agentID, userID) userSessions, err := repo.View.UserSessionsByAgentID(agentID)
if err != nil {
return err
}
userIDs := make([]string, len(userSessions))
for i, session := range userSessions {
userIDs[i] = session.UserID
}
return repo.UserEvents.SignOut(ctx, agentID, userIDs)
} }
func (repo *UserRepo) UserByID(ctx context.Context, id string) (*model.UserView, error) { func (repo *UserRepo) UserByID(ctx context.Context, id string) (*model.UserView, error) {

View File

@@ -23,7 +23,7 @@ type UserRepository interface {
AddMfaOTP(ctx context.Context, userID string) (*model.OTP, error) AddMfaOTP(ctx context.Context, userID string) (*model.OTP, error)
VerifyMfaOTPSetup(ctx context.Context, userID, code string) error VerifyMfaOTPSetup(ctx context.Context, userID, code string) error
SignOut(ctx context.Context, agentID, userID string) error SignOut(ctx context.Context, agentID string) error
UserByID(ctx context.Context, userID string) (*model.UserView, error) UserByID(ctx context.Context, userID string) (*model.UserView, error)
} }

View File

@@ -1049,17 +1049,24 @@ func (es *UserEventstore) verifyMfaOTP(otp *usr_model.OTP, code string) error {
return nil return nil
} }
func (es *UserEventstore) SignOut(ctx context.Context, agentID, userID string) error { func (es *UserEventstore) SignOut(ctx context.Context, agentID string, userIDs []string) error {
user, err := es.UserByID(ctx, userID) users := make([]*model.User, len(userIDs))
if err != nil { for i, id := range userIDs {
return err user, err := es.UserByID(ctx, id)
} if err != nil {
repoUser := model.UserFromModel(user) return err
err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, SignOutAggregate(es.AggregateCreator(), repoUser, agentID)) }
if err != nil { users[i] = model.UserFromModel(user)
return err
} }
es.userCache.cacheUser(repoUser) aggFunc := SignOutAggregates(es.AggregateCreator(), users, agentID)
aggregates, err := aggFunc(ctx)
if err != nil {
return err
}
err = es_sdk.PushAggregates(ctx, es.PushAggregates, nil, aggregates...)
if err != nil {
return err
}
return nil return nil
} }

View File

@@ -630,13 +630,18 @@ func MfaOTPRemoveAggregate(aggCreator *es_models.AggregateCreator, existing *mod
} }
} }
func SignOutAggregate(aggCreator *es_models.AggregateCreator, existing *model.User, agentID string) func(ctx context.Context) (*es_models.Aggregate, error) { func SignOutAggregates(aggCreator *es_models.AggregateCreator, existingUsers []*model.User, agentID string) func(ctx context.Context) ([]*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) { return func(ctx context.Context) ([]*es_models.Aggregate, error) {
agg, err := UserAggregateOverwriteContext(ctx, aggCreator, existing, existing.ResourceOwner, existing.AggregateID) aggregates := make([]*es_models.Aggregate, len(existingUsers))
if err != nil { for i, existing := range existingUsers {
return nil, err agg, err := UserAggregateOverwriteContext(ctx, aggCreator, existing, existing.ResourceOwner, existing.AggregateID)
if err != nil {
return nil, err
}
agg.AppendEvent(model.SignedOut, map[string]interface{}{"userAgentID": agentID})
aggregates[i] = agg
} }
return agg.AppendEvent(model.SignedOut, map[string]interface{}{"userAgentID": agentID}) return aggregates, nil
} }
} }

View File

@@ -66,7 +66,7 @@ func (o *OPStorage) TerminateSession(ctx context.Context, userID, clientID strin
if !ok { if !ok {
return errors.ThrowPreconditionFailed(nil, "OIDC-fso7F", "no user agent id") return errors.ThrowPreconditionFailed(nil, "OIDC-fso7F", "no user agent id")
} }
return o.repo.SignOut(ctx, userAgentID, userID) return o.repo.SignOut(ctx, userAgentID)
} }
func (o *OPStorage) GetSigningKey(ctx context.Context, keyCh chan<- jose.SigningKey, errCh chan<- error, timer <-chan time.Time) { func (o *OPStorage) GetSigningKey(ctx context.Context, keyCh chan<- jose.SigningKey, errCh chan<- error, timer <-chan time.Time) {