-
Notifications
You must be signed in to change notification settings - Fork 101
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
It seems viper function RegisterAlias() does not works as expected, the GetStringSlice() function does not returns anything for any flag (the aliased as well as the alias). So the fix consist of not using RegisterAlias() and simply handle both flags. Also the PR move some bootstrap code from cmd/container.go and cmd/root.go inside package cmd/internal/http_basic.go. Now, all code related to http basic feature is located there.
- Loading branch information
Showing
6 changed files
with
231 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package internal | ||
|
||
import ( | ||
"strings" | ||
|
||
"github.com/spf13/viper" | ||
) | ||
|
||
const ( | ||
envPrefix = "numary" | ||
) | ||
|
||
var EnvVarReplacer = strings.NewReplacer(".", "_", "-", "_") | ||
|
||
func BindEnv(v *viper.Viper) { | ||
v.SetEnvPrefix(envPrefix) | ||
v.SetEnvKeyReplacer(EnvVarReplacer) | ||
v.AutomaticEnv() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package internal | ||
|
||
import ( | ||
"strings" | ||
|
||
"github.com/numary/go-libs/sharedauth" | ||
"github.com/numary/ledger/pkg/api/routes" | ||
"github.com/spf13/cobra" | ||
"github.com/spf13/viper" | ||
) | ||
|
||
const ( | ||
serverHttpBasicAuthFlag = "server.http.basic_auth" | ||
authBasicEnabledFlag = "auth-basic-enabled" | ||
authBasicCredentialsFlag = "auth-basic-credentials" | ||
) | ||
|
||
func HTTPBasicAuthMethod(v *viper.Viper) sharedauth.Method { | ||
basicAuth := v.GetStringSlice(serverHttpBasicAuthFlag) | ||
if len(basicAuth) == 0 { | ||
basicAuth = v.GetStringSlice(authBasicCredentialsFlag) | ||
} | ||
if len(basicAuth) > 0 && | ||
(!v.IsSet(authBasicEnabledFlag) || v.GetBool(authBasicEnabledFlag)) { // Keep compatibility, we disable the feature only if the flag is explicitely set to false | ||
credentials := sharedauth.Credentials{} | ||
for _, kv := range basicAuth { | ||
parts := strings.SplitN(kv, ":", 2) | ||
credentials[parts[0]] = sharedauth.Credential{ | ||
Password: parts[1], | ||
Scopes: routes.AllScopes, | ||
} | ||
} | ||
return sharedauth.NewHTTPBasicMethod(credentials) | ||
} | ||
return nil | ||
} | ||
|
||
func InitHTTPBasicFlags(cmd *cobra.Command) { | ||
cmd.PersistentFlags().Bool(authBasicEnabledFlag, false, "Enable basic auth") | ||
cmd.PersistentFlags().StringSlice(authBasicCredentialsFlag, []string{}, "HTTP basic auth credentials (<username>:<password>)") | ||
cmd.PersistentFlags().String(serverHttpBasicAuthFlag, "", "Http basic auth") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
package internal | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"reflect" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/numary/go-libs/sharedauth" | ||
"github.com/spf13/cobra" | ||
"github.com/spf13/viper" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func withPrefix(flag string) string { | ||
return strings.ToUpper(fmt.Sprintf("%s_%s", envPrefix, EnvVarReplacer.Replace(flag))) | ||
} | ||
|
||
func setEnvVar(key, value string) func() { | ||
prefixedFlag := withPrefix(key) | ||
oldEnv := os.Getenv(prefixedFlag) | ||
os.Setenv(prefixedFlag, value) | ||
return func() { | ||
os.Setenv(prefixedFlag, oldEnv) | ||
} | ||
} | ||
|
||
func TestViperEnvBinding(t *testing.T) { | ||
|
||
type testCase struct { | ||
name string | ||
key string | ||
envValue string | ||
viperMethod interface{} | ||
expectedValue interface{} | ||
} | ||
|
||
for _, testCase := range []testCase{ | ||
{ | ||
name: "using deprecated credentials flag", | ||
key: serverHttpBasicAuthFlag, | ||
envValue: "foo:bar", | ||
viperMethod: (*viper.Viper).GetString, | ||
expectedValue: "foo:bar", | ||
}, | ||
{ | ||
name: "using credentials flag", | ||
key: authBasicCredentialsFlag, | ||
envValue: "foo:bar", | ||
viperMethod: (*viper.Viper).GetStringSlice, | ||
expectedValue: []string{"foo:bar"}, | ||
}, | ||
{ | ||
name: "using http basic enabled flags", | ||
key: authBasicEnabledFlag, | ||
envValue: "true", | ||
viperMethod: (*viper.Viper).GetBool, | ||
expectedValue: true, | ||
}, | ||
} { | ||
t.Run(testCase.name, func(t *testing.T) { | ||
v := viper.GetViper() | ||
cmd := &cobra.Command{ | ||
Run: func(cmd *cobra.Command, args []string) { | ||
ret := reflect.ValueOf(testCase.viperMethod).Call([]reflect.Value{ | ||
reflect.ValueOf(v), | ||
reflect.ValueOf(testCase.key), | ||
}) | ||
require.Len(t, ret, 1) | ||
|
||
rValue := ret[0].Interface() | ||
require.Equal(t, testCase.expectedValue, rValue) | ||
}, | ||
} | ||
InitHTTPBasicFlags(cmd) | ||
BindEnv(v) | ||
|
||
restoreEnvVar := setEnvVar(testCase.key, testCase.envValue) | ||
defer restoreEnvVar() | ||
|
||
require.NoError(t, v.BindPFlags(cmd.PersistentFlags())) | ||
|
||
require.NoError(t, cmd.Execute()) | ||
}) | ||
} | ||
} | ||
|
||
func TestHTTPBasicAuthMethod(t *testing.T) { | ||
|
||
type testCase struct { | ||
name string | ||
args []string | ||
expectedBasicAuthMethod bool | ||
} | ||
|
||
for _, testCase := range []testCase{ | ||
{ | ||
name: "no flag defined", | ||
args: []string{}, | ||
expectedBasicAuthMethod: false, | ||
}, | ||
{ | ||
name: "with latest credentials flag", | ||
args: []string{ | ||
fmt.Sprintf("--%s=%s", authBasicCredentialsFlag, "foo:bar"), | ||
}, | ||
expectedBasicAuthMethod: true, | ||
}, | ||
{ | ||
name: "with deprecated credentials flag", | ||
args: []string{ | ||
fmt.Sprintf("--%s=%s", serverHttpBasicAuthFlag, "foo:bar"), | ||
}, | ||
expectedBasicAuthMethod: true, | ||
}, | ||
{ | ||
name: "with enabled flag set to false", | ||
args: []string{ | ||
fmt.Sprintf("--%s=%s", serverHttpBasicAuthFlag, "foo:bar"), | ||
fmt.Sprintf("--%s=false", authBasicEnabledFlag), | ||
}, | ||
expectedBasicAuthMethod: false, | ||
}, | ||
{ | ||
name: "with enabled flag set to true", | ||
args: []string{ | ||
fmt.Sprintf("--%s=%s", serverHttpBasicAuthFlag, "foo:bar"), | ||
fmt.Sprintf("--%s=true", authBasicEnabledFlag), | ||
}, | ||
expectedBasicAuthMethod: true, | ||
}, | ||
} { | ||
t.Run(testCase.name, func(t *testing.T) { | ||
var method sharedauth.Method | ||
cmd := &cobra.Command{ | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
method = HTTPBasicAuthMethod(viper.GetViper()) | ||
return nil | ||
}, | ||
} | ||
InitHTTPBasicFlags(cmd) | ||
require.NoError(t, viper.BindPFlags(cmd.PersistentFlags())) | ||
|
||
cmd.SetArgs(testCase.args) | ||
|
||
require.NoError(t, cmd.Execute()) | ||
if testCase.expectedBasicAuthMethod { | ||
require.NotNil(t, method) | ||
} else { | ||
require.Nil(t, method) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters