From dd136858f1ea40ad3c94191d647487fa4f31926c Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 18 Oct 2024 20:33:49 +0200 Subject: Adding upstream version 9.0.0. Signed-off-by: Daniel Baumann --- services/auth/source/db/assert_interface_test.go | 20 ++++++ services/auth/source/db/authenticate.go | 87 ++++++++++++++++++++++++ services/auth/source/db/source.go | 35 ++++++++++ 3 files changed, 142 insertions(+) create mode 100644 services/auth/source/db/assert_interface_test.go create mode 100644 services/auth/source/db/authenticate.go create mode 100644 services/auth/source/db/source.go (limited to 'services/auth/source/db') diff --git a/services/auth/source/db/assert_interface_test.go b/services/auth/source/db/assert_interface_test.go new file mode 100644 index 0000000..62387c7 --- /dev/null +++ b/services/auth/source/db/assert_interface_test.go @@ -0,0 +1,20 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package db_test + +import ( + auth_model "code.gitea.io/gitea/models/auth" + "code.gitea.io/gitea/services/auth" + "code.gitea.io/gitea/services/auth/source/db" +) + +// This test file exists to assert that our Source exposes the interfaces that we expect +// It tightly binds the interfaces and implementation without breaking go import cycles + +type sourceInterface interface { + auth.PasswordAuthenticator + auth_model.Config +} + +var _ (sourceInterface) = &db.Source{} diff --git a/services/auth/source/db/authenticate.go b/services/auth/source/db/authenticate.go new file mode 100644 index 0000000..8160141 --- /dev/null +++ b/services/auth/source/db/authenticate.go @@ -0,0 +1,87 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package db + +import ( + "context" + "fmt" + + user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" +) + +// ErrUserPasswordNotSet represents a "ErrUserPasswordNotSet" kind of error. +type ErrUserPasswordNotSet struct { + UID int64 + Name string +} + +func (err ErrUserPasswordNotSet) Error() string { + return fmt.Sprintf("user's password isn't set [uid: %d, name: %s]", err.UID, err.Name) +} + +// Unwrap unwraps this error as a ErrInvalidArgument error +func (err ErrUserPasswordNotSet) Unwrap() error { + return util.ErrInvalidArgument +} + +// ErrUserPasswordInvalid represents a "ErrUserPasswordInvalid" kind of error. +type ErrUserPasswordInvalid struct { + UID int64 + Name string +} + +func (err ErrUserPasswordInvalid) Error() string { + return fmt.Sprintf("user's password is invalid [uid: %d, name: %s]", err.UID, err.Name) +} + +// Unwrap unwraps this error as a ErrInvalidArgument error +func (err ErrUserPasswordInvalid) Unwrap() error { + return util.ErrInvalidArgument +} + +// Authenticate authenticates the provided user against the DB +func Authenticate(ctx context.Context, user *user_model.User, login, password string) (*user_model.User, error) { + if user == nil { + return nil, user_model.ErrUserNotExist{Name: login} + } + + if !user.IsPasswordSet() { + return nil, ErrUserPasswordNotSet{UID: user.ID, Name: user.Name} + } else if !user.ValidatePassword(password) { + return nil, ErrUserPasswordInvalid{UID: user.ID, Name: user.Name} + } + + // Update password hash if server password hash algorithm have changed + // Or update the password when the salt length doesn't match the current + // recommended salt length, this in order to migrate user's salts to a more secure salt. + if user.PasswdHashAlgo != setting.PasswordHashAlgo || len(user.Salt) != user_model.SaltByteLength*2 { + if err := user.SetPassword(password); err != nil { + return nil, err + } + if err := user_model.UpdateUserCols(ctx, user, "passwd", "passwd_hash_algo", "salt"); err != nil { + return nil, err + } + } + + // WARN: DON'T check user.IsActive, that will be checked on reqSign so that + // user could be hinted to resend confirm email. + if user.ProhibitLogin { + return nil, user_model.ErrUserProhibitLogin{ + UID: user.ID, + Name: user.Name, + } + } + + // attempting to login as a non-user account + if user.Type != user_model.UserTypeIndividual { + return nil, user_model.ErrUserProhibitLogin{ + UID: user.ID, + Name: user.Name, + } + } + + return user, nil +} diff --git a/services/auth/source/db/source.go b/services/auth/source/db/source.go new file mode 100644 index 0000000..bb2270c --- /dev/null +++ b/services/auth/source/db/source.go @@ -0,0 +1,35 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package db + +import ( + "context" + + "code.gitea.io/gitea/models/auth" + user_model "code.gitea.io/gitea/models/user" +) + +// Source is a password authentication service +type Source struct{} + +// FromDB fills up an OAuth2Config from serialized format. +func (source *Source) FromDB(bs []byte) error { + return nil +} + +// ToDB exports the config to a byte slice to be saved into database (this method is just dummy and does nothing for DB source) +func (source *Source) ToDB() ([]byte, error) { + return nil, nil +} + +// Authenticate queries if login/password is valid against the PAM, +// and create a local user if success when enabled. +func (source *Source) Authenticate(ctx context.Context, user *user_model.User, login, password string) (*user_model.User, error) { + return Authenticate(ctx, user, login, password) +} + +func init() { + auth.RegisterTypeConfig(auth.NoType, &Source{}) + auth.RegisterTypeConfig(auth.Plain, &Source{}) +} -- cgit v1.2.3