From 330dd832c150fea3dccb90ffc1bc938693386a05 Mon Sep 17 00:00:00 2001 From: Vivek Singh Chauhan Date: Wed, 11 Sep 2024 09:16:39 -0700 Subject: [PATCH] APIGOV-28733 - config for internal OAuth methods (#830) - filter and sort order for internal OAuth CRD types to be allowed when associating to instance --- pkg/apic/apiserviceinstance.go | 7 ++++++- pkg/apic/mockserviceclient.go | 1 + pkg/apic/servicebody.go | 8 ++++++-- pkg/config/centralconfig.go | 3 +++ pkg/config/credentialconfig.go | 30 ++++++++++++++++++++++++++++-- 5 files changed, 44 insertions(+), 5 deletions(-) diff --git a/pkg/apic/apiserviceinstance.go b/pkg/apic/apiserviceinstance.go index 0b005c683..740bd382b 100644 --- a/pkg/apic/apiserviceinstance.go +++ b/pkg/apic/apiserviceinstance.go @@ -29,7 +29,12 @@ func buildAPIServiceInstanceMarketplaceSpec( } func (c *ServiceClient) checkCredentialRequestDefinitions(serviceBody *ServiceBody) []string { - crds := serviceBody.GetCredentialRequestDefinitions() + allowedOAuthMethods := make([]string, 0) + if c.cfg != nil && c.cfg.GetCredentialConfig() != nil { + allowedOAuthMethods = c.cfg.GetCredentialConfig().GetAllowedOAuthMethods() + } + + crds := serviceBody.GetCredentialRequestDefinitions(allowedOAuthMethods) // remove any crd not in the cache knownCRDs := make([]string, 0) diff --git a/pkg/apic/mockserviceclient.go b/pkg/apic/mockserviceclient.go index 78be09cce..b603ff391 100644 --- a/pkg/apic/mockserviceclient.go +++ b/pkg/apic/mockserviceclient.go @@ -34,6 +34,7 @@ func GetTestServiceClient() (*ServiceClient, *api.MockHTTPClient) { Realm: "Broker", ClientID: "dummy", }, + CredentialConfig: &corecfg.CredentialConfiguration{}, } apiClient := &api.MockHTTPClient{ResponseCode: http.StatusOK} diff --git a/pkg/apic/servicebody.go b/pkg/apic/servicebody.go index b67648f4a..c879cfeb0 100644 --- a/pkg/apic/servicebody.go +++ b/pkg/apic/servicebody.go @@ -93,7 +93,7 @@ func (s *ServiceBody) GetScopes() map[string]string { } // GetCredentialRequestDefinitions - returns the array of all credential request policies -func (s *ServiceBody) GetCredentialRequestDefinitions() []string { +func (s *ServiceBody) GetCredentialRequestDefinitions(allowedOAuthMethods []string) []string { if len(s.credentialRequestPolicies) > 0 || s.ignoreSpecBasesCreds { return s.credentialRequestPolicies } @@ -105,7 +105,11 @@ func (s *ServiceBody) GetCredentialRequestDefinitions() []string { s.credentialRequestPolicies = append(s.credentialRequestPolicies, provisioning.APIKeyCRD) } if policy == Oauth { - s.credentialRequestPolicies = append(s.credentialRequestPolicies, []string{provisioning.OAuthPublicKeyCRD, provisioning.OAuthSecretCRD}...) + oauthCRDs := []string{provisioning.OAuthPublicKeyCRD, provisioning.OAuthSecretCRD} + if len(allowedOAuthMethods) > 0 { + oauthCRDs = allowedOAuthMethods + } + s.credentialRequestPolicies = append(s.credentialRequestPolicies, oauthCRDs...) } } return s.credentialRequestPolicies diff --git a/pkg/config/centralconfig.go b/pkg/config/centralconfig.go index 44345d56a..a0a39b672 100644 --- a/pkg/config/centralconfig.go +++ b/pkg/config/centralconfig.go @@ -667,6 +667,7 @@ const ( pathGRPCInsecure = "central.grpc.insecure" pathCacheStoragePath = "central.cacheStoragePath" pathCacheStorageInterval = "central.cacheStorageInterval" + pathCredentialsOAuthMethods = "central.credentials.oauthMethods" ) // ValidateCfg - Validates the config, implementing IConfigInterface @@ -834,6 +835,7 @@ func AddCentralConfigProperties(props properties.Properties, agentType AgentType props.AddBoolProperty(pathGRPCInsecure, false, "Controls whether an agent uses a gRPC connection with TLS") props.AddStringProperty(pathCacheStoragePath, "", "The directory path where agent cache will be persisted to file") props.AddDurationProperty(pathCacheStorageInterval, 10*time.Second, "The interval to persist agent caches to file", properties.WithLowerLimit(10*time.Second)) + props.AddStringSliceProperty(pathCredentialsOAuthMethods, []string{}, "Allowed OAuth credential types") if supportsTraceability(agentType) { props.AddStringProperty(pathEnvironmentID, "", "Offline Usage Reporting Only. The Environment ID the usage is associated with on Amplify Central") @@ -942,6 +944,7 @@ func ParseCentralConfig(props properties.Properties, agentType AgentType) (Centr cfg.AppendEnvironmentToTitle = props.BoolPropertyValue(pathAppendEnvironmentToTitle) cfg.MigrationSettings = ParseMigrationConfig(props) cfg.CredentialConfig = newCredentialConfig() + cfg.CredentialConfig.SetAllowedOAuthMethods(props.StringSlicePropertyValue(pathCredentialsOAuthMethods)) } if cfg.AgentName == "" && cfg.Environment != "" && agentType.ToShortString() != "" { cfg.AgentName = cfg.Environment + "-" + agentType.ToShortString() diff --git a/pkg/config/credentialconfig.go b/pkg/config/credentialconfig.go index 2ce556a4c..aae402bc6 100644 --- a/pkg/config/credentialconfig.go +++ b/pkg/config/credentialconfig.go @@ -1,7 +1,16 @@ package config +import "errors" + +var supportedOAuthMethods = map[string]bool{ + "oauth-secret": true, + "oauth-public-key": true, +} + // SubscriptionConfig - Interface to get subscription config type CredentialConfig interface { + SetAllowedOAuthMethods(allowedMethods []string) + GetAllowedOAuthMethods() []string ShouldDeprovisionExpired() bool SetShouldDeprovisionExpired(deprovisionExpired bool) GetExpirationDays() int @@ -10,18 +19,30 @@ type CredentialConfig interface { // NotificationConfig - type CredentialConfiguration struct { - ExpirationDays int `config:"expirationDays"` - DeprovisionOnExpire bool `config:"deprovisionOnExpire"` + AllowedOAuthMethods []string `config:"allowedOAuthMethods"` + ExpirationDays int `config:"expirationDays"` + DeprovisionOnExpire bool `config:"deprovisionOnExpire"` } // newCredentialConfig - Creates the default credential config func newCredentialConfig() CredentialConfig { return &CredentialConfiguration{ + AllowedOAuthMethods: make([]string, 0), ExpirationDays: 0, DeprovisionOnExpire: false, } } +// SetAllowedOAuthMethods - +func (s *CredentialConfiguration) SetAllowedOAuthMethods(allowedOAuthMethods []string) { + s.AllowedOAuthMethods = allowedOAuthMethods +} + +// GetAllowedOAuthMethods - +func (s *CredentialConfiguration) GetAllowedOAuthMethods() []string { + return s.AllowedOAuthMethods +} + // ExpireAction - func (s *CredentialConfiguration) ShouldDeprovisionExpired() bool { return s.DeprovisionOnExpire @@ -44,6 +65,11 @@ func (s *CredentialConfiguration) SetExpirationDays(expirationDays int) { // ValidateCfg - Validates the config, implementing IConfigInterface func (s *CredentialConfiguration) ValidateCfg() error { + for _, method := range s.AllowedOAuthMethods { + if _, ok := supportedOAuthMethods[method]; !ok { + return errors.New("credential type in allowed method configuration is not supported") + } + } // TODO - validate time to live return nil }