1
1
mirror of https://github.com/go-gitea/gitea synced 2025-07-22 18:28:37 +00:00

Move login related structs and functions to models/login (#17093)

* Move login related structs and functions to models/login

* Fix test

* Fix lint

* Fix lint

* Fix lint of windows

* Fix lint

* Fix test

* Fix test

* Only load necessary fixtures when preparing unit tests envs

* Fix lint

* Fix test

* Fix test

* Fix error log

* Fix error log

* Fix error log

* remove unnecessary change

* fix error log

* merge main branch
This commit is contained in:
Lunny Xiao
2021-09-24 19:32:56 +08:00
committed by GitHub
parent 4a2655098f
commit 5842a55b31
142 changed files with 1050 additions and 907 deletions

View File

@@ -5,7 +5,7 @@
package db_test
import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/login"
"code.gitea.io/gitea/services/auth"
"code.gitea.io/gitea/services/auth/source/db"
)
@@ -15,7 +15,7 @@ import (
type sourceInterface interface {
auth.PasswordAuthenticator
models.LoginConfig
login.Config
}
var _ (sourceInterface) = &db.Source{}

View File

@@ -4,7 +4,10 @@
package db
import "code.gitea.io/gitea/models"
import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/login"
)
// Source is a password authentication service
type Source struct{}
@@ -26,6 +29,6 @@ func (source *Source) Authenticate(user *models.User, login, password string) (*
}
func init() {
models.RegisterLoginTypeConfig(models.LoginNoType, &Source{})
models.RegisterLoginTypeConfig(models.LoginPlain, &Source{})
login.RegisterTypeConfig(login.NoType, &Source{})
login.RegisterTypeConfig(login.Plain, &Source{})
}

View File

@@ -5,7 +5,7 @@
package ldap_test
import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/login"
"code.gitea.io/gitea/services/auth"
"code.gitea.io/gitea/services/auth/source/ldap"
)
@@ -17,12 +17,12 @@ type sourceInterface interface {
auth.PasswordAuthenticator
auth.SynchronizableSource
auth.LocalTwoFASkipper
models.SSHKeyProvider
models.LoginConfig
models.SkipVerifiable
models.HasTLSer
models.UseTLSer
models.LoginSourceSettable
login.SSHKeyProvider
login.Config
login.SkipVerifiable
login.HasTLSer
login.UseTLSer
login.SourceSettable
}
var _ (sourceInterface) = &ldap.Source{}

View File

@@ -8,6 +8,7 @@ import (
"strings"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/login"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/secret"
"code.gitea.io/gitea/modules/setting"
@@ -55,7 +56,7 @@ type Source struct {
SkipLocalTwoFA bool // Skip Local 2fa for users authenticated with this source
// reference to the loginSource
loginSource *models.LoginSource
loginSource *login.Source
}
// FromDB fills up a LDAPConfig from serialized format.
@@ -109,11 +110,11 @@ func (source *Source) ProvidesSSHKeys() bool {
}
// SetLoginSource sets the related LoginSource
func (source *Source) SetLoginSource(loginSource *models.LoginSource) {
func (source *Source) SetLoginSource(loginSource *login.Source) {
source.loginSource = loginSource
}
func init() {
models.RegisterLoginTypeConfig(models.LoginLDAP, &Source{})
models.RegisterLoginTypeConfig(models.LoginDLDAP, &Source{})
login.RegisterTypeConfig(login.LDAP, &Source{})
login.RegisterTypeConfig(login.DLDAP, &Source{})
}

View File

@@ -9,16 +9,17 @@ import (
"strings"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/login"
"code.gitea.io/gitea/services/mailer"
)
// Authenticate queries if login/password is valid against the LDAP directory pool,
// and create a local user if success when enabled.
func (source *Source) Authenticate(user *models.User, login, password string) (*models.User, error) {
sr := source.SearchEntry(login, password, source.loginSource.Type == models.LoginDLDAP)
func (source *Source) Authenticate(user *models.User, userName, password string) (*models.User, error) {
sr := source.SearchEntry(userName, password, source.loginSource.Type == login.DLDAP)
if sr == nil {
// User not in LDAP, do nothing
return nil, models.ErrUserNotExist{Name: login}
return nil, models.ErrUserNotExist{Name: userName}
}
isAttributeSSHPublicKeySet := len(strings.TrimSpace(source.AttributeSSHPublicKey)) > 0
@@ -64,7 +65,7 @@ func (source *Source) Authenticate(user *models.User, login, password string) (*
// Fallback.
if len(sr.Username) == 0 {
sr.Username = login
sr.Username = userName
}
if len(sr.Mail) == 0 {
@@ -78,7 +79,7 @@ func (source *Source) Authenticate(user *models.User, login, password string) (*
Email: sr.Mail,
LoginType: source.loginSource.Type,
LoginSource: source.loginSource.ID,
LoginName: login,
LoginName: userName,
IsActive: true,
IsAdmin: sr.IsAdmin,
IsRestricted: sr.IsRestricted,

View File

@@ -5,7 +5,7 @@
package oauth2_test
import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/login"
"code.gitea.io/gitea/services/auth"
"code.gitea.io/gitea/services/auth/source/oauth2"
)
@@ -14,9 +14,9 @@ import (
// It tightly binds the interfaces and implementation without breaking go import cycles
type sourceInterface interface {
models.LoginConfig
models.LoginSourceSettable
models.RegisterableSource
login.Config
login.SourceSettable
login.RegisterableSource
auth.PasswordAuthenticator
}

View File

@@ -8,8 +8,8 @@ import (
"net/http"
"sync"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/login"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
@@ -74,7 +74,7 @@ func ResetOAuth2() error {
// initOAuth2LoginSources is used to load and register all active OAuth2 providers
func initOAuth2LoginSources() error {
loginSources, _ := models.GetActiveOAuth2ProviderLoginSources()
loginSources, _ := login.GetActiveOAuth2ProviderLoginSources()
for _, source := range loginSources {
oauth2Source, ok := source.Cfg.(*Source)
if !ok {

View File

@@ -9,6 +9,7 @@ import (
"sort"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/login"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
@@ -87,7 +88,7 @@ func GetOAuth2Providers() []Provider {
func GetActiveOAuth2Providers() ([]string, map[string]Provider, error) {
// Maybe also separate used and unused providers so we can force the registration of only 1 active provider for each type
loginSources, err := models.GetActiveOAuth2ProviderLoginSources()
loginSources, err := login.GetActiveOAuth2ProviderLoginSources()
if err != nil {
return nil, nil, err
}

View File

@@ -6,6 +6,7 @@ package oauth2
import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/login"
"code.gitea.io/gitea/modules/json"
)
@@ -27,7 +28,7 @@ type Source struct {
SkipLocalTwoFA bool
// reference to the loginSource
loginSource *models.LoginSource
loginSource *login.Source
}
// FromDB fills up an OAuth2Config from serialized format.
@@ -41,10 +42,10 @@ func (source *Source) ToDB() ([]byte, error) {
}
// SetLoginSource sets the related LoginSource
func (source *Source) SetLoginSource(loginSource *models.LoginSource) {
func (source *Source) SetLoginSource(loginSource *login.Source) {
source.loginSource = loginSource
}
func init() {
models.RegisterLoginTypeConfig(models.LoginOAuth2, &Source{})
login.RegisterTypeConfig(login.OAuth2, &Source{})
}

View File

@@ -5,7 +5,7 @@
package pam_test
import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/login"
"code.gitea.io/gitea/services/auth"
"code.gitea.io/gitea/services/auth/source/pam"
)
@@ -15,8 +15,8 @@ import (
type sourceInterface interface {
auth.PasswordAuthenticator
models.LoginConfig
models.LoginSourceSettable
login.Config
login.SourceSettable
}
var _ (sourceInterface) = &pam.Source{}

View File

@@ -6,6 +6,7 @@ package pam
import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/login"
"code.gitea.io/gitea/modules/json"
)
@@ -22,7 +23,7 @@ type Source struct {
EmailDomain string
// reference to the loginSource
loginSource *models.LoginSource
loginSource *login.Source
}
// FromDB fills up a PAMConfig from serialized format.
@@ -36,10 +37,10 @@ func (source *Source) ToDB() ([]byte, error) {
}
// SetLoginSource sets the related LoginSource
func (source *Source) SetLoginSource(loginSource *models.LoginSource) {
func (source *Source) SetLoginSource(loginSource *login.Source) {
source.loginSource = loginSource
}
func init() {
models.RegisterLoginTypeConfig(models.LoginPAM, &Source{})
login.RegisterTypeConfig(login.PAM, &Source{})
}

View File

@@ -9,6 +9,7 @@ import (
"strings"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/login"
"code.gitea.io/gitea/modules/auth/pam"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/services/mailer"
@@ -18,11 +19,11 @@ import (
// Authenticate queries if login/password is valid against the PAM,
// and create a local user if success when enabled.
func (source *Source) Authenticate(user *models.User, login, password string) (*models.User, error) {
pamLogin, err := pam.Auth(source.ServiceName, login, password)
func (source *Source) Authenticate(user *models.User, userName, password string) (*models.User, error) {
pamLogin, err := pam.Auth(source.ServiceName, userName, password)
if err != nil {
if strings.Contains(err.Error(), "Authentication failure") {
return nil, models.ErrUserNotExist{Name: login}
return nil, models.ErrUserNotExist{Name: userName}
}
return nil, err
}
@@ -54,9 +55,9 @@ func (source *Source) Authenticate(user *models.User, login, password string) (*
Name: username,
Email: email,
Passwd: password,
LoginType: models.LoginPAM,
LoginType: login.PAM,
LoginSource: source.loginSource.ID,
LoginName: login, // This is what the user typed in
LoginName: userName, // This is what the user typed in
IsActive: true,
}

View File

@@ -5,7 +5,7 @@
package smtp_test
import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/login"
"code.gitea.io/gitea/services/auth"
"code.gitea.io/gitea/services/auth/source/smtp"
)
@@ -15,11 +15,11 @@ import (
type sourceInterface interface {
auth.PasswordAuthenticator
models.LoginConfig
models.SkipVerifiable
models.HasTLSer
models.UseTLSer
models.LoginSourceSettable
login.Config
login.SkipVerifiable
login.HasTLSer
login.UseTLSer
login.SourceSettable
}
var _ (sourceInterface) = &smtp.Source{}

View File

@@ -6,6 +6,7 @@ package smtp
import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/login"
"code.gitea.io/gitea/modules/json"
)
@@ -28,7 +29,7 @@ type Source struct {
DisableHelo bool
// reference to the loginSource
loginSource *models.LoginSource
loginSource *login.Source
}
// FromDB fills up an SMTPConfig from serialized format.
@@ -57,10 +58,10 @@ func (source *Source) UseTLS() bool {
}
// SetLoginSource sets the related LoginSource
func (source *Source) SetLoginSource(loginSource *models.LoginSource) {
func (source *Source) SetLoginSource(loginSource *login.Source) {
source.loginSource = loginSource
}
func init() {
models.RegisterLoginTypeConfig(models.LoginSMTP, &Source{})
login.RegisterTypeConfig(login.SMTP, &Source{})
}

View File

@@ -11,31 +11,32 @@ import (
"strings"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/login"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/services/mailer"
)
// Authenticate queries if the provided login/password is authenticates against the SMTP server
// Users will be autoregistered as required
func (source *Source) Authenticate(user *models.User, login, password string) (*models.User, error) {
func (source *Source) Authenticate(user *models.User, userName, password string) (*models.User, error) {
// Verify allowed domains.
if len(source.AllowedDomains) > 0 {
idx := strings.Index(login, "@")
idx := strings.Index(userName, "@")
if idx == -1 {
return nil, models.ErrUserNotExist{Name: login}
} else if !util.IsStringInSlice(login[idx+1:], strings.Split(source.AllowedDomains, ","), true) {
return nil, models.ErrUserNotExist{Name: login}
return nil, models.ErrUserNotExist{Name: userName}
} else if !util.IsStringInSlice(userName[idx+1:], strings.Split(source.AllowedDomains, ","), true) {
return nil, models.ErrUserNotExist{Name: userName}
}
}
var auth smtp.Auth
switch source.Auth {
case PlainAuthentication:
auth = smtp.PlainAuth("", login, password, source.Host)
auth = smtp.PlainAuth("", userName, password, source.Host)
case LoginAuthentication:
auth = &loginAuthenticator{login, password}
auth = &loginAuthenticator{userName, password}
case CRAMMD5Authentication:
auth = smtp.CRAMMD5Auth(login, password)
auth = smtp.CRAMMD5Auth(userName, password)
default:
return nil, errors.New("unsupported SMTP auth type")
}
@@ -46,11 +47,11 @@ func (source *Source) Authenticate(user *models.User, login, password string) (*
tperr, ok := err.(*textproto.Error)
if (ok && tperr.Code == 535) ||
strings.Contains(err.Error(), "Username and Password not accepted") {
return nil, models.ErrUserNotExist{Name: login}
return nil, models.ErrUserNotExist{Name: userName}
}
if (ok && tperr.Code == 534) ||
strings.Contains(err.Error(), "Application-specific password required") {
return nil, models.ErrUserNotExist{Name: login}
return nil, models.ErrUserNotExist{Name: userName}
}
return nil, err
}
@@ -59,20 +60,20 @@ func (source *Source) Authenticate(user *models.User, login, password string) (*
return user, nil
}
username := login
idx := strings.Index(login, "@")
username := userName
idx := strings.Index(userName, "@")
if idx > -1 {
username = login[:idx]
username = userName[:idx]
}
user = &models.User{
LowerName: strings.ToLower(username),
Name: strings.ToLower(username),
Email: login,
Email: userName,
Passwd: password,
LoginType: models.LoginSMTP,
LoginType: login.SMTP,
LoginSource: source.loginSource.ID,
LoginName: login,
LoginName: userName,
IsActive: true,
}

View File

@@ -5,7 +5,7 @@
package sspi_test
import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/login"
"code.gitea.io/gitea/services/auth/source/sspi"
)
@@ -13,7 +13,7 @@ import (
// It tightly binds the interfaces and implementation without breaking go import cycles
type sourceInterface interface {
models.LoginConfig
login.Config
}
var _ (sourceInterface) = &sspi.Source{}

View File

@@ -6,6 +6,7 @@ package sspi
import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/login"
"code.gitea.io/gitea/modules/json"
)
@@ -36,5 +37,5 @@ func (cfg *Source) ToDB() ([]byte, error) {
}
func init() {
models.RegisterLoginTypeConfig(models.LoginSSPI, &Source{})
login.RegisterTypeConfig(login.SSPI, &Source{})
}