From 666630e4a865bebafaa95e1afb149d27fa90a935 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Budzy=C5=84ski?= Date: Fri, 4 Oct 2024 13:04:57 +0200 Subject: [PATCH] chore: Secret Validation change (#3111) ## Changes - changed secret validation to use generated validation without manual adjustments - changed parsing StringArrays to use `ParseCommaSeparatedStringArray()` - removed known issue with ConflictingFields from sdk generator README - removed comments and replaced them with jira issues --- pkg/sdk/poc/README.md | 23 -------- pkg/sdk/secrets_def.go | 56 ++++++++++-------- pkg/sdk/secrets_dto_builders_gen.go | 35 +++++++----- pkg/sdk/secrets_dto_gen.go | 18 +++--- pkg/sdk/secrets_gen.go | 17 +++--- pkg/sdk/secrets_gen_test.go | 46 ++++++++++----- pkg/sdk/secrets_impl_gen.go | 57 ++++++++----------- pkg/sdk/secrets_validations_gen.go | 9 ++- .../testint/secrets_gen_integration_test.go | 29 +++++----- 9 files changed, 155 insertions(+), 135 deletions(-) diff --git a/pkg/sdk/poc/README.md b/pkg/sdk/poc/README.md index 28786b72d7..44af1e130b 100644 --- a/pkg/sdk/poc/README.md +++ b/pkg/sdk/poc/README.md @@ -132,29 +132,6 @@ type SomeReq struct { } ``` -- Wrong generated validations for `ConflictingFields` for more complicated validations - - For now `everyValueSet()` should be manually changed to `moreThanOneValueSet()` if there is a need to validate only one of many options - - Consider following example for `secret`: -```go -// For validation Conflicting fields: -WithValidation(g.ConflictingFields, "SetForOAuthClientCredentialsFlow", "SetForOAuthAuthorizationFlow", "SetForBasicAuthentication", "SetForGenericString") -``` -```go -// Generation results in: -if valueSet(opts.Set) { - if everyValueSet(opts.Set.SetForOAuthClientCredentialsFlow, opts.Set.SetForOAuthAuthorizationFlow, opts.Set.SetForBasicAuthentication, opts.Set.SetForGenericString) { - errs = append(errs, errOneOf("AlterSecretOptions.Set", "SetForOAuthClientCredentialsFlow", "SetForOAuthAuthorizationFlow", "SetForBasicAuthentication", "SetForGenericString")) - } -} - -// For now needs to be manually changed to: -if valueSet(opts.Set) { - if moreThanOneValueSet(opts.Set.SetForOAuthClientCredentialsFlow, opts.Set.SetForOAuthAuthorizationFlow, opts.Set.SetForBasicAuthentication, opts.Set.SetForGenericString) { - errs = append(errs, errOneOf("AlterSecretOptions.Set", "SetForOAuthClientCredentialsFlow", "SetForOAuthAuthorizationFlow", "SetForBasicAuthentication", "SetForGenericString")) - } -} -``` - ##### Known limitations - automatic array conversion is not recursive, so we're only supporting one level mapping - []Request1{ foo Request2, bar int } won't be converted, but []Request1{ foo string, bar int } will diff --git a/pkg/sdk/secrets_def.go b/pkg/sdk/secrets_def.go index d816f19dcd..a1c2ec1a2f 100644 --- a/pkg/sdk/secrets_def.go +++ b/pkg/sdk/secrets_def.go @@ -62,34 +62,40 @@ var oauthScopesListDef = g.NewQueryStruct("OauthScopesList").List("OauthScopesLi var secretSet = g.NewQueryStruct("SecretSet"). OptionalComment(). OptionalQueryStructField( - "SetForOAuthClientCredentialsFlow", - g.NewQueryStruct("SetForOAuthClientCredentialsFlow"). - OptionalQueryStructField("OauthScopes", oauthScopesListDef, g.ParameterOptions().SQL("OAUTH_SCOPES").Parentheses()), + "SetForFlow", + g.NewQueryStruct("SetForFlow"). + OptionalQueryStructField( + "SetForOAuthClientCredentials", + g.NewQueryStruct("SetForOAuthClientCredentials"). + OptionalQueryStructField("OauthScopes", oauthScopesListDef, g.ParameterOptions().SQL("OAUTH_SCOPES").Parentheses()), + g.KeywordOptions(), + ). + OptionalQueryStructField( + "SetForOAuthAuthorization", + g.NewQueryStruct("SetForOAuthAuthorization"). + OptionalTextAssignment("OAUTH_REFRESH_TOKEN", g.ParameterOptions().SingleQuotes()). + OptionalTextAssignment("OAUTH_REFRESH_TOKEN_EXPIRY_TIME", g.ParameterOptions().SingleQuotes()), + g.KeywordOptions(), + ). + OptionalQueryStructField( + "SetForBasicAuthentication", + g.NewQueryStruct("SetForBasicAuthentication"). + OptionalTextAssignment("USERNAME", g.ParameterOptions().SingleQuotes()). + OptionalTextAssignment("PASSWORD", g.ParameterOptions().SingleQuotes()), + g.KeywordOptions(), + ). + OptionalQueryStructField( + "SetForGenericString", + g.NewQueryStruct("SetForGenericString"). + OptionalTextAssignment("SECRET_STRING", g.ParameterOptions().SingleQuotes()), + g.KeywordOptions(), + ). + WithValidation(g.ExactlyOneValueSet, "SetForOAuthClientCredentials", "SetForOAuthAuthorization", "SetForBasicAuthentication", "SetForGenericString"), g.KeywordOptions(), ). - OptionalQueryStructField( - "SetForOAuthAuthorizationFlow", - g.NewQueryStruct("SetForOAuthAuthorizationFlow"). - OptionalTextAssignment("OAUTH_REFRESH_TOKEN", g.ParameterOptions().SingleQuotes()). - OptionalTextAssignment("OAUTH_REFRESH_TOKEN_EXPIRY_TIME", g.ParameterOptions().SingleQuotes()), - g.KeywordOptions(), - ). - OptionalQueryStructField( - "SetForBasicAuthentication", - g.NewQueryStruct("SetForBasicAuthentication"). - OptionalTextAssignment("USERNAME", g.ParameterOptions().SingleQuotes()). - OptionalTextAssignment("PASSWORD", g.ParameterOptions().SingleQuotes()), - g.KeywordOptions(), - ). - OptionalQueryStructField( - "SetForGenericString", - g.NewQueryStruct("SetForGenericString"). - OptionalTextAssignment("SECRET_STRING", g.ParameterOptions().SingleQuotes()), - g.KeywordOptions(), - ). - WithValidation(g.ConflictingFields, "SetForOAuthClientCredentialsFlow", "SetForOAuthAuthorizationFlow", "SetForBasicAuthentication", "SetForGenericString") + WithValidation(g.AtLeastOneValueSet, "SetForFlow", "Comment") -// UNSET doest work, need to use "SET COMMENT = NULL" +// TODO [SNOW-1678749]: Change to use UNSET when it will be possible var secretUnset = g.NewQueryStruct("SecretUnset"). PredefinedQueryStructField("Comment", "*bool", g.KeywordOptions().SQL("SET COMMENT = NULL")) diff --git a/pkg/sdk/secrets_dto_builders_gen.go b/pkg/sdk/secrets_dto_builders_gen.go index 25eff46b72..08982900a0 100644 --- a/pkg/sdk/secrets_dto_builders_gen.go +++ b/pkg/sdk/secrets_dto_builders_gen.go @@ -155,45 +155,54 @@ func (s *SecretSetRequest) WithComment(Comment string) *SecretSetRequest { return s } -func (s *SecretSetRequest) WithSetForOAuthClientCredentialsFlow(SetForOAuthClientCredentialsFlow SetForOAuthClientCredentialsFlowRequest) *SecretSetRequest { - s.SetForOAuthClientCredentialsFlow = &SetForOAuthClientCredentialsFlow +func (s *SecretSetRequest) WithSetForFlow(SetForFlow SetForFlowRequest) *SecretSetRequest { + s.SetForFlow = &SetForFlow return s } -func (s *SecretSetRequest) WithSetForOAuthAuthorizationFlow(SetForOAuthAuthorizationFlow SetForOAuthAuthorizationFlowRequest) *SecretSetRequest { - s.SetForOAuthAuthorizationFlow = &SetForOAuthAuthorizationFlow +func NewSetForFlowRequest() *SetForFlowRequest { + return &SetForFlowRequest{} +} + +func (s *SetForFlowRequest) WithSetForOAuthClientCredentials(SetForOAuthClientCredentials SetForOAuthClientCredentialsRequest) *SetForFlowRequest { + s.SetForOAuthClientCredentials = &SetForOAuthClientCredentials + return s +} + +func (s *SetForFlowRequest) WithSetForOAuthAuthorization(SetForOAuthAuthorization SetForOAuthAuthorizationRequest) *SetForFlowRequest { + s.SetForOAuthAuthorization = &SetForOAuthAuthorization return s } -func (s *SecretSetRequest) WithSetForBasicAuthentication(SetForBasicAuthentication SetForBasicAuthenticationRequest) *SecretSetRequest { +func (s *SetForFlowRequest) WithSetForBasicAuthentication(SetForBasicAuthentication SetForBasicAuthenticationRequest) *SetForFlowRequest { s.SetForBasicAuthentication = &SetForBasicAuthentication return s } -func (s *SecretSetRequest) WithSetForGenericString(SetForGenericString SetForGenericStringRequest) *SecretSetRequest { +func (s *SetForFlowRequest) WithSetForGenericString(SetForGenericString SetForGenericStringRequest) *SetForFlowRequest { s.SetForGenericString = &SetForGenericString return s } -func NewSetForOAuthClientCredentialsFlowRequest() *SetForOAuthClientCredentialsFlowRequest { - return &SetForOAuthClientCredentialsFlowRequest{} +func NewSetForOAuthClientCredentialsRequest() *SetForOAuthClientCredentialsRequest { + return &SetForOAuthClientCredentialsRequest{} } -func (s *SetForOAuthClientCredentialsFlowRequest) WithOauthScopes(OauthScopes OauthScopesListRequest) *SetForOAuthClientCredentialsFlowRequest { +func (s *SetForOAuthClientCredentialsRequest) WithOauthScopes(OauthScopes OauthScopesListRequest) *SetForOAuthClientCredentialsRequest { s.OauthScopes = &OauthScopes return s } -func NewSetForOAuthAuthorizationFlowRequest() *SetForOAuthAuthorizationFlowRequest { - return &SetForOAuthAuthorizationFlowRequest{} +func NewSetForOAuthAuthorizationRequest() *SetForOAuthAuthorizationRequest { + return &SetForOAuthAuthorizationRequest{} } -func (s *SetForOAuthAuthorizationFlowRequest) WithOauthRefreshToken(OauthRefreshToken string) *SetForOAuthAuthorizationFlowRequest { +func (s *SetForOAuthAuthorizationRequest) WithOauthRefreshToken(OauthRefreshToken string) *SetForOAuthAuthorizationRequest { s.OauthRefreshToken = &OauthRefreshToken return s } -func (s *SetForOAuthAuthorizationFlowRequest) WithOauthRefreshTokenExpiryTime(OauthRefreshTokenExpiryTime string) *SetForOAuthAuthorizationFlowRequest { +func (s *SetForOAuthAuthorizationRequest) WithOauthRefreshTokenExpiryTime(OauthRefreshTokenExpiryTime string) *SetForOAuthAuthorizationRequest { s.OauthRefreshTokenExpiryTime = &OauthRefreshTokenExpiryTime return s } diff --git a/pkg/sdk/secrets_dto_gen.go b/pkg/sdk/secrets_dto_gen.go index 656ca9ac69..dd7ccb7d6a 100644 --- a/pkg/sdk/secrets_dto_gen.go +++ b/pkg/sdk/secrets_dto_gen.go @@ -61,18 +61,22 @@ type AlterSecretRequest struct { } type SecretSetRequest struct { - Comment *string - SetForOAuthClientCredentialsFlow *SetForOAuthClientCredentialsFlowRequest - SetForOAuthAuthorizationFlow *SetForOAuthAuthorizationFlowRequest - SetForBasicAuthentication *SetForBasicAuthenticationRequest - SetForGenericString *SetForGenericStringRequest + Comment *string + SetForFlow *SetForFlowRequest } -type SetForOAuthClientCredentialsFlowRequest struct { +type SetForFlowRequest struct { + SetForOAuthClientCredentials *SetForOAuthClientCredentialsRequest + SetForOAuthAuthorization *SetForOAuthAuthorizationRequest + SetForBasicAuthentication *SetForBasicAuthenticationRequest + SetForGenericString *SetForGenericStringRequest +} + +type SetForOAuthClientCredentialsRequest struct { OauthScopes *OauthScopesListRequest } -type SetForOAuthAuthorizationFlowRequest struct { +type SetForOAuthAuthorizationRequest struct { OauthRefreshToken *string OauthRefreshTokenExpiryTime *string } diff --git a/pkg/sdk/secrets_gen.go b/pkg/sdk/secrets_gen.go index db2d30df35..30d467f25e 100644 --- a/pkg/sdk/secrets_gen.go +++ b/pkg/sdk/secrets_gen.go @@ -86,16 +86,19 @@ type AlterSecretOptions struct { Unset *SecretUnset `ddl:"keyword"` } type SecretSet struct { - Comment *string `ddl:"parameter,single_quotes" sql:"COMMENT"` - SetForOAuthClientCredentialsFlow *SetForOAuthClientCredentialsFlow `ddl:"keyword"` - SetForOAuthAuthorizationFlow *SetForOAuthAuthorizationFlow `ddl:"keyword"` - SetForBasicAuthentication *SetForBasicAuthentication `ddl:"keyword"` - SetForGenericString *SetForGenericString `ddl:"keyword"` + Comment *string `ddl:"parameter,single_quotes" sql:"COMMENT"` + SetForFlow *SetForFlow `ddl:"keyword"` } -type SetForOAuthClientCredentialsFlow struct { +type SetForFlow struct { + SetForOAuthClientCredentials *SetForOAuthClientCredentials `ddl:"keyword"` + SetForOAuthAuthorization *SetForOAuthAuthorization `ddl:"keyword"` + SetForBasicAuthentication *SetForBasicAuthentication `ddl:"keyword"` + SetForGenericString *SetForGenericString `ddl:"keyword"` +} +type SetForOAuthClientCredentials struct { OauthScopes *OauthScopesList `ddl:"parameter,parentheses" sql:"OAUTH_SCOPES"` } -type SetForOAuthAuthorizationFlow struct { +type SetForOAuthAuthorization struct { OauthRefreshToken *string `ddl:"parameter,single_quotes" sql:"OAUTH_REFRESH_TOKEN"` OauthRefreshTokenExpiryTime *string `ddl:"parameter,single_quotes" sql:"OAUTH_REFRESH_TOKEN_EXPIRY_TIME"` } diff --git a/pkg/sdk/secrets_gen_test.go b/pkg/sdk/secrets_gen_test.go index 458d505af0..37cc96726a 100644 --- a/pkg/sdk/secrets_gen_test.go +++ b/pkg/sdk/secrets_gen_test.go @@ -196,26 +196,46 @@ func TestSecrets_Alter(t *testing.T) { assertOptsInvalidJoinedErrors(t, opts, errExactlyOneOf("AlterSecretOptions", "Set", "Unset")) }) - t.Run("validation: conflicting fields for [opts.Set.SetForOAuthClientCredentialsFlow opts.Set.SetForOAuthAuthorizationFlow opts.Set.SetForBasicAuthentication opts.Set.SetForGenericString]", func(t *testing.T) { + t.Run("validation: conflicting fields for [opts.Set.SetForFlow.SetForOAuthClientCredentials opts.Set.SetForFlow.SetForOAuthAuthorization opts.Set.SetForFlow.SetForBasicAuthentication opts.Set.SetForFlow.SetForGenericString]", func(t *testing.T) { opts := setOpts() - opts.Set.SetForOAuthClientCredentialsFlow = &SetForOAuthClientCredentialsFlow{OauthScopes: &OauthScopesList{[]ApiIntegrationScope{{Scope: "foo"}}}} - opts.Set.SetForOAuthAuthorizationFlow = &SetForOAuthAuthorizationFlow{OauthRefreshToken: String("foo"), OauthRefreshTokenExpiryTime: String("bar")} - opts.Set.SetForBasicAuthentication = &SetForBasicAuthentication{Username: String("foo"), Password: String("bar")} - opts.Set.SetForGenericString = &SetForGenericString{SecretString: String("secret")} - assertOptsInvalidJoinedErrors(t, opts, errOneOf("AlterSecretOptions.Set", "SetForOAuthClientCredentialsFlow", "SetForOAuthAuthorizationFlow", "SetForBasicAuthentication", "SetForGenericString")) + opts.Set.SetForFlow = &SetForFlow{} + opts.Set.SetForFlow.SetForOAuthClientCredentials = &SetForOAuthClientCredentials{OauthScopes: &OauthScopesList{[]ApiIntegrationScope{{Scope: "foo"}}}} + opts.Set.SetForFlow.SetForOAuthAuthorization = &SetForOAuthAuthorization{OauthRefreshToken: String("foo"), OauthRefreshTokenExpiryTime: String("bar")} + opts.Set.SetForFlow.SetForBasicAuthentication = &SetForBasicAuthentication{Username: String("foo"), Password: String("bar")} + opts.Set.SetForFlow.SetForGenericString = &SetForGenericString{SecretString: String("secret")} + assertOptsInvalidJoinedErrors(t, opts, errExactlyOneOf("AlterSecretOptions.Set.SetForFlow", "SetForOAuthClientCredentials", "SetForOAuthAuthorization", "SetForBasicAuthentication", "SetForGenericString")) + }) + + t.Run("validation: not every fields specified for conflicting fields [opts.Set.SetForFlow.SetForOAuthClientCredentials opts.Set.SetForFlow.SetForOAuthAuthorization opts.Set.SetForFlow.SetForBasicAuthentication opts.Set.SetForFlow.SetForGenericString]", func(t *testing.T) { + opts := setOpts() + opts.Set.SetForFlow = &SetForFlow{} + opts.Set.SetForFlow.SetForBasicAuthentication = &SetForBasicAuthentication{Username: String("foo"), Password: String("bar")} + opts.Set.SetForFlow.SetForGenericString = &SetForGenericString{SecretString: String("secret")} + assertOptsInvalidJoinedErrors(t, opts, errExactlyOneOf("AlterSecretOptions.Set.SetForFlow", "SetForOAuthClientCredentials", "SetForOAuthAuthorization", "SetForBasicAuthentication", "SetForGenericString")) + }) + + t.Run("validation: valid comment only for at lease one of [opts.Set.SetForFlow opts.Set.Comment]", func(t *testing.T) { + opts := setOpts() + opts.Set.Comment = String("test") + assertOptsValid(t, opts) + }) + + t.Run("validation: at least one of [opts.Set.SetForFlow opts.Set.Comment]", func(t *testing.T) { + opts := setOpts() + assertOptsInvalidJoinedErrors(t, opts, errAtLeastOneOf("AlterSecretOptions.Set", "SetForFlow", "Comment")) }) t.Run("alter: set options for Oauth Client Credentials Flow", func(t *testing.T) { opts := setOpts() opts.Set.Comment = String("test") - opts.Set.SetForOAuthClientCredentialsFlow = &SetForOAuthClientCredentialsFlow{OauthScopes: &OauthScopesList{[]ApiIntegrationScope{{"sample_scope"}}}} + opts.Set.SetForFlow = &SetForFlow{SetForOAuthClientCredentials: &SetForOAuthClientCredentials{OauthScopes: &OauthScopesList{[]ApiIntegrationScope{{"sample_scope"}}}}} assertOptsValidAndSQLEquals(t, opts, "ALTER SECRET IF EXISTS %s SET COMMENT = 'test' OAUTH_SCOPES = ('sample_scope')", id.FullyQualifiedName()) }) t.Run("alter: set options for Oauth Client Credentials Flow - empty oauth scopes list", func(t *testing.T) { opts := setOpts() opts.Set.Comment = String("test") - opts.Set.SetForOAuthClientCredentialsFlow = &SetForOAuthClientCredentialsFlow{OauthScopes: &OauthScopesList{}} + opts.Set.SetForFlow = &SetForFlow{SetForOAuthClientCredentials: &SetForOAuthClientCredentials{OauthScopes: &OauthScopesList{}}} assertOptsValidAndSQLEquals(t, opts, "ALTER SECRET IF EXISTS %s SET COMMENT = 'test' OAUTH_SCOPES = ()", id.FullyQualifiedName()) }) @@ -228,20 +248,20 @@ func TestSecrets_Alter(t *testing.T) { t.Run("alter: set options for Oauth Authorization Flow", func(t *testing.T) { opts := setOpts() opts.Set.Comment = String("test") - opts.Set.SetForOAuthAuthorizationFlow = &SetForOAuthAuthorizationFlow{ + opts.Set.SetForFlow = &SetForFlow{SetForOAuthAuthorization: &SetForOAuthAuthorization{ OauthRefreshToken: String("test_token"), OauthRefreshTokenExpiryTime: String("2024-11-11"), - } + }} assertOptsValidAndSQLEquals(t, opts, "ALTER SECRET IF EXISTS %s SET COMMENT = 'test' OAUTH_REFRESH_TOKEN = 'test_token' OAUTH_REFRESH_TOKEN_EXPIRY_TIME = '2024-11-11'", id.FullyQualifiedName()) }) t.Run("alter: set options for Basic Authentication", func(t *testing.T) { opts := setOpts() opts.Set.Comment = String("test") - opts.Set.SetForBasicAuthentication = &SetForBasicAuthentication{ + opts.Set.SetForFlow = &SetForFlow{SetForBasicAuthentication: &SetForBasicAuthentication{ Username: String("foo"), Password: String("bar"), - } + }} assertOptsValidAndSQLEquals(t, opts, "ALTER SECRET IF EXISTS %s SET COMMENT = 'test' USERNAME = 'foo' PASSWORD = 'bar'", id.FullyQualifiedName()) }) @@ -254,7 +274,7 @@ func TestSecrets_Alter(t *testing.T) { t.Run("alter: set options for Generic string", func(t *testing.T) { opts := setOpts() opts.Set.Comment = String("test") - opts.Set.SetForGenericString = &SetForGenericString{String("test")} + opts.Set.SetForFlow = &SetForFlow{SetForGenericString: &SetForGenericString{String("test")}} assertOptsValidAndSQLEquals(t, opts, "ALTER SECRET IF EXISTS %s SET COMMENT = 'test' SECRET_STRING = 'test'", id.FullyQualifiedName()) }) diff --git a/pkg/sdk/secrets_impl_gen.go b/pkg/sdk/secrets_impl_gen.go index f6804181f0..c758ad5aad 100644 --- a/pkg/sdk/secrets_impl_gen.go +++ b/pkg/sdk/secrets_impl_gen.go @@ -2,7 +2,6 @@ package sdk import ( "context" - "strings" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/collections" ) @@ -139,33 +138,37 @@ func (r *AlterSecretRequest) toOpts() *AlterSecretOptions { Comment: r.Set.Comment, } - if r.Set.SetForOAuthClientCredentialsFlow != nil { - opts.Set.SetForOAuthClientCredentialsFlow = &SetForOAuthClientCredentialsFlow{} + if r.Set.SetForFlow != nil { + opts.Set.SetForFlow = &SetForFlow{} - if r.Set.SetForOAuthClientCredentialsFlow.OauthScopes != nil { - opts.Set.SetForOAuthClientCredentialsFlow.OauthScopes = &OauthScopesList{ - OauthScopesList: r.Set.SetForOAuthClientCredentialsFlow.OauthScopes.OauthScopesList, + if r.Set.SetForFlow.SetForOAuthClientCredentials != nil { + opts.Set.SetForFlow.SetForOAuthClientCredentials = &SetForOAuthClientCredentials{} + + if r.Set.SetForFlow.SetForOAuthClientCredentials.OauthScopes != nil { + opts.Set.SetForFlow.SetForOAuthClientCredentials.OauthScopes = &OauthScopesList{ + OauthScopesList: r.Set.SetForFlow.SetForOAuthClientCredentials.OauthScopes.OauthScopesList, + } } } - } - if r.Set.SetForOAuthAuthorizationFlow != nil { - opts.Set.SetForOAuthAuthorizationFlow = &SetForOAuthAuthorizationFlow{ - OauthRefreshToken: r.Set.SetForOAuthAuthorizationFlow.OauthRefreshToken, - OauthRefreshTokenExpiryTime: r.Set.SetForOAuthAuthorizationFlow.OauthRefreshTokenExpiryTime, + if r.Set.SetForFlow.SetForOAuthAuthorization != nil { + opts.Set.SetForFlow.SetForOAuthAuthorization = &SetForOAuthAuthorization{ + OauthRefreshToken: r.Set.SetForFlow.SetForOAuthAuthorization.OauthRefreshToken, + OauthRefreshTokenExpiryTime: r.Set.SetForFlow.SetForOAuthAuthorization.OauthRefreshTokenExpiryTime, + } } - } - if r.Set.SetForBasicAuthentication != nil { - opts.Set.SetForBasicAuthentication = &SetForBasicAuthentication{ - Username: r.Set.SetForBasicAuthentication.Username, - Password: r.Set.SetForBasicAuthentication.Password, + if r.Set.SetForFlow.SetForBasicAuthentication != nil { + opts.Set.SetForFlow.SetForBasicAuthentication = &SetForBasicAuthentication{ + Username: r.Set.SetForFlow.SetForBasicAuthentication.Username, + Password: r.Set.SetForFlow.SetForBasicAuthentication.Password, + } } - } - if r.Set.SetForGenericString != nil { - opts.Set.SetForGenericString = &SetForGenericString{ - SecretString: r.Set.SetForGenericString.SecretString, + if r.Set.SetForFlow.SetForGenericString != nil { + opts.Set.SetForFlow.SetForGenericString = &SetForGenericString{ + SecretString: r.Set.SetForFlow.SetForGenericString.SecretString, + } } } } @@ -195,16 +198,6 @@ func (r *ShowSecretRequest) toOpts() *ShowSecretOptions { return opts } -func getOauthScopes(scopesString string) []string { - formatedScopes := make([]string, 0) - scopesString = strings.TrimPrefix(scopesString, "[") - scopesString = strings.TrimSuffix(scopesString, "]") - for _, scope := range strings.Split(scopesString, ",") { - formatedScopes = append(formatedScopes, strings.TrimSpace(scope)) - } - return formatedScopes -} - func (r secretDBRow) convert() *Secret { s := &Secret{ CreatedOn: r.CreatedOn, @@ -219,7 +212,7 @@ func (r secretDBRow) convert() *Secret { s.Comment = String(r.Comment.String) } if r.OauthScopes.Valid { - s.OauthScopes = getOauthScopes(r.OauthScopes.String) + s.OauthScopes = ParseCommaSeparatedStringArray(r.OauthScopes.String, false) } return s } @@ -249,7 +242,7 @@ func (r secretDetailsDBRow) convert() *SecretDetails { s.Comment = String(r.Comment.String) } if r.OauthScopes.Valid { - s.OauthScopes = getOauthScopes(r.OauthScopes.String) + s.OauthScopes = ParseCommaSeparatedStringArray(r.OauthScopes.String, false) } if r.IntegrationName.Valid { s.IntegrationName = String(r.IntegrationName.String) diff --git a/pkg/sdk/secrets_validations_gen.go b/pkg/sdk/secrets_validations_gen.go index a324b74dee..b674cf0e28 100644 --- a/pkg/sdk/secrets_validations_gen.go +++ b/pkg/sdk/secrets_validations_gen.go @@ -76,8 +76,13 @@ func (opts *AlterSecretOptions) validate() error { errs = append(errs, errExactlyOneOf("AlterSecretOptions", "Set", "Unset")) } if valueSet(opts.Set) { - if moreThanOneValueSet(opts.Set.SetForOAuthClientCredentialsFlow, opts.Set.SetForOAuthAuthorizationFlow, opts.Set.SetForBasicAuthentication, opts.Set.SetForGenericString) { - errs = append(errs, errOneOf("AlterSecretOptions.Set", "SetForOAuthClientCredentialsFlow", "SetForOAuthAuthorizationFlow", "SetForBasicAuthentication", "SetForGenericString")) + if !anyValueSet(opts.Set.SetForFlow, opts.Set.Comment) { + errs = append(errs, errAtLeastOneOf("AlterSecretOptions.Set", "SetForFlow", "Comment")) + } + if valueSet(opts.Set.SetForFlow) { + if !exactlyOneValueSet(opts.Set.SetForFlow.SetForOAuthClientCredentials, opts.Set.SetForFlow.SetForOAuthAuthorization, opts.Set.SetForFlow.SetForBasicAuthentication, opts.Set.SetForFlow.SetForGenericString) { + errs = append(errs, errExactlyOneOf("AlterSecretOptions.Set.SetForFlow", "SetForOAuthClientCredentials", "SetForOAuthAuthorization", "SetForBasicAuthentication", "SetForGenericString")) + } } } return JoinErrors(errs...) diff --git a/pkg/sdk/testint/secrets_gen_integration_test.go b/pkg/sdk/testint/secrets_gen_integration_test.go index 5e845368db..fef05740ba 100644 --- a/pkg/sdk/testint/secrets_gen_integration_test.go +++ b/pkg/sdk/testint/secrets_gen_integration_test.go @@ -19,7 +19,7 @@ func TestInt_Secrets(t *testing.T) { integrationId := testClientHelper().Ids.RandomAccountObjectIdentifier() - // "YYYY-MM-DD" or "YYYY-MM-DD HH-MI-SS" format has to be used, otherwise Snowflake returns error: "Invalid date/time format" + // "YYYY-MM-DD" or "YYYY-MM-DD HH:MI-SS" format has to be used, otherwise Snowflake returns error: "Invalid date/time format" refreshTokenExpiryTime := time.Now().Add(24 * time.Hour).Format(time.DateOnly) _, apiIntegrationCleanup := testClientHelper().SecurityIntegration.CreateApiAuthenticationClientCredentialsWithRequest(t, @@ -94,8 +94,7 @@ func TestInt_Secrets(t *testing.T) { }) }) - // It is possible to create secret without specifying both refresh token properties and OAuth scopes - // Regarding the https://docs.snowflake.com/en/sql-reference/sql/create-secret secret with empty oauth_scopes list should inherit scopes from security_integration, but it does not + // TODO [SNOW-1678767]: possible to create secret without specifying refresh token, token expiry time and OAuth scopes properties t.Run("Create: secretWithOAuth - minimal, without token and scopes", func(t *testing.T) { id := testClientHelper().Ids.RandomSchemaObjectIdentifier() request := sdk.NewCreateWithOAuthClientCredentialsFlowSecretRequest(id, integrationId) @@ -121,7 +120,7 @@ func TestInt_Secrets(t *testing.T) { }) }) - // regarding the https://docs.snowflake.com/en/sql-reference/sql/create-secret secret with empty oauth_scopes list should inherit scopes from security_integration, but it does not + // TODO [SNOW-1678756]: oauth_copes not inherited or not displayed correctly when not provided t.Run("Create: SecretWithOAuthClientCredentialsFlow - Empty Scopes List", func(t *testing.T) { id := testClientHelper().Ids.RandomSchemaObjectIdentifier() request := sdk.NewCreateWithOAuthClientCredentialsFlowSecretRequest(id, integrationId).WithOauthScopes(sdk.OauthScopesListRequest{}) @@ -146,7 +145,7 @@ func TestInt_Secrets(t *testing.T) { assert.NotContains(t, details.OauthScopes, "foo") assert.NotContains(t, details.OauthScopes, "bar") - assert.Equal(t, []string{""}, details.OauthScopes) + assert.Equal(t, []string{}, details.OauthScopes) }) t.Run("Create: SecretWithOAuthAuthorizationCodeFlow - refreshTokenExpiry date format", func(t *testing.T) { @@ -308,9 +307,10 @@ func TestInt_Secrets(t *testing.T) { WithSet( *sdk.NewSecretSetRequest(). WithComment(comment). - WithSetForOAuthClientCredentialsFlow( - *sdk.NewSetForOAuthClientCredentialsFlowRequest(). + WithSetForFlow(*sdk.NewSetForFlowRequest(). + WithSetForOAuthClientCredentials(*sdk.NewSetForOAuthClientCredentialsRequest(). WithOauthScopes(sdk.OauthScopesListRequest{OauthScopesList: []sdk.ApiIntegrationScope{{Scope: "foo"}, {Scope: "bar"}}}), + ), ), ) err := client.Secrets.Alter(ctx, setRequest) @@ -353,10 +353,11 @@ func TestInt_Secrets(t *testing.T) { WithSet( *sdk.NewSecretSetRequest(). WithComment(comment). - WithSetForOAuthAuthorizationFlow( - *sdk.NewSetForOAuthAuthorizationFlowRequest(). + WithSetForFlow(*sdk.NewSetForFlowRequest(). + WithSetForOAuthAuthorization(*sdk.NewSetForOAuthAuthorizationRequest(). WithOauthRefreshToken("bar"). WithOauthRefreshTokenExpiryTime(alteredRefreshTokenExpiryTime), + ), ), ) err := client.Secrets.Alter(ctx, setRequest) @@ -398,10 +399,11 @@ func TestInt_Secrets(t *testing.T) { WithSet( *sdk.NewSecretSetRequest(). WithComment(comment). - WithSetForBasicAuthentication( - *sdk.NewSetForBasicAuthenticationRequest(). + WithSetForFlow(*sdk.NewSetForFlowRequest(). + WithSetForBasicAuthentication(*sdk.NewSetForBasicAuthenticationRequest(). WithUsername("bar"). WithPassword("bar"), + ), ), ) err := client.Secrets.Alter(ctx, setRequest) @@ -442,9 +444,10 @@ func TestInt_Secrets(t *testing.T) { WithSet( *sdk.NewSecretSetRequest(). WithComment(comment). - WithSetForGenericString( - *sdk.NewSetForGenericStringRequest(). + WithSetForFlow(*sdk.NewSetForFlowRequest(). + WithSetForGenericString(*sdk.NewSetForGenericStringRequest(). WithSecretString("bar"), + ), ), ) err := client.Secrets.Alter(ctx, setRequest)