Files

116 lines
5.1 KiB
Go

package parser_test
import (
"os"
"path/filepath"
"testing"
"github.com/opencloud-eu/opencloud/pkg/shared"
"github.com/opencloud-eu/opencloud/services/proxy/pkg/config"
"github.com/opencloud-eu/opencloud/services/proxy/pkg/config/defaults"
"github.com/opencloud-eu/opencloud/services/proxy/pkg/config/parser"
"github.com/stretchr/testify/require"
)
func TestParseOIDCAudiences(t *testing.T) {
tests := []struct {
name string
yaml string
env string
method string
setEnv bool
want []string
wantErr string
}{
{name: "unset defaults to disabled"},
{name: "YAML", yaml: "oidc:\n audiences: [opencloud, opencloud-api]\n", want: []string{"opencloud", "opencloud-api"}},
{name: "empty YAML list", yaml: "oidc:\n audiences: []\n"},
{name: "null YAML list", yaml: "oidc:\n audiences: null\n"},
{name: "ENV", setEnv: true, env: "opencloud,opencloud-api", want: []string{"opencloud", "opencloud-api"}},
{name: "ENV trims list entries", setEnv: true, env: " opencloud, opencloud-api ", want: []string{"opencloud", "opencloud-api"}},
{name: "ENV precedence", yaml: "oidc:\n audiences: [yaml-audience]\n", setEnv: true, env: "env-audience", want: []string{"env-audience"}},
{name: "empty ENV disables YAML", yaml: "oidc:\n audiences: [opencloud]\n", setEnv: true},
{name: "existing ENV empty segment handling", setEnv: true, env: "opencloud,,opencloud-api", want: []string{"opencloud", "opencloud-api"}},
{name: "YAML blank entry", yaml: "oidc:\n audiences: ['']\n", wantErr: "empty or whitespace-only"},
{name: "YAML whitespace entry", yaml: "oidc:\n audiences: [' ']\n", wantErr: "empty or whitespace-only"},
{name: "ENV whitespace entry", setEnv: true, env: "opencloud, ", wantErr: "empty or whitespace-only"},
{name: "ENV whitespace only", setEnv: true, env: " ", wantErr: "empty or whitespace-only"},
{name: "YAML preserves case", yaml: "oidc:\n audiences: [OpenCloud]\n", want: []string{"OpenCloud"}},
{name: "YAML incompatible verification", yaml: "oidc:\n audiences: [opencloud]\n access_token_verify_method: none\n", wantErr: "require access_token_verify_method to be 'jwt'"},
{name: "ENV incompatible verification", setEnv: true, env: "opencloud", method: "none", wantErr: "require access_token_verify_method to be 'jwt'"},
{name: "ENV enables JWT over YAML none", yaml: "oidc:\n audiences: [opencloud]\n access_token_verify_method: none\n", method: "jwt", want: []string{"opencloud"}},
{name: "empty ENV restores none compatibility", yaml: "oidc:\n audiences: [opencloud]\n access_token_verify_method: none\n", setEnv: true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
dir := t.TempDir()
t.Setenv("OC_CONFIG_DIR", dir)
t.Setenv("PROXY_OIDC_ACCESS_TOKEN_VERIFY_METHOD", "")
require.NoError(t, os.Unsetenv("PROXY_OIDC_ACCESS_TOKEN_VERIFY_METHOD"))
if tt.method != "" {
t.Setenv("PROXY_OIDC_ACCESS_TOKEN_VERIFY_METHOD", tt.method)
}
t.Setenv("PROXY_OIDC_SKIP_USER_INFO", "false")
t.Setenv("PROXY_OIDC_AUDIENCES", "")
require.NoError(t, os.Unsetenv("PROXY_OIDC_AUDIENCES"))
if tt.setEnv {
t.Setenv("PROXY_OIDC_AUDIENCES", tt.env)
}
require.NoError(t, os.WriteFile(filepath.Join(dir, "proxy.yaml"), []byte(tt.yaml), 0600))
cfg := validProxyConfig()
err := parser.ParseConfig(cfg)
if tt.wantErr != "" {
require.ErrorContains(t, err, tt.wantErr)
require.ErrorContains(t, err, "PROXY_OIDC_AUDIENCES")
return
}
require.NoError(t, err)
if len(tt.want) == 0 {
require.Empty(t, cfg.OIDC.Audiences)
} else {
require.Equal(t, tt.want, cfg.OIDC.Audiences)
}
})
}
}
func TestValidateOIDCAudiences(t *testing.T) {
for _, tt := range []struct {
name string
audiences []string
method string
wantErr string
}{
{name: "disabled JWT", method: "jwt"},
{name: "disabled none", method: "none"},
{name: "enabled JWT", audiences: []string{"opencloud"}, method: "jwt"},
{name: "enabled none", audiences: []string{"opencloud"}, method: "none", wantErr: "require access_token_verify_method to be 'jwt'"},
{name: "blank", audiences: []string{""}, method: "jwt", wantErr: "empty or whitespace-only"},
{name: "whitespace", audiences: []string{" \t"}, method: "jwt", wantErr: "empty or whitespace-only"},
{name: "mixed valid and blank", audiences: []string{"opencloud", ""}, method: "jwt", wantErr: "empty or whitespace-only"},
} {
t.Run(tt.name, func(t *testing.T) {
cfg := validProxyConfig()
cfg.OIDC.Audiences = tt.audiences
cfg.OIDC.AccessTokenVerifyMethod = tt.method
err := parser.Validate(cfg)
if tt.wantErr != "" {
require.ErrorContains(t, err, tt.wantErr)
require.ErrorContains(t, err, "PROXY_OIDC_AUDIENCES")
} else {
require.NoError(t, err)
}
})
}
}
func validProxyConfig() *config.Config {
cfg := defaults.FullDefaultConfig()
cfg.MachineAuthAPIKey = "test-machine-key"
cfg.TransferSecret = "test-transfer-secret"
cfg.ServiceAccount.ServiceAccountID = "test-service-account"
cfg.ServiceAccount.ServiceAccountSecret = "test-service-secret"
cfg.Commons = &shared.Commons{URLSigningSecret: "test-url-secret"}
return cfg
}