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

Refactor web package and context package (#25298)

1. The "web" package shouldn't depends on "modules/context" package,
instead, let each "web context" register themselves to the "web"
package.
2. The old Init/Free doesn't make sense, so simplify it
* The ctx in "Init(ctx)" is never used, and shouldn't be used that way
* The "Free" is never called and shouldn't be called because the SSPI
instance is shared

---------

Co-authored-by: Giteabot <teabot@gitea.io>
This commit is contained in:
wxiaoguang
2023-06-18 15:59:09 +08:00
committed by GitHub
parent fc2115b494
commit 4e2f1ee58d
45 changed files with 218 additions and 292 deletions

View File

@@ -4,7 +4,6 @@
package auth
import (
"context"
"net/http"
"reflect"
"strings"
@@ -14,9 +13,7 @@ import (
// Ensure the struct implements the interface.
var (
_ Method = &Group{}
_ Initializable = &Group{}
_ Freeable = &Group{}
_ Method = &Group{}
)
// Group implements the Auth interface with serval Auth.
@@ -49,35 +46,6 @@ func (b *Group) Name() string {
return strings.Join(names, ",")
}
// Init does nothing as the Basic implementation does not need to allocate any resources
func (b *Group) Init(ctx context.Context) error {
for _, method := range b.methods {
initializable, ok := method.(Initializable)
if !ok {
continue
}
if err := initializable.Init(ctx); err != nil {
return err
}
}
return nil
}
// Free does nothing as the Basic implementation does not have to release any resources
func (b *Group) Free() error {
for _, method := range b.methods {
freeable, ok := method.(Freeable)
if !ok {
continue
}
if err := freeable.Free(); err != nil {
return err
}
}
return nil
}
// Verify extracts and validates
func (b *Group) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error) {
// Try to sign in with each of the enabled plugins

View File

@@ -29,26 +29,11 @@ type Method interface {
Verify(http *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error)
}
// Initializable represents a structure that requires initialization
// It usually should only be called once before anything else is called
type Initializable interface {
// Init should be called exactly once before using any of the other methods,
// in order to allow the plugin to allocate necessary resources
Init(ctx context.Context) error
}
// Named represents a named thing
type Named interface {
Name() string
}
// Freeable represents a structure that is required to be freed
type Freeable interface {
// Free should be called exactly once before application closes, in order to
// give chance to the plugin to free any allocated resources
Free() error
}
// PasswordAuthenticator represents a source of authentication
type PasswordAuthenticator interface {
Authenticate(user *user_model.User, login, password string) (*user_model.User, error)

View File

@@ -4,10 +4,10 @@
package auth
import (
"context"
"errors"
"net/http"
"strings"
"sync"
"code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/avatars"
@@ -32,13 +32,12 @@ 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
sspiAuth *websspi.Authenticator
sspiAuthOnce sync.Once
// Ensure the struct implements the interface.
_ Method = &SSPI{}
_ Named = &SSPI{}
_ Initializable = &SSPI{}
_ Freeable = &SSPI{}
_ Method = &SSPI{}
_ Named = &SSPI{}
)
// SSPI implements the SingleSignOn interface and authenticates requests
@@ -47,32 +46,25 @@ var (
// Returns nil if authentication fails.
type SSPI struct{}
// Init creates a new global websspi.Authenticator object
func (s *SSPI) Init(ctx context.Context) error {
config := websspi.NewConfig()
var err error
sspiAuth, err = websspi.New(config)
if err != nil {
return err
}
return nil
}
// Name represents the name of auth method
func (s *SSPI) Name() string {
return "sspi"
}
// Free releases resources used by the global websspi.Authenticator object
func (s *SSPI) Free() error {
return sspiAuth.Free()
}
// Verify uses SSPI (Windows implementation of SPNEGO) to authenticate the request.
// If authentication is successful, returns the corresponding user object.
// 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
}
if !s.shouldAuthenticate(req) {
return nil, nil
}