Refactored auth settings
Auth settings update/reload reimplemented to remove the need for restart after initial run and settings autodiscovery
This commit is contained in:
Vendored
+2
-2
@@ -24,7 +24,7 @@ const (
|
||||
WellKnown = "/.well-known/openid-configuration"
|
||||
)
|
||||
|
||||
func setupGoth(as service.AuthSettings) {
|
||||
func setupGoth(as *service.AuthSettings) {
|
||||
if !as.ExternalEnabled {
|
||||
log().Info("external authentication disabled")
|
||||
return
|
||||
@@ -47,7 +47,7 @@ func setupGoth(as service.AuthSettings) {
|
||||
|
||||
}
|
||||
|
||||
func setupGothProviders(as service.AuthSettings) {
|
||||
func setupGothProviders(as *service.AuthSettings) {
|
||||
var (
|
||||
err error
|
||||
scopes = []string{"email"}
|
||||
|
||||
Vendored
+1
-1
@@ -50,7 +50,7 @@ func AddProvider(name string, eap *service.AuthSettingsExternalAuthProvider, for
|
||||
|
||||
// @todo remove dependency on github.com/crusttech/go-oidc (and github.com/coreos/go-oidc)
|
||||
// and move client registration to corteza codebase
|
||||
func DiscoverOidcProvider(ctx context.Context, eas service.AuthSettings, name, url string) (eap *service.AuthSettingsExternalAuthProvider, err error) {
|
||||
func DiscoverOidcProvider(ctx context.Context, eas *service.AuthSettings, name, url string) (eap *service.AuthSettingsExternalAuthProvider, err error) {
|
||||
var (
|
||||
provider *oidc.Provider
|
||||
client *oidc.Client
|
||||
|
||||
@@ -29,7 +29,7 @@ type (
|
||||
credentials repository.CredentialsRepository
|
||||
users repository.UserRepository
|
||||
roles repository.RoleRepository
|
||||
settings AuthSettings
|
||||
settings *AuthSettings
|
||||
notifications AuthNotificationService
|
||||
|
||||
providerValidator func(string) error
|
||||
|
||||
@@ -18,7 +18,7 @@ type (
|
||||
ctx context.Context
|
||||
logger *zap.Logger
|
||||
|
||||
settings AuthSettings
|
||||
settings *AuthSettings
|
||||
}
|
||||
|
||||
AuthNotificationService interface {
|
||||
@@ -107,16 +107,16 @@ var (
|
||||
|
||||
func AuthNotification(ctx context.Context) AuthNotificationService {
|
||||
return (&authNotification{
|
||||
logger: DefaultLogger.Named("auth-notification"),
|
||||
logger: DefaultLogger.Named("auth-notification"),
|
||||
settings: DefaultAuthSettings,
|
||||
}).With(ctx)
|
||||
}
|
||||
|
||||
func (svc authNotification) With(ctx context.Context) AuthNotificationService {
|
||||
return &authNotification{
|
||||
ctx: ctx,
|
||||
logger: svc.logger,
|
||||
|
||||
settings: DefaultAuthSettings,
|
||||
ctx: ctx,
|
||||
logger: svc.logger,
|
||||
settings: svc.settings,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -71,29 +71,33 @@ type (
|
||||
// ParseAuthSettings maps from plain values to AuthSettings struct
|
||||
//
|
||||
// see settings.Initialize() func
|
||||
func ParseAuthSettings(kv intset.KV) (as AuthSettings, err error) {
|
||||
as = AuthSettings{
|
||||
FrontendUrlPasswordReset: kv.String("auth.frontend.url.password-reset"),
|
||||
FrontendUrlEmailConfirmation: kv.String("auth.frontend.url.email-confirmation"),
|
||||
FrontendUrlRedirect: kv.String("auth.frontend.url.redirect"),
|
||||
FrontendUrlBase: kv.String("auth.frontend.url.base"),
|
||||
func ParseAuthSettings(kv intset.KV) (as *AuthSettings, err error) {
|
||||
as = &AuthSettings{}
|
||||
as.ReadKV(kv)
|
||||
return
|
||||
}
|
||||
|
||||
MailFromAddress: kv.String("auth.mail.from-address"),
|
||||
MailFromName: kv.String("auth.mail.from-name"),
|
||||
func (as *AuthSettings) ReadKV(kv intset.KV) (err error) {
|
||||
as.FrontendUrlPasswordReset = kv.String("auth.frontend.url.password-reset")
|
||||
as.FrontendUrlEmailConfirmation = kv.String("auth.frontend.url.email-confirmation")
|
||||
as.FrontendUrlRedirect = kv.String("auth.frontend.url.redirect")
|
||||
as.FrontendUrlBase = kv.String("auth.frontend.url.base")
|
||||
|
||||
InternalEnabled: kv.Bool("auth.internal.enabled"),
|
||||
as.MailFromAddress = kv.String("auth.mail.from-address")
|
||||
as.MailFromName = kv.String("auth.mail.from-name")
|
||||
|
||||
InternalSignUpEnabled: kv.Bool("auth.internal.signup.enabled"),
|
||||
InternalSignUpEmailConfirmationRequired: kv.Bool("auth.internal.signup-email-confirmation-required"),
|
||||
as.InternalEnabled = kv.Bool("auth.internal.enabled")
|
||||
|
||||
InternalPasswordResetEnabled: kv.Bool("auth.internal.password-reset.enabled"),
|
||||
as.InternalSignUpEnabled = kv.Bool("auth.internal.signup.enabled")
|
||||
as.InternalSignUpEmailConfirmationRequired = kv.Bool("auth.internal.signup-email-confirmation-required")
|
||||
|
||||
ExternalEnabled: kv.Bool("auth.external.enabled"),
|
||||
as.InternalPasswordResetEnabled = kv.Bool("auth.internal.password-reset.enabled")
|
||||
|
||||
ExternalRedirectUrl: kv.String("auth.external.redirect-url"),
|
||||
ExternalSessionStoreSecret: kv.String("auth.external.session-store-secret"),
|
||||
ExternalSessionStoreSecure: kv.Bool("auth.external.session-store-secure"),
|
||||
}
|
||||
as.ExternalEnabled = kv.Bool("auth.external.enabled")
|
||||
|
||||
as.ExternalRedirectUrl = kv.String("auth.external.redirect-url")
|
||||
as.ExternalSessionStoreSecret = kv.String("auth.external.session-store-secret")
|
||||
as.ExternalSessionStoreSecure = kv.Bool("auth.external.session-store-secure")
|
||||
|
||||
as.ExternalProviders, err = as.parseExternalProviders(kv)
|
||||
|
||||
|
||||
@@ -32,6 +32,10 @@ func makeMockAuthService(u repository.UserRepository, c repository.CredentialsRe
|
||||
return nil
|
||||
},
|
||||
|
||||
logger: zap.NewNop(),
|
||||
|
||||
settings: &AuthSettings{},
|
||||
|
||||
now: func() *time.Time {
|
||||
return nil
|
||||
},
|
||||
@@ -64,7 +68,6 @@ func TestAuth_External_Existing(t *testing.T) {
|
||||
usrRpoMock.EXPECT().FindByID(u.ID).Times(1).Return(u, nil)
|
||||
|
||||
svc := makeMockAuthService(usrRpoMock, crdRpoMock)
|
||||
svc.logger = zap.NewNop()
|
||||
svc.settings.ExternalEnabled = true
|
||||
|
||||
{
|
||||
@@ -110,7 +113,6 @@ func TestAuth_External_NonExisting(t *testing.T) {
|
||||
Return(uint(0))
|
||||
|
||||
svc := makeMockAuthService(usrRpoMock, crdRpoMock)
|
||||
svc.logger = zap.NewNop()
|
||||
svc.settings.ExternalEnabled = true
|
||||
|
||||
{
|
||||
@@ -135,9 +137,13 @@ func Test_auth_validateInternalLogin(t *testing.T) {
|
||||
{name: "no pass", args: args{"test@domain.tld", ""}, wantErr: true},
|
||||
{name: "all good", args: args{"test@domain.tld", "password"}, wantErr: false},
|
||||
}
|
||||
svc := auth{}
|
||||
svc.logger = zap.NewNop()
|
||||
svc.settings.InternalEnabled = true
|
||||
|
||||
svc := auth{
|
||||
logger: zap.NewNop(),
|
||||
settings: &AuthSettings{
|
||||
InternalEnabled: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
@@ -194,8 +200,12 @@ func Test_auth_checkPassword(t *testing.T) {
|
||||
&types.Credentials{ID: 3, Credentials: ""},
|
||||
}}},
|
||||
}
|
||||
svc := auth{}
|
||||
svc.logger = zap.NewNop()
|
||||
|
||||
svc := auth{
|
||||
logger: zap.NewNop(),
|
||||
settings: &AuthSettings{},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if err := svc.checkPassword(tt.args.password, tt.args.cc); (err != nil) != tt.wantErr {
|
||||
|
||||
@@ -63,7 +63,7 @@ var (
|
||||
DefaultAutomationRunner automationRunner
|
||||
|
||||
DefaultAuthNotification AuthNotificationService
|
||||
DefaultAuthSettings AuthSettings
|
||||
DefaultAuthSettings *AuthSettings
|
||||
|
||||
DefaultSink *sink
|
||||
|
||||
@@ -98,6 +98,7 @@ func Init(ctx context.Context, log *zap.Logger, c Config) (err error) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
DefaultAuthNotification = AuthNotification(ctx)
|
||||
DefaultAuth = Auth(ctx)
|
||||
|
||||
|
||||
@@ -35,7 +35,8 @@ type (
|
||||
BulkSet(vv internalSettings.ValueSet) (err error)
|
||||
Get(name string, ownedBy uint64) (out *internalSettings.Value, err error)
|
||||
|
||||
LoadAuthSettings() (AuthSettings, error)
|
||||
LoadAuthSettings() (*AuthSettings, error)
|
||||
UpdateAuthSettings(*AuthSettings) error
|
||||
AutoDiscovery() error
|
||||
}
|
||||
)
|
||||
@@ -99,12 +100,18 @@ func (svc settings) Get(name string, ownedBy uint64) (out *internalSettings.Valu
|
||||
}
|
||||
|
||||
// Loads auth.% settings, initializes & fills auth settings struct
|
||||
func (svc settings) LoadAuthSettings() (AuthSettings, error) {
|
||||
func (svc settings) LoadAuthSettings() (*AuthSettings, error) {
|
||||
as := &AuthSettings{}
|
||||
return as, svc.UpdateAuthSettings(as)
|
||||
}
|
||||
|
||||
func (svc settings) UpdateAuthSettings(as *AuthSettings) error {
|
||||
vv, err := svc.internalSettings.FindByPrefix("auth.")
|
||||
if err != nil {
|
||||
return AuthSettings{}, err
|
||||
return err
|
||||
}
|
||||
return ParseAuthSettings(vv.KV())
|
||||
|
||||
return as.ReadKV(vv.KV())
|
||||
}
|
||||
|
||||
// AutoDiscovery orchestrates settings auto discovery
|
||||
|
||||
@@ -29,7 +29,7 @@ type (
|
||||
ctx context.Context
|
||||
logger *zap.Logger
|
||||
|
||||
settings AuthSettings
|
||||
settings *AuthSettings
|
||||
|
||||
auth userAuth
|
||||
|
||||
|
||||
+2
-2
@@ -65,13 +65,13 @@ func Configure() *cli.Config {
|
||||
|
||||
// Reload auto-configured settings
|
||||
// adding externals and oidc auto discovery depends on redirect-url setting
|
||||
service.DefaultAuthSettings, _ = service.DefaultSettings.LoadAuthSettings()
|
||||
cli.HandleError(service.DefaultSettings.UpdateAuthSettings(service.DefaultAuthSettings))
|
||||
|
||||
cli.HandleError(authAddExternals(ctx, cmd, c))
|
||||
cli.HandleError(oidcAutoDiscovery(ctx, cmd, c))
|
||||
|
||||
// Reload auto-configured settings
|
||||
service.DefaultAuthSettings, _ = service.DefaultSettings.LoadAuthSettings()
|
||||
cli.HandleError(service.DefaultSettings.UpdateAuthSettings(service.DefaultAuthSettings))
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user