Skip to content

Commit

Permalink
Merge branch 'v2' into v2-ui
Browse files Browse the repository at this point in the history
  • Loading branch information
markphelps authored Feb 4, 2025
2 parents fb96957 + f30ff63 commit da8747f
Show file tree
Hide file tree
Showing 15 changed files with 187 additions and 278 deletions.
23 changes: 11 additions & 12 deletions internal/config/authentication.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ func (c *AuthenticationConfig) setDefaults(v *viper.Viper) error {
v.SetDefault("authentication", map[string]any{
"required": false,
"session": map[string]any{
"storage": map[string]any{
"type": "memory",
"cleanup": map[string]any{
"grace_period": "30m",
},
},
"token_lifetime": "24h",
"state_lifetime": "10m",
},
Expand Down Expand Up @@ -202,17 +208,6 @@ func (c AuthenticationSessionStorageConfig) validate() error {
return c.Cleanup.validate()
}

func (c AuthenticationSessionStorageConfig) setDefaults(v *viper.Viper) error {
v.SetDefault("authentication.session.storage", map[string]any{
"type": "memory",
"cleanup": map[string]any{
"grace_period": "30m",
},
})

return nil
}

// AuthenticationSessionStorageCleanupConfig configures the schedule for cleaning up expired authentication records.
type AuthenticationSessionStorageCleanupConfig struct {
GracePeriod time.Duration `json:"gracePeriod,omitempty" mapstructure:"grace_period" yaml:"grace_period,omitempty"`
Expand Down Expand Up @@ -389,7 +384,11 @@ type AuthenticationMethodTokenConfig struct {
Storage AuthenticationMethodTokenStorage `json:"storage" mapstructure:"storage" yaml:"storage"`
}

func (a AuthenticationMethodTokenConfig) setDefaults(map[string]any) {}
func (a AuthenticationMethodTokenConfig) setDefaults(defaults map[string]any) {
defaults["storage"] = map[string]any{
"type": "static",
}
}

// info describes properties of the authentication method "token".
func (a AuthenticationMethodTokenConfig) info(_ context.Context) AuthenticationMethodInfo {
Expand Down
14 changes: 13 additions & 1 deletion internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,13 @@ func bindEnvVars(v envBinder, env, prefixes []string, typ reflect.Type) {
bindEnvVars(v, env, append(prefixes, wildcard), typ.Elem())

return
case reflect.Struct:
case reflect.Struct, reflect.Slice:
if typ.Kind() == reflect.Slice {
if typ = typ.Elem(); typ.Kind() != reflect.Struct {
break
}
}

for i := 0; i < typ.NumField(); i++ {
var (
structField = typ.Field(i)
Expand Down Expand Up @@ -616,6 +622,12 @@ func Default() *Config {

Authentication: AuthenticationConfig{
Session: AuthenticationSessionConfig{
Storage: AuthenticationSessionStorageConfig{
Type: AuthenticationSessionStorageTypeMemory,
Cleanup: AuthenticationSessionStorageCleanupConfig{
GracePeriod: 30 * time.Minute,
},
},
TokenLifetime: 24 * time.Hour,
StateLifetime: 10 * time.Minute,
},
Expand Down
111 changes: 80 additions & 31 deletions internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,16 +220,6 @@ func TestLoad(t *testing.T) {
path: "./testdata/server/https_not_found_cert_key.yml",
wantErr: errors.New("server: cert_key stat ./testdata/ssl_cert_not_exist.key: no such file or directory"),
},
{
name: "authentication token negative interval",
path: "./testdata/authentication/token_negative_interval.yml",
wantErr: errors.New("authentication: cleanup_interval must be a positive non-zero duration"),
},
{
name: "authentication token zero grace_period",
path: "./testdata/authentication/token_zero_grace_period.yml",
wantErr: errors.New("authentication: cleanup_grace_period must be a positive non-zero duration"),
},
{
name: "authentication token with provided bootstrap token",
path: "./testdata/authentication/token_bootstrap_token.yml",
Expand All @@ -240,9 +230,14 @@ func TestLoad(t *testing.T) {
Token: AuthenticationMethod[AuthenticationMethodTokenConfig]{
Enabled: true,
Method: AuthenticationMethodTokenConfig{
Bootstrap: AuthenticationMethodTokenBootstrapConfig{
Token: "s3cr3t!",
Expiration: 24 * time.Hour,
Storage: AuthenticationMethodTokenStorage{
Type: AuthenticationMethodTokenStorageTypeStatic,
Tokens: []AuthenticationMethodStaticToken{
{
Name: "bootstrap token",
Credential: "s3cr3t!",
},
},
},
},
},
Expand All @@ -260,11 +255,21 @@ func TestLoad(t *testing.T) {
Domain: "localhost",
Storage: AuthenticationSessionStorageConfig{
Type: AuthenticationSessionStorageTypeMemory,
Cleanup: AuthenticationSessionStorageCleanupConfig{
GracePeriod: 30 * time.Minute,
},
},
TokenLifetime: 24 * time.Hour,
StateLifetime: 10 * time.Minute,
}
cfg.Authentication.Methods = AuthenticationMethodsConfig{
Token: AuthenticationMethod[AuthenticationMethodTokenConfig]{
Enabled: true,
Method: AuthenticationMethodTokenConfig{
Storage: AuthenticationMethodTokenStorage{
Type: AuthenticationMethodTokenStorageTypeStatic,
},
},
},
OIDC: AuthenticationMethod[AuthenticationMethodOIDCConfig]{
Enabled: true,
Expand All @@ -283,7 +288,12 @@ func TestLoad(t *testing.T) {
Domain: "localhost",
Storage: AuthenticationSessionStorageConfig{
Type: AuthenticationSessionStorageTypeMemory,
Cleanup: AuthenticationSessionStorageCleanupConfig{
GracePeriod: 30 * time.Minute,
},
},
TokenLifetime: 24 * time.Hour,
StateLifetime: 10 * time.Minute,
}
cfg.Authentication.Methods = AuthenticationMethodsConfig{
OIDC: AuthenticationMethod[AuthenticationMethodOIDCConfig]{
Expand Down Expand Up @@ -424,11 +434,19 @@ func TestLoad(t *testing.T) {
},
Storage: AuthenticationSessionStorageConfig{
Type: AuthenticationSessionStorageTypeMemory,
Cleanup: AuthenticationSessionStorageCleanupConfig{
GracePeriod: 30 * time.Minute,
},
},
},
Methods: AuthenticationMethodsConfig{
Token: AuthenticationMethod[AuthenticationMethodTokenConfig]{
Enabled: true,
Method: AuthenticationMethodTokenConfig{
Storage: AuthenticationMethodTokenStorage{
Type: AuthenticationMethodTokenStorageTypeStatic,
},
},
},
OIDC: AuthenticationMethod[AuthenticationMethodOIDCConfig]{
Method: AuthenticationMethodOIDCConfig{
Expand Down Expand Up @@ -507,11 +525,16 @@ func TestLoad(t *testing.T) {
Remote: "https://github.com/flipt-io/flipt.git",
Branch: "main",
PollInterval: 5 * time.Second,
Authentication: StorageGitAuthenticationConfig{
BasicAuth: &GitBasicAuth{
Username: "user",
Password: "pass",
},
Credentials: "git",
},
}

cfg.Credentials = CredentialsConfig{
"git": {
Type: "basic",
Basic: &BasicAuthConfig{
Username: "user",
Password: "pass",
},
},
}
Expand Down Expand Up @@ -545,11 +568,25 @@ func TestLoad(t *testing.T) {
},
Storage: AuthenticationSessionStorageConfig{
Type: AuthenticationSessionStorageTypeMemory,
Cleanup: AuthenticationSessionStorageCleanupConfig{
GracePeriod: 30 * time.Minute,
},
},
},
Methods: AuthenticationMethodsConfig{
Token: AuthenticationMethod[AuthenticationMethodTokenConfig]{
Enabled: true,
Method: AuthenticationMethodTokenConfig{
Storage: AuthenticationMethodTokenStorage{
Type: AuthenticationMethodTokenStorageTypeStatic,
Tokens: []AuthenticationMethodStaticToken{
{
Name: "some static token",
Credential: "abcdefg",
},
},
},
},
},
OIDC: AuthenticationMethod[AuthenticationMethodOIDCConfig]{
Method: AuthenticationMethodOIDCConfig{
Expand Down Expand Up @@ -646,22 +683,22 @@ func TestLoad(t *testing.T) {
{
name: "git basic auth partially provided",
path: "./testdata/storage/git_basic_auth_invalid.yml",
wantErr: errors.New("storage default: both username and password need to be provided for basic auth"),
wantErr: errors.New(`credential "default": both username and password need to be provided for basic auth`),
},
{
name: "git ssh auth missing password",
path: "./testdata/storage/git_ssh_auth_invalid_missing_password.yml",
wantErr: errors.New("storage default: ssh authentication password required"),
wantErr: errors.New(`credential "default": ssh authentication: string: password non-empty value is required`),
},
{
name: "git ssh auth missing private key parts",
path: "./testdata/storage/git_ssh_auth_invalid_private_key_missing.yml",
wantErr: errors.New("storage default: ssh authentication please provide exclusively one of private_key_bytes or private_key_path"),
wantErr: errors.New(`credential "default": ssh authentication: please provide exclusively one of private_key_bytes or private_key_path`),
},
{
name: "git ssh auth provided both private key forms",
path: "./testdata/storage/git_ssh_auth_invalid_private_key_both.yml",
wantErr: errors.New("storage default: ssh authentication please provide exclusively one of private_key_bytes or private_key_path"),
wantErr: errors.New(`credential "default": ssh authentication: please provide exclusively one of private_key_bytes or private_key_path`),
},
{
name: "git valid with ssh auth",
Expand All @@ -676,12 +713,16 @@ func TestLoad(t *testing.T) {
Remote: "[email protected]:foo/bar.git",
Branch: "main",
PollInterval: 30 * time.Second,
Authentication: StorageGitAuthenticationConfig{
SSHAuth: &GitSSHAuth{
User: "git",
Password: "bar",
PrivateKeyPath: "/path/to/pem.key",
},
Credentials: "git",
},
}
cfg.Credentials = CredentialsConfig{
"git": {
Type: "ssh",
SSH: &SSHAuthConfig{
User: "git",
Password: "bar",
PrivateKeyPath: "/path/to/pem.key",
},
},
}
Expand Down Expand Up @@ -868,16 +909,24 @@ func readYAMLIntoEnv(t *testing.T, path string) [][2]string {
}

func getEnvVars(prefix string, v map[any]any) (vals [][2]string) {
OUTER:
for key, value := range v {
switch v := value.(type) {
case map[any]any:
vals = append(vals, getEnvVars(fmt.Sprintf("%s_%v", prefix, key), v)...)
case []any:
builder := strings.Builder{}
for i, s := range v {
builder.WriteString(fmt.Sprintf("%v", s))
if i < len(v)-1 {
builder.WriteByte(' ')
switch s := s.(type) {
case map[any]any:
// descend into slices of objects
vals = append(vals, getEnvVars(fmt.Sprintf("%s_%v", prefix, key), s)...)
continue OUTER
default:
builder.WriteString(fmt.Sprintf("%v", s))
if i < len(v)-1 {
builder.WriteByte(' ')
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion internal/config/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ type StorageConfig struct {
PollInterval time.Duration `json:"pollInterval,omitempty" mapstructure:"poll_interval" yaml:"poll_interval,omitempty"`
InsecureSkipTLS bool `json:"-" mapstructure:"insecure_skip_tls" yaml:"-"`
Credentials string `json:"-" mapstructure:"credentials" yaml:"-"`
Signature SignatureConfig `json:"signature" mapstructure:"signature,omitempty" yaml:"signature"`
Signature SignatureConfig `json:"signature,omitempty" mapstructure:"signature,omitempty" yaml:"signature,omitempty"`
}

func (c *StorageConfig) validate() error {
Expand Down
25 changes: 17 additions & 8 deletions internal/config/testdata/advanced.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,14 @@ storage:
default:
remote: https://github.com/flipt-io/flipt.git
poll_interval: 5s
authentication:
basic:
username: user
password: pass
credentials: "git"

credentials:
git:
type: basic
basic:
username: "user"
password: "pass"

meta:
check_for_updates: false
Expand All @@ -48,12 +52,17 @@ authentication:
secure: true
csrf:
key: "abcdefghijklmnopqrstuvwxyz1234567890" #gitleaks:allow
cleanup:
interval: 2h
grace_period: 48h
methods:
token:
enabled: true
cleanup:
interval: 2h
grace_period: 48h
storage:
type: static
tokens:
- name: "some static token"
credential: "abcdefg"
oidc:
enabled: true
providers:
Expand Down Expand Up @@ -91,4 +100,4 @@ authorization:
poll_interval: 1m
data:
path: "/path/to/policy/data.json"
poll_interval: 1m
poll_interval: 1m
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ authentication:
methods:
token:
enabled: true
bootstrap:
token: "s3cr3t!"
expiration: 24h
storage:
type: static
tokens:
- name: "bootstrap token"
credential: "s3cr3t!"
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ authentication:
methods:
token:
enabled: true
cleanup:
interval: 2h
grace_period: 48h
oidc:
enabled: true
providers:
Expand Down
10 changes: 7 additions & 3 deletions internal/config/testdata/storage/git_basic_auth_invalid.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
storage:
default:
remote: "[email protected]:foo/bar.git"
authentication:
basic:
username: foo
credentials: basic

credentials:
default:
type: basic
basic:
username: foo
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
storage:
default:
remote: "[email protected]:foo/bar.git"
authentication:
ssh:
user: foo
private_key_path: "/path/to/pem.key"
credentials: default

credentials:
default:
type: ssh
ssh:
user: foo
private_key_path: "/path/to/pem.key"
Loading

0 comments on commit da8747f

Please sign in to comment.