diff --git a/pkg/apiserver/authentication/identityprovider/aliyunidaas/idaas.go b/pkg/apiserver/authentication/identityprovider/aliyunidaas/idaas.go index 9103a268f..184115269 100644 --- a/pkg/apiserver/authentication/identityprovider/aliyunidaas/idaas.go +++ b/pkg/apiserver/authentication/identityprovider/aliyunidaas/idaas.go @@ -27,7 +27,7 @@ import ( "golang.org/x/oauth2" "kubesphere.io/kubesphere/pkg/apiserver/authentication/identityprovider" - "kubesphere.io/kubesphere/pkg/apiserver/authentication/oauth" + "kubesphere.io/kubesphere/pkg/server/options" ) func init() { @@ -89,9 +89,9 @@ func (f *idaasProviderFactory) Type() string { return "AliyunIDaaSProvider" } -func (f *idaasProviderFactory) Create(options oauth.DynamicOptions) (identityprovider.OAuthProvider, error) { +func (f *idaasProviderFactory) Create(opts options.DynamicOptions) (identityprovider.OAuthProvider, error) { var idaas aliyunIDaaS - if err := mapstructure.Decode(options, &idaas); err != nil { + if err := mapstructure.Decode(opts, &idaas); err != nil { return nil, err } idaas.Config = &oauth2.Config{ diff --git a/pkg/apiserver/authentication/identityprovider/aliyunidaas/idaas_test.go b/pkg/apiserver/authentication/identityprovider/aliyunidaas/idaas_test.go index 8feca4b96..1f524b90c 100644 --- a/pkg/apiserver/authentication/identityprovider/aliyunidaas/idaas_test.go +++ b/pkg/apiserver/authentication/identityprovider/aliyunidaas/idaas_test.go @@ -24,16 +24,16 @@ import ( "gopkg.in/yaml.v3" "kubesphere.io/kubesphere/pkg/apiserver/authentication/identityprovider" - "kubesphere.io/kubesphere/pkg/apiserver/authentication/oauth" + "kubesphere.io/kubesphere/pkg/server/options" ) func Test_idaasProviderFactory_Create(t *testing.T) { type args struct { - options oauth.DynamicOptions + options options.DynamicOptions } - mustUnmarshalYAML := func(data string) oauth.DynamicOptions { - var dynamicOptions oauth.DynamicOptions + mustUnmarshalYAML := func(data string) options.DynamicOptions { + var dynamicOptions options.DynamicOptions _ = yaml.Unmarshal([]byte(data), &dynamicOptions) return dynamicOptions } diff --git a/pkg/apiserver/authentication/identityprovider/cas/cas.go b/pkg/apiserver/authentication/identityprovider/cas/cas.go index 97bf32d4d..f4752f903 100644 --- a/pkg/apiserver/authentication/identityprovider/cas/cas.go +++ b/pkg/apiserver/authentication/identityprovider/cas/cas.go @@ -26,7 +26,7 @@ import ( gocas "gopkg.in/cas.v2" "kubesphere.io/kubesphere/pkg/apiserver/authentication/identityprovider" - "kubesphere.io/kubesphere/pkg/apiserver/authentication/oauth" + "kubesphere.io/kubesphere/pkg/server/options" ) func init() { @@ -63,9 +63,9 @@ func (f casProviderFactory) Type() string { return "CASIdentityProvider" } -func (f casProviderFactory) Create(options oauth.DynamicOptions) (identityprovider.OAuthProvider, error) { +func (f casProviderFactory) Create(opts options.DynamicOptions) (identityprovider.OAuthProvider, error) { var cas cas - if err := mapstructure.Decode(options, &cas); err != nil { + if err := mapstructure.Decode(opts, &cas); err != nil { return nil, err } casURL, err := url.Parse(cas.CASServerURL) diff --git a/pkg/apiserver/authentication/identityprovider/generic_provider.go b/pkg/apiserver/authentication/identityprovider/generic_provider.go index bc3599f12..67b9fa2a2 100644 --- a/pkg/apiserver/authentication/identityprovider/generic_provider.go +++ b/pkg/apiserver/authentication/identityprovider/generic_provider.go @@ -19,7 +19,7 @@ package identityprovider import ( - "kubesphere.io/kubesphere/pkg/apiserver/authentication/oauth" + "kubesphere.io/kubesphere/pkg/server/options" ) type GenericProvider interface { @@ -31,5 +31,5 @@ type GenericProviderFactory interface { // Type unique type of the provider Type() string // Apply the dynamic options from kubesphere-config - Create(options oauth.DynamicOptions) (GenericProvider, error) + Create(options options.DynamicOptions) (GenericProvider, error) } diff --git a/pkg/apiserver/authentication/identityprovider/github/github.go b/pkg/apiserver/authentication/identityprovider/github/github.go index c4e166b0d..6e173d806 100644 --- a/pkg/apiserver/authentication/identityprovider/github/github.go +++ b/pkg/apiserver/authentication/identityprovider/github/github.go @@ -28,7 +28,7 @@ import ( "golang.org/x/oauth2" "kubesphere.io/kubesphere/pkg/apiserver/authentication/identityprovider" - "kubesphere.io/kubesphere/pkg/apiserver/authentication/oauth" + "kubesphere.io/kubesphere/pkg/server/options" ) const ( @@ -121,9 +121,9 @@ func (g *ldapProviderFactory) Type() string { return "GitHubIdentityProvider" } -func (g *ldapProviderFactory) Create(options oauth.DynamicOptions) (identityprovider.OAuthProvider, error) { +func (g *ldapProviderFactory) Create(opts options.DynamicOptions) (identityprovider.OAuthProvider, error) { var github github - if err := mapstructure.Decode(options, &github); err != nil { + if err := mapstructure.Decode(opts, &github); err != nil { return nil, err } @@ -137,7 +137,7 @@ func (g *ldapProviderFactory) Create(options oauth.DynamicOptions) (identityprov github.Endpoint.UserInfoURL = userInfoURL } // fixed options - options["endpoint"] = oauth.DynamicOptions{ + opts["endpoint"] = options.DynamicOptions{ "authURL": github.Endpoint.AuthURL, "tokenURL": github.Endpoint.TokenURL, "userInfoURL": github.Endpoint.UserInfoURL, diff --git a/pkg/apiserver/authentication/identityprovider/github/github_test.go b/pkg/apiserver/authentication/identityprovider/github/github_test.go index 817ce095d..46a3d64f7 100644 --- a/pkg/apiserver/authentication/identityprovider/github/github_test.go +++ b/pkg/apiserver/authentication/identityprovider/github/github_test.go @@ -27,6 +27,8 @@ import ( "testing" "time" + "kubesphere.io/kubesphere/pkg/server/options" + . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/onsi/gomega/gexec" @@ -34,7 +36,6 @@ import ( "gopkg.in/yaml.v3" "kubesphere.io/kubesphere/pkg/apiserver/authentication/identityprovider" - "kubesphere.io/kubesphere/pkg/apiserver/authentication/oauth" ) var githubServer *httptest.Server @@ -119,12 +120,12 @@ scopes: Expect(provider).Should(Equal(expected)) }) It("should configure successfully", func() { - config := oauth.DynamicOptions{ + config := options.DynamicOptions{ "clientID": "de6ff8bed0304e487b6e", "clientSecret": "2b70536f79ec8d2939863509d05e2a71c268b9af", "redirectURL": "https://ks-console.kubesphere-system.svc/oauth/redirect/github", "insecureSkipVerify": true, - "endpoint": oauth.DynamicOptions{ + "endpoint": options.DynamicOptions{ "authURL": fmt.Sprintf("%s/login/oauth/authorize", githubServer.URL), "tokenURL": fmt.Sprintf("%s/login/oauth/access_token", githubServer.URL), "userInfoURL": fmt.Sprintf("%s/user", githubServer.URL), @@ -133,12 +134,12 @@ scopes: factory := ldapProviderFactory{} provider, err = factory.Create(config) Expect(err).Should(BeNil()) - expected := oauth.DynamicOptions{ + expected := options.DynamicOptions{ "clientID": "de6ff8bed0304e487b6e", "clientSecret": "2b70536f79ec8d2939863509d05e2a71c268b9af", "redirectURL": "https://ks-console.kubesphere-system.svc/oauth/redirect/github", "insecureSkipVerify": true, - "endpoint": oauth.DynamicOptions{ + "endpoint": options.DynamicOptions{ "authURL": fmt.Sprintf("%s/login/oauth/authorize", githubServer.URL), "tokenURL": fmt.Sprintf("%s/login/oauth/access_token", githubServer.URL), "userInfoURL": fmt.Sprintf("%s/user", githubServer.URL), @@ -158,8 +159,8 @@ scopes: }) }) -func mustUnmarshalYAML(data string) oauth.DynamicOptions { - var dynamicOptions oauth.DynamicOptions +func mustUnmarshalYAML(data string) options.DynamicOptions { + var dynamicOptions options.DynamicOptions _ = yaml.Unmarshal([]byte(data), &dynamicOptions) return dynamicOptions } diff --git a/pkg/apiserver/authentication/identityprovider/identity_provider_test.go b/pkg/apiserver/authentication/identityprovider/identity_provider_test.go index e7441b87b..96195c905 100644 --- a/pkg/apiserver/authentication/identityprovider/identity_provider_test.go +++ b/pkg/apiserver/authentication/identityprovider/identity_provider_test.go @@ -22,6 +22,8 @@ import ( "net/http" "testing" + "kubesphere.io/kubesphere/pkg/server/options" + "kubesphere.io/kubesphere/pkg/apiserver/authentication/oauth" ) @@ -55,7 +57,7 @@ func (e emptyOAuthProvider) IdentityExchangeCallback(req *http.Request) (Identit return emptyIdentity{}, nil } -func (e emptyOAuthProviderFactory) Create(options oauth.DynamicOptions) (OAuthProvider, error) { +func (e emptyOAuthProviderFactory) Create(options options.DynamicOptions) (OAuthProvider, error) { return emptyOAuthProvider{}, nil } @@ -74,7 +76,7 @@ func (e emptyGenericProvider) Authenticate(username string, password string) (Id return emptyIdentity{}, nil } -func (e emptyGenericProviderFactory) Create(options oauth.DynamicOptions) (GenericProvider, error) { +func (e emptyGenericProviderFactory) Create(options options.DynamicOptions) (GenericProvider, error) { return emptyGenericProvider{}, nil } @@ -97,7 +99,7 @@ func TestSetupWith(t *testing.T) { Name: "ldap", MappingMethod: "auto", Type: "LDAPIdentityProvider", - Provider: oauth.DynamicOptions{}, + Provider: options.DynamicOptions{}, }, }}, wantErr: false, @@ -109,7 +111,7 @@ func TestSetupWith(t *testing.T) { Name: "ldap", MappingMethod: "auto", Type: "LDAPIdentityProvider", - Provider: oauth.DynamicOptions{}, + Provider: options.DynamicOptions{}, }, }}, wantErr: true, @@ -121,7 +123,7 @@ func TestSetupWith(t *testing.T) { Name: "test", MappingMethod: "auto", Type: "NotSupported", - Provider: oauth.DynamicOptions{}, + Provider: options.DynamicOptions{}, }, }}, wantErr: true, diff --git a/pkg/apiserver/authentication/identityprovider/ldap/ldap.go b/pkg/apiserver/authentication/identityprovider/ldap/ldap.go index fd40ddc55..eaa4b7eb2 100644 --- a/pkg/apiserver/authentication/identityprovider/ldap/ldap.go +++ b/pkg/apiserver/authentication/identityprovider/ldap/ldap.go @@ -30,7 +30,7 @@ import ( "k8s.io/klog/v2" "kubesphere.io/kubesphere/pkg/apiserver/authentication/identityprovider" - "kubesphere.io/kubesphere/pkg/apiserver/authentication/oauth" + "kubesphere.io/kubesphere/pkg/server/options" ) const ( @@ -85,9 +85,9 @@ func (l *ldapProviderFactory) Type() string { return ldapIdentityProvider } -func (l *ldapProviderFactory) Create(options oauth.DynamicOptions) (identityprovider.GenericProvider, error) { +func (l *ldapProviderFactory) Create(opts options.DynamicOptions) (identityprovider.GenericProvider, error) { var ldapProvider ldapProvider - if err := mapstructure.Decode(options, &ldapProvider); err != nil { + if err := mapstructure.Decode(opts, &ldapProvider); err != nil { return nil, err } if ldapProvider.ReadTimeout <= 0 { diff --git a/pkg/apiserver/authentication/identityprovider/ldap/ldap_test.go b/pkg/apiserver/authentication/identityprovider/ldap/ldap_test.go index 97aa26c7f..8fb569823 100644 --- a/pkg/apiserver/authentication/identityprovider/ldap/ldap_test.go +++ b/pkg/apiserver/authentication/identityprovider/ldap/ldap_test.go @@ -20,14 +20,14 @@ import ( "os" "testing" + "kubesphere.io/kubesphere/pkg/server/options" + "github.com/google/go-cmp/cmp" "gopkg.in/yaml.v3" - - "kubesphere.io/kubesphere/pkg/apiserver/authentication/oauth" ) func TestNewLdapProvider(t *testing.T) { - options := ` + opts := ` host: test.sn.mynetname.net:389 managerDN: uid=root,cn=users,dc=test,dc=sn,dc=mynetname,dc=net managerPassword: test @@ -36,8 +36,8 @@ userSearchBase: dc=test,dc=sn,dc=mynetname,dc=net loginAttribute: uid mailAttribute: mail ` - var dynamicOptions oauth.DynamicOptions - err := yaml.Unmarshal([]byte(options), &dynamicOptions) + var dynamicOptions options.DynamicOptions + err := yaml.Unmarshal([]byte(opts), &dynamicOptions) if err != nil { t.Fatal(err) } @@ -73,12 +73,12 @@ func TestLdapProvider_Authenticate(t *testing.T) { if configFile == "" { t.Skip("Skipped") } - options, err := os.ReadFile(configFile) + opts, err := os.ReadFile(configFile) if err != nil { t.Fatal(err) } - var dynamicOptions oauth.DynamicOptions - if err = yaml.Unmarshal(options, &dynamicOptions); err != nil { + var dynamicOptions options.DynamicOptions + if err = yaml.Unmarshal(opts, &dynamicOptions); err != nil { t.Fatal(err) } ldapProvider, err := new(ldapProviderFactory).Create(dynamicOptions) diff --git a/pkg/apiserver/authentication/identityprovider/oauth_provider.go b/pkg/apiserver/authentication/identityprovider/oauth_provider.go index 29fea1395..208d1e82b 100644 --- a/pkg/apiserver/authentication/identityprovider/oauth_provider.go +++ b/pkg/apiserver/authentication/identityprovider/oauth_provider.go @@ -19,7 +19,7 @@ package identityprovider import ( "net/http" - "kubesphere.io/kubesphere/pkg/apiserver/authentication/oauth" + "kubesphere.io/kubesphere/pkg/server/options" ) type OAuthProvider interface { @@ -31,5 +31,5 @@ type OAuthProviderFactory interface { // Type unique type of the provider Type() string // Create Apply the dynamic options - Create(options oauth.DynamicOptions) (OAuthProvider, error) + Create(options options.DynamicOptions) (OAuthProvider, error) } diff --git a/pkg/apiserver/authentication/identityprovider/oidc/oidc.go b/pkg/apiserver/authentication/identityprovider/oidc/oidc.go index 88308e2cf..1669522ed 100644 --- a/pkg/apiserver/authentication/identityprovider/oidc/oidc.go +++ b/pkg/apiserver/authentication/identityprovider/oidc/oidc.go @@ -25,15 +25,14 @@ import ( "io" "net/http" - "kubesphere.io/kubesphere/pkg/utils/sliceutil" - "github.com/coreos/go-oidc" "github.com/golang-jwt/jwt/v4" "github.com/mitchellh/mapstructure" "golang.org/x/oauth2" "kubesphere.io/kubesphere/pkg/apiserver/authentication/identityprovider" - "kubesphere.io/kubesphere/pkg/apiserver/authentication/oauth" + "kubesphere.io/kubesphere/pkg/server/options" + "kubesphere.io/kubesphere/pkg/utils/sliceutil" ) func init() { @@ -133,9 +132,9 @@ func (f *oidcProviderFactory) Type() string { return "OIDCIdentityProvider" } -func (f *oidcProviderFactory) Create(options oauth.DynamicOptions) (identityprovider.OAuthProvider, error) { +func (f *oidcProviderFactory) Create(opts options.DynamicOptions) (identityprovider.OAuthProvider, error) { var oidcProvider oidcProvider - if err := mapstructure.Decode(options, &oidcProvider); err != nil { + if err := mapstructure.Decode(opts, &oidcProvider); err != nil { return nil, err } // dynamically discover @@ -169,7 +168,7 @@ func (f *oidcProviderFactory) Create(options oauth.DynamicOptions) (identityprov // TODO: support HS256 ClientID: oidcProvider.ClientID, }) - options["endpoint"] = oauth.DynamicOptions{ + opts["endpoint"] = options.DynamicOptions{ "authURL": oidcProvider.Endpoint.AuthURL, "tokenURL": oidcProvider.Endpoint.TokenURL, "userInfoURL": oidcProvider.Endpoint.UserInfoURL, diff --git a/pkg/apiserver/authentication/identityprovider/oidc/oidc_test.go b/pkg/apiserver/authentication/identityprovider/oidc/oidc_test.go index 2f351de5f..d8a5b3fb8 100644 --- a/pkg/apiserver/authentication/identityprovider/oidc/oidc_test.go +++ b/pkg/apiserver/authentication/identityprovider/oidc/oidc_test.go @@ -33,6 +33,8 @@ import ( "testing" "time" + "kubesphere.io/kubesphere/pkg/server/options" + "github.com/golang-jwt/jwt/v4" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -40,7 +42,6 @@ import ( "gopkg.in/square/go-jose.v2" "kubesphere.io/kubesphere/pkg/apiserver/authentication/identityprovider" - "kubesphere.io/kubesphere/pkg/apiserver/authentication/oauth" ) var ( @@ -167,7 +168,7 @@ var _ = Describe("OIDC", func() { err error ) It("should configure successfully", func() { - config := oauth.DynamicOptions{ + config := options.DynamicOptions{ "issuer": oidcServer.URL, "clientID": "kubesphere", "clientSecret": "c53e80ab92d48ab12f4e7f1f6976d1bdc996e0d7", @@ -177,13 +178,13 @@ var _ = Describe("OIDC", func() { factory := oidcProviderFactory{} provider, err = factory.Create(config) Expect(err).Should(BeNil()) - expected := oauth.DynamicOptions{ + expected := options.DynamicOptions{ "issuer": oidcServer.URL, "clientID": "kubesphere", "clientSecret": "c53e80ab92d48ab12f4e7f1f6976d1bdc996e0d7", "redirectURL": "https://ks-console.kubesphere-system.svc/oauth/redirect/oidc", "insecureSkipVerify": true, - "endpoint": oauth.DynamicOptions{ + "endpoint": options.DynamicOptions{ "authURL": fmt.Sprintf("%s/authorize", oidcServer.URL), "tokenURL": fmt.Sprintf("%s/token", oidcServer.URL), "userInfoURL": fmt.Sprintf("%s/userinfo", oidcServer.URL), diff --git a/pkg/apiserver/authentication/oauth/options.go b/pkg/apiserver/authentication/oauth/options.go index 39b5de24c..8ed1b9a48 100644 --- a/pkg/apiserver/authentication/oauth/options.go +++ b/pkg/apiserver/authentication/oauth/options.go @@ -17,12 +17,12 @@ limitations under the License. package oauth import ( - "encoding/json" "errors" "net/url" - "strings" "time" + "kubesphere.io/kubesphere/pkg/server/options" + "kubesphere.io/kubesphere/pkg/utils/sliceutil" ) @@ -91,57 +91,6 @@ type Options struct { AccessTokenInactivityTimeout time.Duration `json:"accessTokenInactivityTimeout" yaml:"accessTokenInactivityTimeout"` } -// DynamicOptions accept dynamic configuration, the type of key MUST be string -type DynamicOptions map[string]interface{} - -func (o DynamicOptions) MarshalJSON() ([]byte, error) { - data, err := json.Marshal(desensitize(o)) - return data, err -} - -var ( - sensitiveKeys = [...]string{"password", "secret"} -) - -// isSensitiveData returns whether the input string contains sensitive information -func isSensitiveData(key string) bool { - for _, v := range sensitiveKeys { - if strings.Contains(strings.ToLower(key), v) { - return true - } - } - return false -} - -// desensitize returns the desensitized data -func desensitize(data map[string]interface{}) map[string]interface{} { - output := make(map[string]interface{}) - for k, v := range data { - if isSensitiveData(k) { - continue - } - switch v := v.(type) { - case map[interface{}]interface{}: - output[k] = desensitize(convert(v)) - default: - output[k] = v - } - } - return output -} - -// convert returns formatted data -func convert(m map[interface{}]interface{}) map[string]interface{} { - output := make(map[string]interface{}) - for k, v := range m { - switch k := k.(type) { - case string: - output[k] = v - } - } - return output -} - type IdentityProviderOptions struct { // The provider name. Name string `json:"name" yaml:"name"` @@ -164,7 +113,7 @@ type IdentityProviderOptions struct { Type string `json:"type" yaml:"type"` // The options of identify provider - Provider DynamicOptions `json:"provider" yaml:"provider"` + Provider options.DynamicOptions `json:"provider" yaml:"provider"` } type Token struct { diff --git a/pkg/models/auth/oauth_test.go b/pkg/models/auth/oauth_test.go index f999e12d0..cd029f585 100644 --- a/pkg/models/auth/oauth_test.go +++ b/pkg/models/auth/oauth_test.go @@ -22,6 +22,8 @@ import ( "reflect" "testing" + "kubesphere.io/kubesphere/pkg/server/options" + "kubesphere.io/kubesphere/pkg/apiserver/authentication" "github.com/mitchellh/mapstructure" @@ -44,7 +46,7 @@ func Test_oauthAuthenticator_Authenticate(t *testing.T) { Name: "fake", MappingMethod: "auto", Type: "FakeIdentityProvider", - Provider: oauth.DynamicOptions{ + Provider: options.DynamicOptions{ "identities": map[string]interface{}{ "code1": map[string]string{ "uid": "100001", @@ -213,9 +215,9 @@ func (fakeProviderFactory) Type() string { return "FakeIdentityProvider" } -func (fakeProviderFactory) Create(options oauth.DynamicOptions) (identityprovider.OAuthProvider, error) { +func (fakeProviderFactory) Create(dynamicOptions options.DynamicOptions) (identityprovider.OAuthProvider, error) { var fakeProvider fakeProvider - if err := mapstructure.Decode(options, &fakeProvider); err != nil { + if err := mapstructure.Decode(dynamicOptions, &fakeProvider); err != nil { return nil, err } return &fakeProvider, nil diff --git a/pkg/models/auth/password_test.go b/pkg/models/auth/password_test.go index 22b2925a3..8474234b0 100644 --- a/pkg/models/auth/password_test.go +++ b/pkg/models/auth/password_test.go @@ -23,6 +23,8 @@ import ( "reflect" "testing" + "kubesphere.io/kubesphere/pkg/server/options" + "github.com/mitchellh/mapstructure" "golang.org/x/crypto/bcrypt" "k8s.io/apimachinery/pkg/api/errors" @@ -62,7 +64,7 @@ func Test_passwordAuthenticator_Authenticate(t *testing.T) { Name: "fakepwd", MappingMethod: "auto", Type: "fakePasswordProvider", - Provider: oauth.DynamicOptions{ + Provider: options.DynamicOptions{ "identities": map[string]interface{}{ "user1": map[string]string{ "uid": "100001", @@ -84,7 +86,7 @@ func Test_passwordAuthenticator_Authenticate(t *testing.T) { MappingMethod: "auto", Type: "fakePasswordProvider", DisableLoginConfirmation: true, - Provider: oauth.DynamicOptions{ + Provider: options.DynamicOptions{ "identities": map[string]interface{}{ "user5": map[string]string{ "uid": "100005", @@ -100,7 +102,7 @@ func Test_passwordAuthenticator_Authenticate(t *testing.T) { MappingMethod: "lookup", Type: "fakePasswordProvider", DisableLoginConfirmation: true, - Provider: oauth.DynamicOptions{ + Provider: options.DynamicOptions{ "identities": map[string]interface{}{ "user6": map[string]string{ "uid": "100006", @@ -276,9 +278,9 @@ func (fakePasswordProviderFactory) Type() string { return "fakePasswordProvider" } -func (fakePasswordProviderFactory) Create(options oauth.DynamicOptions) (identityprovider.GenericProvider, error) { +func (fakePasswordProviderFactory) Create(dynamicOptions options.DynamicOptions) (identityprovider.GenericProvider, error) { var fakeProvider fakePasswordProvider - if err := mapstructure.Decode(options, &fakeProvider); err != nil { + if err := mapstructure.Decode(dynamicOptions, &fakeProvider); err != nil { return nil, err } return &fakeProvider, nil diff --git a/pkg/server/options/dynamic_options.go b/pkg/server/options/dynamic_options.go new file mode 100644 index 000000000..a59c3f8f3 --- /dev/null +++ b/pkg/server/options/dynamic_options.go @@ -0,0 +1,57 @@ +package options + +import ( + "encoding/json" + "strings" +) + +// DynamicOptions accept dynamic configuration, the type of key MUST be string +type DynamicOptions map[string]interface{} + +func (o DynamicOptions) MarshalJSON() ([]byte, error) { + data, err := json.Marshal(desensitize(o)) + return data, err +} + +var ( + sensitiveKeys = [...]string{"password", "secret"} +) + +// isSensitiveData returns whether the input string contains sensitive information +func isSensitiveData(key string) bool { + for _, v := range sensitiveKeys { + if strings.Contains(strings.ToLower(key), v) { + return true + } + } + return false +} + +// desensitize returns the desensitized data +func desensitize(data map[string]interface{}) map[string]interface{} { + output := make(map[string]interface{}) + for k, v := range data { + if isSensitiveData(k) { + continue + } + switch v := v.(type) { + case map[interface{}]interface{}: + output[k] = desensitize(convert(v)) + default: + output[k] = v + } + } + return output +} + +// convert returns formatted data +func convert(m map[interface{}]interface{}) map[string]interface{} { + output := make(map[string]interface{}) + for k, v := range m { + switch k := k.(type) { + case string: + output[k] = v + } + } + return output +} diff --git a/pkg/simple/client/cache/cache.go b/pkg/simple/client/cache/cache.go index 374f6c0fb..0d8b11f7e 100644 --- a/pkg/simple/client/cache/cache.go +++ b/pkg/simple/client/cache/cache.go @@ -49,10 +49,6 @@ type Interface interface { Expire(key string, duration time.Duration) error } -// DynamicOptions the options of the cache. For redis, options key can be "host", "port", "db", "password". -// For InMemoryCache, options key can be "cleanupperiod" -type DynamicOptions map[string]interface{} - func RegisterCacheFactory(factory CacheFactory) { cacheFactories[factory.Type()] = factory } diff --git a/pkg/simple/client/cache/factory.go b/pkg/simple/client/cache/factory.go index 45b45c326..afe320cf4 100644 --- a/pkg/simple/client/cache/factory.go +++ b/pkg/simple/client/cache/factory.go @@ -1,8 +1,10 @@ package cache +import "kubesphere.io/kubesphere/pkg/server/options" + type CacheFactory interface { // Type unique type of the cache Type() string // Create relevant caches by type - Create(options DynamicOptions, stopCh <-chan struct{}) (Interface, error) + Create(options options.DynamicOptions, stopCh <-chan struct{}) (Interface, error) } diff --git a/pkg/simple/client/cache/inmemory_cache.go b/pkg/simple/client/cache/inmemory_cache.go index 95397cb2e..899b9275f 100644 --- a/pkg/simple/client/cache/inmemory_cache.go +++ b/pkg/simple/client/cache/inmemory_cache.go @@ -21,6 +21,8 @@ import ( "strings" "time" + "kubesphere.io/kubesphere/pkg/server/options" + "github.com/mitchellh/mapstructure" "k8s.io/apimachinery/pkg/util/wait" @@ -177,7 +179,7 @@ func (sf *inMemoryCacheFactory) Type() string { return typeInMemoryCache } -func (sf *inMemoryCacheFactory) Create(options DynamicOptions, stopCh <-chan struct{}) (Interface, error) { +func (sf *inMemoryCacheFactory) Create(options options.DynamicOptions, stopCh <-chan struct{}) (Interface, error) { var sOptions InMemoryCacheOptions decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ diff --git a/pkg/simple/client/cache/options.go b/pkg/simple/client/cache/options.go index 08fd64021..eb84f034a 100644 --- a/pkg/simple/client/cache/options.go +++ b/pkg/simple/client/cache/options.go @@ -18,11 +18,13 @@ package cache import ( "fmt" + + "kubesphere.io/kubesphere/pkg/server/options" ) type Options struct { - Type string `json:"type"` - Options DynamicOptions `json:"options"` + Type string `json:"type"` + Options options.DynamicOptions `json:"options"` } // NewCacheOptions returns options points to nowhere, diff --git a/pkg/simple/client/cache/redis.go b/pkg/simple/client/cache/redis.go index e67250d69..2f5438a64 100644 --- a/pkg/simple/client/cache/redis.go +++ b/pkg/simple/client/cache/redis.go @@ -24,6 +24,8 @@ import ( "github.com/go-redis/redis" "github.com/mitchellh/mapstructure" "k8s.io/klog/v2" + + "kubesphere.io/kubesphere/pkg/server/options" ) const typeRedis = "redis" @@ -108,7 +110,7 @@ func (rf *redisFactory) Type() string { return typeRedis } -func (rf *redisFactory) Create(options DynamicOptions, stopCh <-chan struct{}) (Interface, error) { +func (rf *redisFactory) Create(options options.DynamicOptions, stopCh <-chan struct{}) (Interface, error) { var rOptions redisOptions if err := mapstructure.Decode(options, &rOptions); err != nil { return nil, err