Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/musl.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# Only trigger when a PR is committed.
name: Linux Build Musl Static
#on: [pull_request]
on:
Expand All @@ -7,6 +6,7 @@ on:

jobs:
build:
# Only trigger when a PR is committed.
if: github.event.pull_request.merged
name: Build
runs-on: ubuntu-latest
Expand Down
140 changes: 114 additions & 26 deletions api/authenticators/auth.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package authenticators

import (
"context"
"crypto/x509"
"errors"
"fmt"
Expand All @@ -16,11 +17,21 @@ import (
var (
mu sync.Mutex

// Factory dispatcher
auth_dispatcher = make(map[string]func(
ctx *HTTPClientContext,
config_obj *config_proto.Config,
auth_config *config_proto.Authenticator) (Authenticator, error))

auth_cache Authenticator
)

func ResetAuthCache() {
mu.Lock()
defer mu.Unlock()
auth_cache = nil
}

// All SSO Authenticators implement this interface.
type Authenticator interface {
AddHandlers(mux *utils.ServeMux) error
Expand All @@ -44,11 +55,35 @@ func NewAuthenticator(config_obj *config_proto.Config) (Authenticator, error) {
return nil, errors.New("GUI not configured")
}

return getAuthenticatorByType(config_obj, config_obj.GUI.Authenticator)
mu.Lock()
cached := auth_cache
mu.Unlock()

if cached != nil {
return cached, nil
}

ctx, err := ClientContext(context.Background(), config_obj,
DefaultTransforms(config_obj, config_obj.GUI.Authenticator))
if err != nil {
return nil, err
}

new_auth, err := getAuthenticatorByType(
ctx, config_obj, config_obj.GUI.Authenticator)
if err == nil {
mu.Lock()
auth_cache = new_auth
mu.Unlock()
}

return new_auth, err
}

func RegisterAuthenticator(name string,
handler func(config_obj *config_proto.Config,
handler func(
ctx *HTTPClientContext,
config_obj *config_proto.Config,
auth_config *config_proto.Authenticator) (Authenticator, error)) {
mu.Lock()
defer mu.Unlock()
Expand All @@ -57,14 +92,19 @@ func RegisterAuthenticator(name string,
}

func getAuthenticatorByType(
ctx *HTTPClientContext,
config_obj *config_proto.Config,
auth_config *config_proto.Authenticator) (Authenticator, error) {

mu.Lock()
handler, pres := auth_dispatcher[strings.ToLower(auth_config.Type)]
key := strings.ToLower(auth_config.Type)
handler, pres := auth_dispatcher[key]
mu.Unlock()
if pres {
return handler(config_obj, auth_config)
// Make sure the dispatcher lock is unlocked during call to
// handler - the multi authenticator needs to access the
// other types.
return handler(ctx, config_obj, auth_config)
}
return nil, errors.New("No valid authenticator found")
}
Expand All @@ -79,55 +119,89 @@ func configRequirePublicUrl(config_obj *config_proto.Config) error {
}

func init() {
RegisterAuthenticator("azure", func(config_obj *config_proto.Config,
RegisterAuthenticator("azure", func(
ctx *HTTPClientContext,
config_obj *config_proto.Config,
auth_config *config_proto.Authenticator) (Authenticator, error) {
err := configRequirePublicUrl(config_obj)
if err != nil {
return nil, err
}
return &AzureAuthenticator{
router := &AzureOidcRouter{
config_obj: config_obj,
authenticator: auth_config,
}, nil
}
claims_getter := &AzureClaimsGetter{
config_obj: config_obj,
router: router,
}
return NewOidcAuthenticator(
config_obj, auth_config, router, claims_getter), nil
})

RegisterAuthenticator("github", func(config_obj *config_proto.Config,
RegisterAuthenticator("github", func(
ctx *HTTPClientContext,
config_obj *config_proto.Config,
auth_config *config_proto.Authenticator) (Authenticator, error) {
err := configRequirePublicUrl(config_obj)
if err != nil {
return nil, err
}
return &GitHubAuthenticator{
config_obj: config_obj,
authenticator: auth_config,
}, nil

router := &GithubOidcRouter{
config_obj: config_obj,
}
claims_getter := &GithubClaimsGetter{
config_obj: config_obj,
}
return NewOidcAuthenticator(
config_obj, auth_config, router, claims_getter), nil
})

RegisterAuthenticator("google", func(config_obj *config_proto.Config,
// This is now basically an alias for a generic OIDC connector
// since Google is pretty good about following the standards.
RegisterAuthenticator("google", func(
ctx *HTTPClientContext,
config_obj *config_proto.Config,
auth_config *config_proto.Authenticator) (Authenticator, error) {
err := configRequirePublicUrl(config_obj)
if err != nil {
return nil, err
}
return &GoogleAuthenticator{
config_obj: config_obj,
authenticator: auth_config,
}, nil

router := &GoogleOidcRouter{
config_obj: config_obj,
}

claims_getter, err := NewOidcClaimsGetter(
ctx, config_obj, auth_config, router)
if err != nil {
return nil, err
}

return NewOidcAuthenticator(
config_obj, auth_config, router, claims_getter), nil
})

RegisterAuthenticator("saml", func(config_obj *config_proto.Config,
RegisterAuthenticator("saml", func(
ctx *HTTPClientContext,
config_obj *config_proto.Config,
auth_config *config_proto.Authenticator) (Authenticator, error) {
return NewSamlAuthenticator(config_obj, auth_config)
})

RegisterAuthenticator("basic", func(config_obj *config_proto.Config,
RegisterAuthenticator("basic", func(
ctx *HTTPClientContext,
config_obj *config_proto.Config,
auth_config *config_proto.Authenticator) (Authenticator, error) {
return &BasicAuthenticator{
config_obj: config_obj,
}, nil
})

RegisterAuthenticator("certs", func(config_obj *config_proto.Config,
RegisterAuthenticator("certs", func(
ctx *HTTPClientContext,
config_obj *config_proto.Config,
auth_config *config_proto.Authenticator) (Authenticator, error) {
if config_obj.GUI == nil || config_obj.GUI.UsePlainHttp {
return nil, errors.New("'Certs' authenticator must use TLS!")
Expand All @@ -146,20 +220,34 @@ func init() {
return result, nil
})

RegisterAuthenticator("oidc", func(config_obj *config_proto.Config,
RegisterAuthenticator("oidc", func(
ctx *HTTPClientContext,
config_obj *config_proto.Config,
auth_config *config_proto.Authenticator) (Authenticator, error) {
err := configRequirePublicUrl(config_obj)
if err != nil {
return nil, err
}
return &OidcAuthenticator{
config_obj: config_obj,

router := &DefaultOidcRouter{
authenticator: auth_config,
}, nil
config_obj: config_obj,
}

claims_getter, err := NewOidcClaimsGetter(
ctx, config_obj, auth_config, router)
if err != nil {
return nil, err
}

return NewOidcAuthenticator(
config_obj, auth_config, router, claims_getter), nil
})

RegisterAuthenticator("multi", func(config_obj *config_proto.Config,
RegisterAuthenticator("multi", func(
ctx *HTTPClientContext,
config_obj *config_proto.Config,
auth_config *config_proto.Authenticator) (Authenticator, error) {
return NewMultiAuthenticator(config_obj, auth_config)
return NewMultiAuthenticator(ctx, config_obj, auth_config)
})
}
Loading
Loading