diff options
author | wxiaoguang <wxiaoguang@gmail.com> | 2023-09-18 07:32:56 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-17 23:32:56 +0000 |
commit | 8531ca08372dd4a4739564dec17766fffe34a385 (patch) | |
tree | a6c05c2083d71230bab7768d205e7fbfedcebd4c /services | |
parent | 47b878858ada27fc4c74eeadcc1e467d2da90e04 (diff) | |
download | gitea-8531ca08372dd4a4739564dec17766fffe34a385.tar.gz gitea-8531ca08372dd4a4739564dec17766fffe34a385.zip |
Make SSPI auth mockable (#27036)
Before, the SSPI auth is only complied for Windows, it's difficult to
test and it breaks a lot.
Now, make the SSPI auth mockable and testable.
Diffstat (limited to 'services')
-rw-r--r-- | services/auth/sspi.go (renamed from services/auth/sspi_windows.go) | 30 | ||||
-rw-r--r-- | services/auth/sspiauth_posix.go | 30 | ||||
-rw-r--r-- | services/auth/sspiauth_windows.go | 19 |
3 files changed, 63 insertions, 16 deletions
diff --git a/services/auth/sspi_windows.go b/services/auth/sspi.go index e29bd71529..d4f7e3ec60 100644 --- a/services/auth/sspi_windows.go +++ b/services/auth/sspi.go @@ -22,19 +22,21 @@ import ( "code.gitea.io/gitea/services/auth/source/sspi" gouuid "github.com/google/uuid" - "github.com/quasoft/websspi" ) const ( tplSignIn base.TplName = "user/auth/signin" ) +type SSPIAuth interface { + AppendAuthenticateHeader(w http.ResponseWriter, data string) + Authenticate(r *http.Request, w http.ResponseWriter) (userInfo *SSPIUserInfo, outToken string, err error) +} + var ( - // sspiAuth is a global instance of the websspi authentication package, - // which is used to avoid acquiring the server credential handle on - // every request - sspiAuth *websspi.Authenticator - sspiAuthOnce sync.Once + sspiAuth SSPIAuth // a global instance of the websspi authenticator to avoid acquiring the server credential handle on every request + sspiAuthOnce sync.Once + sspiAuthErrInit error // Ensure the struct implements the interface. _ Method = &SSPI{} @@ -42,8 +44,9 @@ var ( // SSPI implements the SingleSignOn interface and authenticates requests // via the built-in SSPI module in Windows for SPNEGO authentication. -// On successful authentication returns a valid user object. -// Returns nil if authentication fails. +// The SSPI plugin is expected to be executed last, as it returns 401 status code if negotiation +// fails (or if negotiation should continue), which would prevent other authentication methods +// to execute at all. type SSPI struct{} // Name represents the name of auth method @@ -56,15 +59,10 @@ func (s *SSPI) Name() string { // If negotiation should continue or authentication fails, immediately returns a 401 HTTP // response code, as required by the SPNEGO protocol. func (s *SSPI) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error) { - var errInit error - sspiAuthOnce.Do(func() { - config := websspi.NewConfig() - sspiAuth, errInit = websspi.New(config) - }) - if errInit != nil { - return nil, errInit + sspiAuthOnce.Do(func() { sspiAuthErrInit = sspiAuthInit() }) + if sspiAuthErrInit != nil { + return nil, sspiAuthErrInit } - if !s.shouldAuthenticate(req) { return nil, nil } diff --git a/services/auth/sspiauth_posix.go b/services/auth/sspiauth_posix.go new file mode 100644 index 0000000000..49b0ed4a52 --- /dev/null +++ b/services/auth/sspiauth_posix.go @@ -0,0 +1,30 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +//go:build !windows + +package auth + +import ( + "errors" + "net/http" +) + +type SSPIUserInfo struct { + Username string // Name of user, usually in the form DOMAIN\User + Groups []string // The global groups the user is a member of +} + +type sspiAuthMock struct{} + +func (s sspiAuthMock) AppendAuthenticateHeader(w http.ResponseWriter, data string) { +} + +func (s sspiAuthMock) Authenticate(r *http.Request, w http.ResponseWriter) (userInfo *SSPIUserInfo, outToken string, err error) { + return nil, "", errors.New("not implemented") +} + +func sspiAuthInit() error { + sspiAuth = &sspiAuthMock{} // TODO: we can mock the SSPI auth in tests + return nil +} diff --git a/services/auth/sspiauth_windows.go b/services/auth/sspiauth_windows.go new file mode 100644 index 0000000000..093caaed33 --- /dev/null +++ b/services/auth/sspiauth_windows.go @@ -0,0 +1,19 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +//go:build windows + +package auth + +import ( + "github.com/quasoft/websspi" +) + +type SSPIUserInfo = websspi.UserInfo + +func sspiAuthInit() error { + var err error + config := websspi.NewConfig() + sspiAuth, err = websspi.New(config) + return err +} |