Skip to content

Commit

Permalink
Added option to restrict OIDC users and groups better with custom sco…
Browse files Browse the repository at this point in the history
…pes, better OIDC error handling, try silent OIDC consent first before showing prompt, fixed download button symbol on e2esetup
  • Loading branch information
Forceu committed Jan 19, 2024
1 parent 0c67f4d commit 9083ac3
Show file tree
Hide file tree
Showing 13 changed files with 445 additions and 110 deletions.
8 changes: 7 additions & 1 deletion internal/configuration/configupgrade/Upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

// CurrentConfigVersion is the version of the configuration structure. Used for upgrading
const CurrentConfigVersion = 16
const CurrentConfigVersion = 17

// DoUpgrade checks if an old version is present and updates it to the current version if required
func DoUpgrade(settings *models.Configuration, env *environment.Environment) bool {
Expand Down Expand Up @@ -58,6 +58,12 @@ func updateConfig(settings *models.Configuration, env *environment.Environment)
database.SaveApiKey(apikey)
}
}
// < v1.8.2
if settings.ConfigVersion < 17 {
if len(settings.Authentication.OAuthUsers) > 0 {
settings.Authentication.OAuthUserScope = "email"
}
}
}

// migrateToSqlite copies the content of the old bitcask database to a new sqlite database
Expand Down
61 changes: 54 additions & 7 deletions internal/configuration/setup/Setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,12 +186,17 @@ func getFormValueString(formObjects *[]jsonFormObject, key string) (string, erro
func getFormValueBool(formObjects *[]jsonFormObject, key string) (bool, error) {
value, err := getFormValueString(formObjects, key)
if err != nil {
return false, err
valueHidden, err2 := getFormValueString(formObjects, key+".unchecked")
if err2 != nil {
return false, err
} else {
value = valueHidden
}
}
if value == "0" {
if value == "0" || value == "false" {
return false, nil
}
if value == "1" {
if value == "1" || value == "true" {
return true, nil
}
return false, errors.New("could not convert " + key + " to bool, got: " + value)
Expand Down Expand Up @@ -285,10 +290,13 @@ func parseBasicAuthSettings(result *models.Configuration, formObjects *[]jsonFor

func parseOAuthSettings(result *models.Configuration, formObjects *[]jsonFormObject) error {
var err error
result.Authentication.OauthProvider, err = getFormValueString(formObjects, "oauth_provider")
result.Authentication.OAuthProvider, err = getFormValueString(formObjects, "oauth_provider")
if err != nil {
return err
}
if strings.HasSuffix(result.Authentication.OAuthProvider, "/") {
result.Authentication.OAuthProvider = strings.TrimRight(result.Authentication.OAuthProvider, "/")
}

result.Authentication.OAuthClientId, err = getFormValueString(formObjects, "oauth_id")
if err != nil {
Expand All @@ -300,11 +308,48 @@ func parseOAuthSettings(result *models.Configuration, formObjects *[]jsonFormObj
return err
}

oauthAllowedUsers, err := getFormValueString(formObjects, "oauth_header_users")
restrictUsers, err := getFormValueBool(formObjects, "oauth_restrict_users")
if err != nil {
return err
}
result.Authentication.OauthUsers = splitAndTrim(oauthAllowedUsers)

scopeUsers, err := getFormValueString(formObjects, "oauth_scope_users")
if err != nil {
return err
}

oauthAllowedUsers, err := getFormValueString(formObjects, "oauth_allowed_users")
if err != nil {
return err
}
if restrictUsers {
result.Authentication.OAuthUserScope = scopeUsers
result.Authentication.OAuthUsers = splitAndTrim(oauthAllowedUsers)
} else {
result.Authentication.OAuthUsers = []string{}
result.Authentication.OAuthUserScope = ""
}

restrictGroups, err := getFormValueBool(formObjects, "oauth_restrict_groups")
if err != nil {
return err
}
oauthAllowedGroups, err := getFormValueString(formObjects, "oauth_allowed_groups")
if err != nil {
return err
}
scopeGroups, err := getFormValueString(formObjects, "oauth_scope_groups")
if err != nil {
return err
}
if restrictGroups {
result.Authentication.OAuthGroupScope = scopeGroups
result.Authentication.OAuthGroups = splitAndTrim(oauthAllowedGroups)
} else {
result.Authentication.OAuthGroups = []string{}
result.Authentication.OAuthGroupScope = ""
}

return nil
}

Expand Down Expand Up @@ -532,6 +577,7 @@ type setupView struct {
IsDocker bool
Port int
OAuthUsers string
OAuthGroups string
HeaderUsers string
Auth models.AuthenticationConfig
Settings models.Configuration
Expand All @@ -552,7 +598,8 @@ func (v *setupView) loadFromConfig() {
v.Settings = *settings
v.Auth = settings.Authentication
v.CloudSettings, _ = cloudconfig.Load()
v.OAuthUsers = strings.Join(settings.Authentication.OauthUsers, ";")
v.OAuthUsers = strings.Join(settings.Authentication.OAuthUsers, ";")
v.OAuthGroups = strings.Join(settings.Authentication.OAuthGroups, ";")
v.HeaderUsers = strings.Join(settings.Authentication.HeaderUsers, ";")

if strings.Contains(settings.Port, "localhost") || strings.Contains(settings.Port, "127.0.0.1") {
Expand Down
84 changes: 49 additions & 35 deletions internal/configuration/setup/Setup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,10 +325,10 @@ func TestIntegration(t *testing.T) {
settings := configuration.Get()
test.IsEqualInt(t, settings.Authentication.Method, 0)
test.IsEqualString(t, settings.Authentication.Username, "admin")
test.IsEqualString(t, settings.Authentication.OauthProvider, "")
test.IsEqualString(t, settings.Authentication.OAuthProvider, "")
test.IsEqualString(t, settings.Authentication.OAuthClientId, "")
test.IsEqualString(t, settings.Authentication.OAuthClientSecret, "")
test.IsEqualInt(t, len(settings.Authentication.OauthUsers), 0)
test.IsEqualInt(t, len(settings.Authentication.OAuthUsers), 0)
test.IsEqualString(t, settings.Authentication.HeaderKey, "")
test.IsEqualInt(t, len(settings.Authentication.HeaderUsers), 0)
test.IsEqualBool(t, strings.Contains(settings.Port, "127.0.0.1"), true)
Expand Down Expand Up @@ -400,10 +400,10 @@ func TestIntegration(t *testing.T) {
settings = configuration.Get()
test.IsEqualInt(t, settings.Authentication.Method, 2)
test.IsEqualString(t, settings.Authentication.Username, "")
test.IsEqualString(t, settings.Authentication.OauthProvider, "")
test.IsEqualString(t, settings.Authentication.OAuthProvider, "")
test.IsEqualString(t, settings.Authentication.OAuthClientId, "")
test.IsEqualString(t, settings.Authentication.OAuthClientSecret, "")
test.IsEqualInt(t, len(settings.Authentication.OauthUsers), 0)
test.IsEqualInt(t, len(settings.Authentication.OAuthUsers), 0)
test.IsEqualString(t, settings.Authentication.HeaderKey, "testkey")
headerUsers := len(settings.Authentication.HeaderUsers)
test.IsEqualInt(t, headerUsers, 2)
Expand Down Expand Up @@ -445,43 +445,48 @@ func TestIntegration(t *testing.T) {
waitForServer(t, false)

test.IsEqualBool(t, settings.PicturesAlwaysLocal, true)
test.IsEqualString(t, settings.Authentication.OauthProvider, "provider")
test.IsEqualString(t, settings.Authentication.OAuthProvider, "provider")
test.IsEqualString(t, settings.Authentication.OAuthClientId, "id")
test.IsEqualString(t, settings.Authentication.OAuthClientSecret, "secret")
oauthUsers := len(settings.Authentication.OauthUsers)
oauthUsers := len(settings.Authentication.OAuthUsers)
test.IsEqualInt(t, oauthUsers, 2)
if oauthUsers == 2 {
test.IsEqualString(t, settings.Authentication.OauthUsers[0], "oatest1")
test.IsEqualString(t, settings.Authentication.OauthUsers[1], "oatest2")
test.IsEqualString(t, settings.Authentication.OAuthUsers[0], "oatest1")
test.IsEqualString(t, settings.Authentication.OAuthUsers[1], "oatest2")
}
}

type setupValues struct {
BindLocalhost setupEntry `form:"localhost_sel" isBool:"true"`
UseSsl setupEntry `form:"ssl_sel" isBool:"true"`
SaveIp setupEntry `form:"logip_sel" isBool:"true"`
Port setupEntry `form:"port" isInt:"true"`
PublicName setupEntry `form:"public_name"`
ExtUrl setupEntry `form:"url"`
RedirectUrl setupEntry `form:"url_redirection"`
AuthenticationMode setupEntry `form:"authentication_sel" isInt:"true"`
AuthUsername setupEntry `form:"auth_username"`
AuthPassword setupEntry `form:"auth_pw"`
OAuthProvider setupEntry `form:"oauth_provider"`
OAuthClientId setupEntry `form:"oauth_id"`
OAuthClientSecret setupEntry `form:"oauth_secret"`
OAuthAuthorisedUsers setupEntry `form:"oauth_header_users"`
AuthHeaderKey setupEntry `form:"auth_headerkey"`
AuthHeaderUsers setupEntry `form:"auth_header_users"`
StorageSelection setupEntry `form:"storage_sel"`
PicturesAlwaysLocal setupEntry `form:"storage_sel_image"`
S3Bucket setupEntry `form:"s3_bucket"`
S3Region setupEntry `form:"s3_region"`
S3ApiKey setupEntry `form:"s3_api"`
S3ApiSecret setupEntry `form:"s3_secret"`
S3Endpoint setupEntry `form:"s3_endpoint"`
EncryptionLevel setupEntry `form:"encrypt_sel" isInt:"true"`
EncryptionPassword setupEntry `form:"enc_pw"`
BindLocalhost setupEntry `form:"localhost_sel" isBool:"true"`
UseSsl setupEntry `form:"ssl_sel" isBool:"true"`
SaveIp setupEntry `form:"logip_sel" isBool:"true"`
Port setupEntry `form:"port" isInt:"true"`
PublicName setupEntry `form:"public_name"`
ExtUrl setupEntry `form:"url"`
RedirectUrl setupEntry `form:"url_redirection"`
AuthenticationMode setupEntry `form:"authentication_sel" isInt:"true"`
AuthUsername setupEntry `form:"auth_username"`
AuthPassword setupEntry `form:"auth_pw"`
OAuthProvider setupEntry `form:"oauth_provider"`
OAuthClientId setupEntry `form:"oauth_id"`
OAuthClientSecret setupEntry `form:"oauth_secret"`
OAuthAuthorisedUsers setupEntry `form:"oauth_allowed_users"`
OAuthAuthorisedGroups setupEntry `form:"oauth_allowed_groups"`
OAuthScopeUser setupEntry `form:"oauth_scope_users"`
OAuthScopeGroup setupEntry `form:"oauth_scope_groups"`
OAuthRestrictUser setupEntry `form:"oauth_restrict_users" isBool:"true"`
OAuthRestrictGroups setupEntry `form:"oauth_restrict_groups" isBool:"true"`
AuthHeaderKey setupEntry `form:"auth_headerkey"`
AuthHeaderUsers setupEntry `form:"auth_header_users"`
StorageSelection setupEntry `form:"storage_sel"`
PicturesAlwaysLocal setupEntry `form:"storage_sel_image"`
S3Bucket setupEntry `form:"s3_bucket"`
S3Region setupEntry `form:"s3_region"`
S3ApiKey setupEntry `form:"s3_api"`
S3ApiSecret setupEntry `form:"s3_secret"`
S3Endpoint setupEntry `form:"s3_endpoint"`
EncryptionLevel setupEntry `form:"encrypt_sel" isInt:"true"`
EncryptionPassword setupEntry `form:"enc_pw"`
}

func (s *setupValues) init() {
Expand Down Expand Up @@ -529,13 +534,13 @@ func createInvalidSetupValues() []setupValues {
for i := 0; i < t.NumField(); i++ {
invalidSetup := input
v := reflect.ValueOf(&invalidSetup)
v.Elem().Field(i).FieldByName("FormName").SetString("invalid")
v.Elem().Field(i).FieldByName("FormName").SetString("XXXinvalidNameXXX")
result = append(result, invalidSetup)

tag := t.Field(i).Tag.Get("isInt")
if tag == "true" {
invalidSetup = input
v.Elem().Field(i).FieldByName("Value").SetString("notInt")
v.Elem().Field(i).FieldByName("Value").SetString("XXXnotIntXXX")
result = append(result, invalidSetup)
}
tag = t.Field(i).Tag.Get("isBool")
Expand Down Expand Up @@ -593,6 +598,8 @@ func createInputInternalAuth() setupValues {
values.EncryptionLevel.Value = "0"
values.PicturesAlwaysLocal.Value = "nochange"
values.SaveIp.Value = "0"
values.OAuthRestrictUser.Value = "false"
values.OAuthRestrictGroups.Value = "false"

return values
}
Expand All @@ -613,6 +620,8 @@ func createInputHeaderAuth() setupValues {
values.StorageSelection.Value = "local"
values.EncryptionLevel.Value = "0"
values.SaveIp.Value = "1"
values.OAuthRestrictUser.Value = "false"
values.OAuthRestrictGroups.Value = "false"

return values
}
Expand All @@ -623,7 +632,12 @@ func createInputOAuth() setupValues {
values.OAuthProvider.Value = "provider"
values.OAuthClientId.Value = "id"
values.OAuthClientSecret.Value = "secret"
values.OAuthRestrictUser.Value = "true"
values.OAuthRestrictGroups.Value = "true"
values.OAuthScopeUser.Value = "email"
values.OAuthAuthorisedUsers.Value = "oatest1; oatest2"
values.OAuthScopeGroup.Value = "groups"
values.OAuthAuthorisedGroups.Value = "group1; group2"
values.StorageSelection.Value = "local"
values.PicturesAlwaysLocal.Value = "local"
return values
Expand Down
Loading

0 comments on commit 9083ac3

Please sign in to comment.