fix: a password change or ban ends authorized device sessions
The device hand-over now refuses a session authorized before the user's tokens_valid_after, and every AccessRevokedEvent revokes the user's pending and confirmed device sessions inside the write's transaction (classes.RevokeDeviceSessions).
This commit is contained in:
@@ -241,7 +241,10 @@ func writeDeviceStatus(w http.ResponseWriter, r *http.Request, gdb *gorm.DB, row
|
||||
// handOverDevice gives the confirmed session's user a session token for the
|
||||
// device (D-12a). It reports false, having written nothing, when another
|
||||
// poll already took the session or it expired meanwhile; the token it
|
||||
// minted is then dropped unsent.
|
||||
// minted is then dropped unsent. A user who is gone, deactivated or
|
||||
// banned, or whose tokens_valid_after (a password change, a revocation)
|
||||
// is later than the authorization, gets nothing: the session becomes
|
||||
// revoked, as a token minted at the authorization would be refused.
|
||||
func handOverDevice(w http.ResponseWriter, r *http.Request, app *backpack.App, gdb *gorm.DB, secret string, row models.DeviceAuthSession) bool {
|
||||
ctx := r.Context()
|
||||
var user models.User
|
||||
@@ -257,7 +260,7 @@ func handOverDevice(w http.ResponseWriter, r *http.Request, app *backpack.App, g
|
||||
writeOpaque500(w)
|
||||
return true
|
||||
}
|
||||
refused = banned[user.ID]
|
||||
refused = banned[user.ID] || authorizedBeforeCutoff(&user, row)
|
||||
}
|
||||
if refused {
|
||||
// A deactivated, deleted or banned user signs no device in.
|
||||
@@ -307,6 +310,16 @@ func handOverDevice(w http.ResponseWriter, r *http.Request, app *backpack.App, g
|
||||
return true
|
||||
}
|
||||
|
||||
// authorizedBeforeCutoff reports whether row was confirmed before the
|
||||
// user's tokens_valid_after, compared as the jwt guard compares a token's
|
||||
// whole-second iat.
|
||||
func authorizedBeforeCutoff(user *models.User, row models.DeviceAuthSession) bool {
|
||||
if user.TokensValidAfter == nil || row.ConfirmedAt == nil {
|
||||
return false
|
||||
}
|
||||
return row.ConfirmedAt.Truncate(time.Second).Before(*user.TokensValidAfter)
|
||||
}
|
||||
|
||||
// DeviceAuthorize is POST /devices/authorize: a signed-in user (a valid,
|
||||
// not blacklisted session token; no second-factor check, D-12c) binds a
|
||||
// pending device session to themselves by its short_code (hyphens and
|
||||
|
||||
Reference in New Issue
Block a user