summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorwxiaoguang <wxiaoguang@gmail.com>2023-09-18 07:32:56 +0800
committerGitHub <noreply@github.com>2023-09-17 23:32:56 +0000
commit8531ca08372dd4a4739564dec17766fffe34a385 (patch)
treea6c05c2083d71230bab7768d205e7fbfedcebd4c /services
parent47b878858ada27fc4c74eeadcc1e467d2da90e04 (diff)
downloadgitea-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.go30
-rw-r--r--services/auth/sspiauth_windows.go19
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
+}