web UI: allow to enable OIDC login and/or login forms
any combination is now supported Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
parent
e6bfbcd489
commit
1470018054
6 changed files with 62 additions and 20 deletions
|
@ -255,7 +255,7 @@ The configuration file contains the following sections:
|
|||
- `address`, string. Leave blank to listen on all available network interfaces. On *NIX you can specify an absolute path to listen on a Unix-domain socket Default: blank.
|
||||
- `enable_web_admin`, boolean. Set to `false` to disable the built-in web admin for this binding. You also need to define `templates_path` and `static_files_path` to use the built-in web admin interface. Default `true`.
|
||||
- `enable_web_client`, boolean. Set to `false` to disable the built-in web client for this binding. You also need to define `templates_path` and `static_files_path` to use the built-in web client interface. Default `true`.
|
||||
- `enabled_login_methods`, integer. Defines the login methods available for the WebAdmin and WebClient UIs. `0` means any configured method: username/password login form and OIDC, if enabled. `1` means OIDC for the WebAdmin UI. The username/password login form will not be available for the WebAdmin UI. `2` means OIDC for the WebClient UI. The username/password login form will not be available for the WebClient UI. You can combine the values. For example `3` means that you can only login using OIDC on both WebClient and WebAdmin UI. Default: `0`.
|
||||
- `enabled_login_methods`, integer. Defines the login methods available for the WebAdmin and WebClient UIs. `0` means any configured method: username/password login form and OIDC, if enabled. `1` means OIDC for the WebAdmin UI. `2` means OIDC for the WebClient UI. `4` means login form for the WebAdmin UI. `8` means login form for the WebClient UI. You can combine the values. For example `3` means that you can only login using OIDC on both WebClient and WebAdmin UI. Default: `0`.
|
||||
- `enable_https`, boolean. Set to `true` and provide both a certificate and a key file to enable HTTPS connection for this binding. Default `false`.
|
||||
- `certificate_file`, string. Binding specific TLS certificate. This can be an absolute path or a path relative to the config dir.
|
||||
- `certificate_key_file`, string. Binding specific private key matching the above certificate. This can be an absolute path or a path relative to the config dir. If not set the global ones will be used, if any.
|
||||
|
|
6
go.mod
6
go.mod
|
@ -67,9 +67,9 @@ require (
|
|||
gocloud.dev v0.25.0
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d
|
||||
golang.org/x/net v0.0.0-20220708220712-1185a9018129
|
||||
golang.org/x/oauth2 v0.0.0-20220718184931-c8730f7fcb92
|
||||
golang.org/x/sys v0.0.0-20220721230656-c6bc011c0c49
|
||||
golang.org/x/time v0.0.0-20220609170525-579cf78fd858
|
||||
golang.org/x/oauth2 v0.0.0-20220722155238-128564f6959c
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f
|
||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9
|
||||
google.golang.org/api v0.88.0
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||
)
|
||||
|
|
12
go.sum
12
go.sum
|
@ -869,8 +869,8 @@ golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j
|
|||
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
|
||||
golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
|
||||
golang.org/x/oauth2 v0.0.0-20220718184931-c8730f7fcb92 h1:oVlhw3Oe+1reYsE2Nqu19PDJfLzwdU3QUUrG86rLK68=
|
||||
golang.org/x/oauth2 v0.0.0-20220718184931-c8730f7fcb92/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
|
||||
golang.org/x/oauth2 v0.0.0-20220722155238-128564f6959c h1:q3gFqPqH7NVofKo3c3yETAP//pPI+G5mvB7qqj1Y5kY=
|
||||
golang.org/x/oauth2 v0.0.0-20220722155238-128564f6959c/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -970,8 +970,8 @@ golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220721230656-c6bc011c0c49 h1:TMjZDarEwf621XDryfitp/8awEhiZNiwgphKlTMGRIg=
|
||||
golang.org/x/sys v0.0.0-20220721230656-c6bc011c0c49/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
|
@ -990,8 +990,8 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb
|
|||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U=
|
||||
golang.org/x/time v0.0.0-20220609170525-579cf78fd858/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 h1:ftMN5LMiBFjbzleLqtoBZk7KdJwhuybIU+FckUHgoyQ=
|
||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
|
|
|
@ -413,8 +413,10 @@ type Binding struct {
|
|||
// Defines the login methods available for the WebAdmin and WebClient UIs:
|
||||
//
|
||||
// - 0 means any configured method: username/password login form and OIDC, if enabled
|
||||
// - 1 means OIDC for the WebAdmin UI. The username/password login form will not be available
|
||||
// - 2 means OIDC for the WebClient UI. The username/password login form will not be available
|
||||
// - 1 means OIDC for the WebAdmin UI
|
||||
// - 2 means OIDC for the WebClient UI
|
||||
// - 4 means login form for the WebAdmin UI
|
||||
// - 8 means login form for the WebClient UI
|
||||
//
|
||||
// You can combine the values. For example 3 means that you can only login using OIDC on
|
||||
// both WebClient and WebAdmin UI.
|
||||
|
@ -529,12 +531,32 @@ func (b *Binding) IsValid() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (b *Binding) isWebAdminOIDCLoginDisabled() bool {
|
||||
if b.EnableWebAdmin {
|
||||
if b.EnabledLoginMethods == 0 {
|
||||
return false
|
||||
}
|
||||
return b.EnabledLoginMethods&1 == 0
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (b *Binding) isWebClientOIDCLoginDisabled() bool {
|
||||
if b.EnableWebClient {
|
||||
if b.EnabledLoginMethods == 0 {
|
||||
return false
|
||||
}
|
||||
return b.EnabledLoginMethods&2 == 0
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (b *Binding) isWebAdminLoginFormDisabled() bool {
|
||||
if b.EnableWebAdmin {
|
||||
if b.EnabledLoginMethods == 0 {
|
||||
return false
|
||||
}
|
||||
return b.EnabledLoginMethods&1 != 0
|
||||
return b.EnabledLoginMethods&4 == 0
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -544,18 +566,28 @@ func (b *Binding) isWebClientLoginFormDisabled() bool {
|
|||
if b.EnabledLoginMethods == 0 {
|
||||
return false
|
||||
}
|
||||
return b.EnabledLoginMethods&2 != 0
|
||||
return b.EnabledLoginMethods&8 == 0
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (b *Binding) checkLoginMethods() error {
|
||||
if b.isWebAdminLoginFormDisabled() && b.isWebAdminOIDCLoginDisabled() {
|
||||
return errors.New("no login method available for WebAdmin UI")
|
||||
}
|
||||
if !b.isWebAdminOIDCLoginDisabled() {
|
||||
if b.isWebAdminLoginFormDisabled() && !b.OIDC.hasRoles() {
|
||||
return errors.New("no login method available for WebAdmin UI")
|
||||
}
|
||||
}
|
||||
if b.isWebClientLoginFormDisabled() && b.isWebClientOIDCLoginDisabled() {
|
||||
return errors.New("no login method available for WebClient UI")
|
||||
}
|
||||
if !b.isWebClientOIDCLoginDisabled() {
|
||||
if b.isWebClientLoginFormDisabled() && !b.OIDC.isEnabled() {
|
||||
return errors.New("no login method available for WebClient UI")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -533,6 +533,16 @@ func TestInitialization(t *testing.T) {
|
|||
}
|
||||
httpdConf.Bindings[0].EnabledLoginMethods = 2
|
||||
err = httpdConf.Initialize(configDir, isShared)
|
||||
if assert.Error(t, err) {
|
||||
assert.Contains(t, err.Error(), "no login method available for WebAdmin UI")
|
||||
}
|
||||
httpdConf.Bindings[0].EnabledLoginMethods = 6
|
||||
err = httpdConf.Initialize(configDir, isShared)
|
||||
if assert.Error(t, err) {
|
||||
assert.Contains(t, err.Error(), "no login method available for WebClient UI")
|
||||
}
|
||||
httpdConf.Bindings[0].EnabledLoginMethods = 4
|
||||
err = httpdConf.Initialize(configDir, isShared)
|
||||
if assert.Error(t, err) {
|
||||
assert.Contains(t, err.Error(), "no login method available for WebClient UI")
|
||||
}
|
||||
|
|
|
@ -174,7 +174,7 @@ func (s *httpdServer) renderClientLoginPage(w http.ResponseWriter, error, ip str
|
|||
if smtp.IsEnabled() && !data.FormDisabled {
|
||||
data.ForgotPwdURL = webClientForgotPwdPath
|
||||
}
|
||||
if s.binding.OIDC.isEnabled() {
|
||||
if s.binding.OIDC.isEnabled() && !s.binding.isWebClientOIDCLoginDisabled() {
|
||||
data.OpenIDLoginURL = webClientOIDCLoginPath
|
||||
}
|
||||
renderClientTemplate(w, templateClientLogin, data)
|
||||
|
@ -552,7 +552,7 @@ func (s *httpdServer) renderAdminLoginPage(w http.ResponseWriter, error, ip stri
|
|||
if smtp.IsEnabled() && !data.FormDisabled {
|
||||
data.ForgotPwdURL = webAdminForgotPwdPath
|
||||
}
|
||||
if s.binding.OIDC.hasRoles() {
|
||||
if s.binding.OIDC.hasRoles() && !s.binding.isWebAdminOIDCLoginDisabled() {
|
||||
data.OpenIDLoginURL = webAdminOIDCLoginPath
|
||||
}
|
||||
renderAdminTemplate(w, templateLogin, data)
|
||||
|
@ -1396,7 +1396,7 @@ func (s *httpdServer) setupWebClientRoutes() {
|
|||
http.Redirect(w, r, webClientLoginPath, http.StatusFound)
|
||||
})
|
||||
s.router.Get(webClientLoginPath, s.handleClientWebLogin)
|
||||
if s.binding.OIDC.isEnabled() {
|
||||
if s.binding.OIDC.isEnabled() && !s.binding.isWebClientOIDCLoginDisabled() {
|
||||
s.router.Get(webClientOIDCLoginPath, s.handleWebClientOIDCLogin)
|
||||
}
|
||||
if !s.binding.isWebClientLoginFormDisabled() {
|
||||
|
@ -1497,7 +1497,7 @@ func (s *httpdServer) setupWebAdminRoutes() {
|
|||
s.redirectToWebPath(w, r, webAdminLoginPath)
|
||||
})
|
||||
s.router.Get(webAdminLoginPath, s.handleWebAdminLogin)
|
||||
if s.binding.OIDC.hasRoles() {
|
||||
if s.binding.OIDC.hasRoles() && !s.binding.isWebAdminOIDCLoginDisabled() {
|
||||
s.router.Get(webAdminOIDCLoginPath, s.handleWebAdminOIDCLogin)
|
||||
}
|
||||
s.router.Get(webAdminSetupPath, s.handleWebAdminSetupGet)
|
||||
|
|
Loading…
Reference in a new issue