You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

58 lines
1.8 KiB

package mock
import (
"context"
"errors"
"strings"
"tera-clone/services/tera-api/internal/domain"
)
// VerifyCurrentPassword reauthenticates the session actor without creating or
// replacing a browser session. The caller cannot nominate another account.
func (s *Store) VerifyCurrentPassword(ctx context.Context, credential string) error {
actor, ok := domain.ActorFromContext(ctx)
if !ok || actor.Name == "" {
return errors.New("authentication required")
}
s.mu.Lock()
username := ""
var user authUserRecord
for name, candidate := range s.authUsers {
if candidate.Actor == actor.Name {
username, user = name, candidate
break
}
}
external := username == "" && strings.HasPrefix(actor.Name, "external-")
if external {
username = strings.TrimPrefix(actor.Name, "external-")
}
now := s.clock().UTC()
locked, _ := s.loginLockedLocked(username, now)
config := cloneExternalAuth(s.runningExternalAuth)
verified := false
if !locked && !external && username != "" && !user.Disabled && credential != "" {
verified, _ = s.passwordKDFs.Verify(user.Password, credential)
}
s.mu.Unlock()
if external && !locked && credential != "" {
authenticated, accepted, _ := s.authenticateExternal(ctx, config, username, credential)
verified = accepted && authenticated.Name == actor.Name
}
s.mu.Lock()
defer s.mu.Unlock()
if !verified {
if !locked {
s.recordLoginFailureLocked(username, now)
}
s.recordAuditLocked(ctx, "auth.reauthenticate", actor.Name, "failed", "current account password verification failed")
if err := s.persistLoginFailureStoreLocked(); err != nil {
return err
}
return errors.New("current account password is incorrect or account is locked")
}
delete(s.loginFailures, username)
return s.persistLoginFailureStoreLocked()
}