Add a new method Match for auth

This commit is contained in:
Lunny Xiao 2024-11-15 23:29:17 -08:00
parent e546480d0a
commit 5ac876a728
No known key found for this signature in database
GPG Key ID: C3B7C91B632F738A
12 changed files with 58 additions and 4 deletions

View File

@ -52,6 +52,10 @@ func (a *Auth) Name() string {
return "chef" return "chef"
} }
func (a *Auth) Match(req *http.Request) bool {
return true
}
// Verify extracts the user from the signed request // Verify extracts the user from the signed request
// If the request is signed with the user private key the user is verified. // If the request is signed with the user private key the user is verified.
func (a *Auth) Verify(req *http.Request, w http.ResponseWriter, store auth.DataStore, sess auth.SessionStore) (*user_model.User, error) { func (a *Auth) Verify(req *http.Request, w http.ResponseWriter, store auth.DataStore, sess auth.SessionStore) (*user_model.User, error) {

View File

@ -20,6 +20,10 @@ func (a *Auth) Name() string {
return "conan" return "conan"
} }
func (a *Auth) Match(req *http.Request) bool {
return true
}
// Verify extracts the user from the Bearer token // Verify extracts the user from the Bearer token
func (a *Auth) Verify(req *http.Request, w http.ResponseWriter, store auth.DataStore, sess auth.SessionStore) (*user_model.User, error) { func (a *Auth) Verify(req *http.Request, w http.ResponseWriter, store auth.DataStore, sess auth.SessionStore) (*user_model.User, error) {
packageMeta, err := packages.ParseAuthorizationRequest(req) packageMeta, err := packages.ParseAuthorizationRequest(req)

View File

@ -20,6 +20,10 @@ func (a *Auth) Name() string {
return "container" return "container"
} }
func (a *Auth) Match(req *http.Request) bool {
return true
}
// Verify extracts the user from the Bearer token // Verify extracts the user from the Bearer token
// If it's an anonymous session a ghost user is returned // If it's an anonymous session a ghost user is returned
func (a *Auth) Verify(req *http.Request, w http.ResponseWriter, store auth.DataStore, sess auth.SessionStore) (*user_model.User, error) { func (a *Auth) Verify(req *http.Request, w http.ResponseWriter, store auth.DataStore, sess auth.SessionStore) (*user_model.User, error) {

View File

@ -21,6 +21,10 @@ func (a *Auth) Name() string {
return "nuget" return "nuget"
} }
func (a *Auth) Match(req *http.Request) bool {
return true
}
// https://docs.microsoft.com/en-us/nuget/api/package-publish-resource#request-parameters // https://docs.microsoft.com/en-us/nuget/api/package-publish-resource#request-parameters
func (a *Auth) Verify(req *http.Request, w http.ResponseWriter, store auth.DataStore, sess auth.SessionStore) (*user_model.User, error) { func (a *Auth) Verify(req *http.Request, w http.ResponseWriter, store auth.DataStore, sess auth.SessionStore) (*user_model.User, error) {
token, err := auth_model.GetAccessTokenBySHA(req.Context(), req.Header.Get("X-NuGet-ApiKey")) token, err := auth_model.GetAccessTokenBySHA(req.Context(), req.Header.Get("X-NuGet-ApiKey"))

View File

@ -42,6 +42,10 @@ func (b *Basic) Name() string {
return BasicMethodName return BasicMethodName
} }
func (b *Basic) Match(req *http.Request) bool {
return true
}
// Verify extracts and validates Basic data (username and password/token) from the // Verify extracts and validates Basic data (username and password/token) from the
// "Authorization" header of the request and returns the corresponding user object for that // "Authorization" header of the request and returns the corresponding user object for that
// name/token on successful validation. // name/token on successful validation.

View File

@ -41,10 +41,22 @@ func (b *Group) Name() string {
return strings.Join(names, ",") return strings.Join(names, ",")
} }
func (b *Group) Match(req *http.Request) bool {
return true
}
func (b *Group) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error) { 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 // find all methods that match the request
var retErr error matchedMethods := make([]Method, 0, len(b.methods))
for _, m := range b.methods { for _, m := range b.methods {
if m.Match(req) {
matchedMethods = append(matchedMethods, m)
}
}
var retErr error
// Try to sign in with each of the matched plugins
for _, m := range matchedMethods {
user, err := m.Verify(req, w, store, sess) user, err := m.Verify(req, w, store, sess)
if err != nil { if err != nil {
if retErr == nil { if retErr == nil {

View File

@ -36,6 +36,10 @@ func (h *HTTPSign) Name() string {
return "httpsign" return "httpsign"
} }
func (h *HTTPSign) Match(req *http.Request) bool {
return true
}
// Verify extracts and validates HTTPsign from the Signature header of the request and returns // Verify extracts and validates HTTPsign from the Signature header of the request and returns
// the corresponding user object on successful validation. // the corresponding user object on successful validation.
// Returns nil if header is empty or validation fails. // Returns nil if header is empty or validation fails.

View File

@ -24,10 +24,12 @@ type Method interface {
// If verification is successful returns either an existing user object (with id > 0) // If verification is successful returns either an existing user object (with id > 0)
// or a new user object (with id = 0) populated with the information that was found // or a new user object (with id = 0) populated with the information that was found
// in the authentication data (username or email). // in the authentication data (username or email).
// Second argument returns err if verification fails, otherwise // Third argument returns err if verification fails, otherwise
// Second return argument returns true
// First return argument returns nil if no matched verification condition // First return argument returns nil if no matched verification condition
Verify(http *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error) Verify(http *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error)
// Match returns true if the request is a match for this method
Match(*http.Request) bool
Name() string Name() string
} }

View File

@ -131,6 +131,10 @@ func (o *OAuth2) userIDFromToken(ctx context.Context, tokenSHA string, store Dat
return t.UID return t.UID
} }
func (o *OAuth2) Match(req *http.Request) bool {
return true
}
// Verify extracts the user ID from the OAuth token in the query parameters // Verify extracts the user ID from the OAuth token in the query parameters
// or the "Authorization" header and returns the corresponding user object for that ID. // or the "Authorization" header and returns the corresponding user object for that ID.
// If verification is successful returns an existing user object. // If verification is successful returns an existing user object.

View File

@ -100,6 +100,10 @@ func (r *ReverseProxy) getUserFromAuthEmail(req *http.Request) *user_model.User
return user return user
} }
func (r *ReverseProxy) Match(req *http.Request) bool {
return true
}
// Verify attempts to load a user object based on headers sent by the reverse proxy. // Verify attempts to load a user object based on headers sent by the reverse proxy.
// First it will attempt to load it based on the username (see docs for getUserFromAuthUser), // First it will attempt to load it based on the username (see docs for getUserFromAuthUser),
// and failing that it will attempt to load it based on the email (see docs for getUserFromAuthEmail). // and failing that it will attempt to load it based on the email (see docs for getUserFromAuthEmail).

View File

@ -24,6 +24,10 @@ func (s *Session) Name() string {
return "session" return "session"
} }
func (s *Session) Match(req *http.Request) bool {
return true
}
// Verify checks if there is a user uid stored in the session and returns the user // Verify checks if there is a user uid stored in the session and returns the user
// object for that uid. // object for that uid.
// Returns nil if there is no user uid stored in the session. // Returns nil if there is no user uid stored in the session.

View File

@ -54,6 +54,10 @@ func (s *SSPI) Name() string {
return "sspi" return "sspi"
} }
func (s *SSPI) Match(req *http.Request) bool {
return true
}
// Verify uses SSPI (Windows implementation of SPNEGO) to authenticate the request. // Verify uses SSPI (Windows implementation of SPNEGO) to authenticate the request.
// If authentication is successful, returns the corresponding user object. // If authentication is successful, returns the corresponding user object.
// If negotiation should continue or authentication fails, immediately returns a 401 HTTP // If negotiation should continue or authentication fails, immediately returns a 401 HTTP