Skip to content

Commit 57f7e12

Browse files
gregns1bbrks
andauthored
CBG-5311: [4.0.5 backport] Cleanup for GetUser (#8261)
Co-authored-by: Ben Brooks <ben.brooks@couchbase.com>
1 parent 9f99659 commit 57f7e12

7 files changed

Lines changed: 45 additions & 18 deletions

File tree

auth/auth.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,9 @@ func (auth *Authenticator) casUpdatePrincipal(p Principal, callback casUpdatePri
719719
if err != nil {
720720
return fmt.Errorf("Error reloading principal after CAS failure: %w", err)
721721
}
722+
if p == nil {
723+
return base.ErrNotFound
724+
}
722725
}
723726
base.InfofCtx(auth.LogCtx, base.KeyAuth, "Unable to update principal after %d attempts. Principal:%s Error:%v", PrincipalUpdateMaxCasRetries, base.UD(p.Name()), err)
724727
return err
@@ -929,7 +932,7 @@ func (auth *Authenticator) authenticateJWTIdentity(identity *Identity, provider
929932
if common.Register {
930933
base.DebugfCtx(auth.LogCtx, base.KeyAuth, "Registering new user: %v with email: %v", base.UD(username), base.UD(identity.Email))
931934
user, err := auth.RegisterNewUser(username, identity.Email)
932-
if err != nil && !base.IsCasMismatch(err) {
935+
if err != nil {
933936
base.InfofCtx(auth.LogCtx, base.KeyAuth, "Error registering new user: %v", err)
934937
return nil, PrincipalConfig{}, time.Time{}, err
935938
}
@@ -941,8 +944,8 @@ func (auth *Authenticator) authenticateJWTIdentity(identity *Identity, provider
941944
}
942945

943946
// Registers a new user account based on the given verified username and optional email address.
944-
// Password will be random. The user will have access to no channels. If the user already exists,
945-
// returns the existing user along with the cas failure error
947+
// Password will be random. The user will have access to no channels. If the user already exists
948+
// (race with a concurrent registration), returns the existing user with a nil error.
946949
func (auth *Authenticator) RegisterNewUser(username, email string) (User, error) {
947950
secret, err := base.GenerateRandomSecret()
948951
if err != nil {
@@ -964,7 +967,14 @@ func (auth *Authenticator) RegisterNewUser(username, email string) (User, error)
964967

965968
err = auth.Save(user)
966969
if base.IsCasMismatch(err) {
967-
return auth.GetUser(username)
970+
existing, getErr := auth.GetUser(username)
971+
if getErr != nil {
972+
return nil, getErr
973+
}
974+
if existing == nil {
975+
return nil, err
976+
}
977+
return existing, nil
968978
} else if err != nil {
969979
return nil, err
970980
}

auth/session.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,7 @@ func (auth *Authenticator) AuthenticateCookie(rq *http.Request, response http.Re
7272
if err != nil {
7373
return nil, err
7474
}
75-
76-
if session.SessionUUID != user.GetSessionUUID() {
75+
if user == nil || session.SessionUUID != user.GetSessionUUID() {
7776
base.InfofCtx(auth.LogCtx, base.KeyAuth, "Session no longer valid for user %s", base.UD(session.Username))
7877
return nil, base.HTTPErrorf(http.StatusUnauthorized, "Session no longer valid for user")
7978
}

db/crud.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3179,6 +3179,8 @@ func (db *DatabaseCollectionWithUser) MarkPrincipalsChanged(ctx context.Context,
31793179
user, err := db.Authenticator(ctx).GetUser(db.user.Name())
31803180
if err != nil {
31813181
base.WarnfCtx(ctx, "Error reloading active db.user[%s], security information will not be recalculated until next authentication --> %+v", base.UD(db.user.Name()), err)
3182+
} else if user == nil {
3183+
base.WarnfCtx(ctx, "Active db.user[%s] no longer exists; security information will not be recalculated until next authentication", base.UD(db.user.Name()))
31823184
} else {
31833185
db.user = user
31843186
}

db/database.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1717,22 +1717,28 @@ func (c *DatabaseCollection) updateAllPrincipalsSequences(ctx context.Context) e
17171717

17181718
authr := c.Authenticator(ctx)
17191719

1720-
for _, role := range roles {
1721-
role, err := authr.GetRole(role)
1720+
for _, roleName := range roles {
1721+
role, err := authr.GetRole(roleName)
17221722
if err != nil {
17231723
return err
17241724
}
1725+
if role == nil {
1726+
continue
1727+
}
17251728
err = c.regeneratePrincipalSequences(ctx, authr, role)
17261729
if err != nil {
17271730
return err
17281731
}
17291732
}
17301733

1731-
for _, user := range users {
1732-
user, err := authr.GetUser(user)
1734+
for _, userName := range users {
1735+
user, err := authr.GetUser(userName)
17331736
if err != nil {
17341737
return err
17351738
}
1739+
if user == nil {
1740+
continue
1741+
}
17361742
err = c.regeneratePrincipalSequences(ctx, authr, user)
17371743
if err != nil {
17381744
return err

rest/diagnostic_api.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,10 @@ func getHistoricRoleChanEntryOverlap(roleEntries []auth.GrantHistorySequencePair
197197

198198
func (h *handler) handleGetAllChannels() error {
199199
h.assertAdminOnly()
200-
user, err := h.db.Authenticator(h.ctx()).GetUser(internalUserName(mux.Vars(h.rq)["name"]))
200+
name := internalUserName(mux.Vars(h.rq)["name"])
201+
user, err := h.db.Authenticator(h.ctx()).GetUser(name)
201202
if err != nil {
202-
return fmt.Errorf("could not get user %s: %w", user.Name(), err)
203+
return fmt.Errorf("could not get user %s: %w", name, err)
203204
}
204205
if user == nil {
205206
return kNotFoundError
@@ -221,9 +222,10 @@ func (h *handler) handleGetAllChannels() error {
221222

222223
func (h *handler) handleGetUserDocAccessSpan() error {
223224
h.assertAdminOnly()
224-
user, err := h.db.Authenticator(h.ctx()).GetUser(internalUserName(mux.Vars(h.rq)["name"]))
225+
name := internalUserName(mux.Vars(h.rq)["name"])
226+
user, err := h.db.Authenticator(h.ctx()).GetUser(name)
225227
if err != nil {
226-
return fmt.Errorf("could not get user %s: %w", user.Name(), err)
228+
return fmt.Errorf("could not get user %s: %w", name, err)
227229
}
228230
if user == nil {
229231
return kNotFoundError

rest/handler.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -521,10 +521,13 @@ func (h *handler) validateAndWriteHeaders(method handlerMethod, accessPermission
521521
return fmt.Errorf("failed to revoke stale OIDC roles/channels: %w", err)
522522
}
523523
// TODO: could avoid this extra fetch if UpdatePrincipal returned the new principal
524-
h.user, err = dbContext.Authenticator(h.ctx()).GetUser(*updates.Name)
524+
user, err := dbContext.Authenticator(h.ctx()).GetUser(*updates.Name)
525525
if err != nil {
526526
return err
527+
} else if user == nil {
528+
return ErrInvalidLogin
527529
}
530+
h.user = user
528531
}
529532
}
530533

@@ -981,7 +984,13 @@ func (h *handler) setUserForPublicAuth(dbCtx *db.DatabaseContext) (base.AuditFie
981984
}
982985
// TODO: could avoid this extra fetch if UpdatePrincipal returned the newly updated principal
983986
if updates.Name != nil {
984-
h.user, err = dbCtx.Authenticator(h.ctx()).GetUser(*updates.Name)
987+
user, err := dbCtx.Authenticator(h.ctx()).GetUser(*updates.Name)
988+
if err != nil {
989+
return auditFields, err
990+
} else if user == nil {
991+
return auditFields, ErrInvalidLogin
992+
}
993+
h.user = user
985994
}
986995
return auditFields, err
987996
}

rest/session_api.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,8 @@ func (h *handler) makeSessionFromNameAndEmail(username, email string, createUser
194194
}
195195

196196
// Create a User with the given username, email address, and a random password.
197-
// CAS mismatch indicates the user has been created by another request underneath us, can continue with session creation
198197
user, err = h.db.Authenticator(h.ctx()).RegisterNewUser(username, email)
199-
if err != nil && !base.IsCasMismatch(err) {
198+
if err != nil {
200199
return err
201200
}
202201
}

0 commit comments

Comments
 (0)