From 79eff2795fae91c407708cb46232895ab4b3e688 Mon Sep 17 00:00:00 2001 From: Fabi <38692350+fgerschwiler@users.noreply.github.com> Date: Mon, 29 Jun 2020 09:49:40 +0200 Subject: [PATCH] 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 --- .../eventsourcing/eventstore/user.go | 12 +++++++-- internal/auth/repository/user.go | 2 +- .../repository/eventsourcing/eventstore.go | 27 ++++++++++++------- .../user/repository/eventsourcing/user.go | 17 +++++++----- pkg/auth/api/oidc/auth_request.go | 2 +- 5 files changed, 40 insertions(+), 20 deletions(-) diff --git a/internal/auth/repository/eventsourcing/eventstore/user.go b/internal/auth/repository/eventsourcing/eventstore/user.go index f50e00142..28de33b4e 100644 --- a/internal/auth/repository/eventsourcing/eventstore/user.go +++ b/internal/auth/repository/eventsourcing/eventstore/user.go @@ -227,8 +227,16 @@ func (repo *UserRepo) SetPassword(ctx context.Context, userID, code, password st return repo.UserEvents.SetPassword(ctx, policy, userID, code, password) } -func (repo *UserRepo) SignOut(ctx context.Context, agentID, userID string) error { - return repo.UserEvents.SignOut(ctx, agentID, userID) +func (repo *UserRepo) SignOut(ctx context.Context, agentID string) error { + 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) { diff --git a/internal/auth/repository/user.go b/internal/auth/repository/user.go index 6b341f527..30838621f 100644 --- a/internal/auth/repository/user.go +++ b/internal/auth/repository/user.go @@ -23,7 +23,7 @@ type UserRepository interface { AddMfaOTP(ctx context.Context, userID string) (*model.OTP, 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) } diff --git a/internal/user/repository/eventsourcing/eventstore.go b/internal/user/repository/eventsourcing/eventstore.go index 97d66a9db..2bde070f3 100644 --- a/internal/user/repository/eventsourcing/eventstore.go +++ b/internal/user/repository/eventsourcing/eventstore.go @@ -1049,17 +1049,24 @@ func (es *UserEventstore) verifyMfaOTP(otp *usr_model.OTP, code string) error { return nil } -func (es *UserEventstore) SignOut(ctx context.Context, agentID, userID string) error { - user, err := es.UserByID(ctx, userID) - if err != nil { - return err - } - repoUser := model.UserFromModel(user) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, SignOutAggregate(es.AggregateCreator(), repoUser, agentID)) - if err != nil { - return err +func (es *UserEventstore) SignOut(ctx context.Context, agentID string, userIDs []string) error { + users := make([]*model.User, len(userIDs)) + for i, id := range userIDs { + user, err := es.UserByID(ctx, id) + if err != nil { + return err + } + users[i] = model.UserFromModel(user) } - 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 } diff --git a/internal/user/repository/eventsourcing/user.go b/internal/user/repository/eventsourcing/user.go index 1fa63b992..e9b236801 100644 --- a/internal/user/repository/eventsourcing/user.go +++ b/internal/user/repository/eventsourcing/user.go @@ -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) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - agg, err := UserAggregateOverwriteContext(ctx, aggCreator, existing, existing.ResourceOwner, existing.AggregateID) - if err != nil { - return nil, err +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) { + aggregates := make([]*es_models.Aggregate, len(existingUsers)) + for i, existing := range existingUsers { + 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 } } diff --git a/pkg/auth/api/oidc/auth_request.go b/pkg/auth/api/oidc/auth_request.go index 62366797e..0de08181e 100644 --- a/pkg/auth/api/oidc/auth_request.go +++ b/pkg/auth/api/oidc/auth_request.go @@ -66,7 +66,7 @@ func (o *OPStorage) TerminateSession(ctx context.Context, userID, clientID strin if !ok { 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) {