Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add authentication policies to SDK #2937

Merged
Merged
54 changes: 54 additions & 0 deletions pkg/acceptance/helpers/authentication_policy_client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package helpers

import (
"context"
"testing"

"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"
"github.com/stretchr/testify/require"
)

type AuthenticationPolicyClient struct {
context *TestClientContext
ids *IdsGenerator
}

func NewAuthenticationPolicyClient(context *TestClientContext, idsGenerator *IdsGenerator) *AuthenticationPolicyClient {
return &AuthenticationPolicyClient{
context: context,
ids: idsGenerator,
}
}

func (c *AuthenticationPolicyClient) client() sdk.AuthenticationPolicies {
return c.context.client.AuthenticationPolicies
}

func (c *AuthenticationPolicyClient) CreateAuthenticationPolicy(t *testing.T) (*sdk.AuthenticationPolicy, func()) {
t.Helper()
id := c.ids.RandomSchemaObjectIdentifier()
return c.CreateAuthenticationPolicyWithOptions(t, id, sdk.NewCreateAuthenticationPolicyRequest(id))
}

func (c *AuthenticationPolicyClient) CreateAuthenticationPolicyWithOptions(t *testing.T, id sdk.SchemaObjectIdentifier, request *sdk.CreateAuthenticationPolicyRequest) (*sdk.AuthenticationPolicy, func()) {
t.Helper()
ctx := context.Background()

err := c.client().Create(ctx, request)
require.NoError(t, err)

sessionPolicy, err := c.client().ShowByID(ctx, id)
require.NoError(t, err)

return sessionPolicy, c.DropAuthenticationPolicyFunc(t, id)
}

func (c *AuthenticationPolicyClient) DropAuthenticationPolicyFunc(t *testing.T, id sdk.SchemaObjectIdentifier) func() {
t.Helper()
ctx := context.Background()

return func() {
err := c.client().Drop(ctx, sdk.NewDropAuthenticationPolicyRequest(id).WithIfExists(true))
require.NoError(t, err)
}
}
2 changes: 2 additions & 0 deletions pkg/acceptance/helpers/test_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type TestClient struct {
ApiIntegration *ApiIntegrationClient
Application *ApplicationClient
ApplicationPackage *ApplicationPackageClient
AuthenticationPolicy *AuthenticationPolicyClient
BcrBundles *BcrBundlesClient
Context *ContextClient
CortexSearchService *CortexSearchServiceClient
Expand Down Expand Up @@ -79,6 +80,7 @@ func NewTestClient(c *sdk.Client, database string, schema string, warehouse stri
ApiIntegration: NewApiIntegrationClient(context, idsGenerator),
Application: NewApplicationClient(context, idsGenerator),
ApplicationPackage: NewApplicationPackageClient(context, idsGenerator),
AuthenticationPolicy: NewAuthenticationPolicyClient(context, idsGenerator),
BcrBundles: NewBcrBundlesClient(context),
Context: NewContextClient(context),
CortexSearchService: NewCortexSearchServiceClient(context, idsGenerator),
Expand Down
24 changes: 13 additions & 11 deletions pkg/sdk/accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,16 +162,17 @@ func (opts *AccountLevelParameters) validate() error {
}

type AccountSet struct {
Parameters *AccountLevelParameters `ddl:"list,no_parentheses"`
ResourceMonitor AccountObjectIdentifier `ddl:"identifier,equals" sql:"RESOURCE_MONITOR"`
PasswordPolicy SchemaObjectIdentifier `ddl:"identifier" sql:"PASSWORD POLICY"`
SessionPolicy SchemaObjectIdentifier `ddl:"identifier" sql:"SESSION POLICY"`
Parameters *AccountLevelParameters `ddl:"list,no_parentheses"`
ResourceMonitor AccountObjectIdentifier `ddl:"identifier,equals" sql:"RESOURCE_MONITOR"`
PasswordPolicy SchemaObjectIdentifier `ddl:"identifier" sql:"PASSWORD POLICY"`
SessionPolicy SchemaObjectIdentifier `ddl:"identifier" sql:"SESSION POLICY"`
AuthenticationPolicy SchemaObjectIdentifier `ddl:"identifier" sql:"AUTHENTICATION POLICY"`
}

func (opts *AccountSet) validate() error {
var errs []error
if !exactlyOneValueSet(opts.Parameters, opts.ResourceMonitor, opts.PasswordPolicy, opts.SessionPolicy) {
errs = append(errs, errExactlyOneOf("AccountSet", "Parameters", "ResourceMonitor", "PasswordPolicy", "SessionPolicy"))
if !exactlyOneValueSet(opts.Parameters, opts.ResourceMonitor, opts.PasswordPolicy, opts.SessionPolicy, opts.AuthenticationPolicy) {
errs = append(errs, errExactlyOneOf("AccountSet", "Parameters", "ResourceMonitor", "PasswordPolicy", "SessionPolicy", "AuthenticationPolicy"))
}
if valueSet(opts.Parameters) {
if err := opts.Parameters.validate(); err != nil {
Expand All @@ -196,15 +197,16 @@ func (opts *AccountLevelParametersUnset) validate() error {
}

type AccountUnset struct {
Parameters *AccountLevelParametersUnset `ddl:"list,no_parentheses"`
PasswordPolicy *bool `ddl:"keyword" sql:"PASSWORD POLICY"`
SessionPolicy *bool `ddl:"keyword" sql:"SESSION POLICY"`
Parameters *AccountLevelParametersUnset `ddl:"list,no_parentheses"`
PasswordPolicy *bool `ddl:"keyword" sql:"PASSWORD POLICY"`
SessionPolicy *bool `ddl:"keyword" sql:"SESSION POLICY"`
AuthenticationPolicy *bool `ddl:"keyword" sql:"AUTHENTICATION POLICY"`
}

func (opts *AccountUnset) validate() error {
var errs []error
if !exactlyOneValueSet(opts.Parameters, opts.PasswordPolicy, opts.SessionPolicy) {
errs = append(errs, errExactlyOneOf("AccountUnset", "Parameters", "PasswordPolicy", "SessionPolicy"))
if !exactlyOneValueSet(opts.Parameters, opts.PasswordPolicy, opts.SessionPolicy, opts.AuthenticationPolicy) {
errs = append(errs, errExactlyOneOf("AccountUnset", "Parameters", "PasswordPolicy", "SessionPolicy", "AuthenticationPolicy"))
}
if valueSet(opts.Parameters) {
if err := opts.Parameters.validate(); err != nil {
Expand Down
19 changes: 19 additions & 0 deletions pkg/sdk/accounts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,16 @@ func TestAccountAlter(t *testing.T) {
assertOptsValidAndSQLEquals(t, opts, `ALTER ACCOUNT SET SESSION POLICY %s`, id.FullyQualifiedName())
})

t.Run("with set authentication policy", func(t *testing.T) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the validation tests are missing (validations were updated but no test failed here)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in #3068

id := randomSchemaObjectIdentifier()
opts := &AlterAccountOptions{
Set: &AccountSet{
AuthenticationPolicy: id,
},
}
assertOptsValidAndSQLEquals(t, opts, `ALTER ACCOUNT SET AUTHENTICATION POLICY %s`, id.FullyQualifiedName())
})

t.Run("with unset password policy", func(t *testing.T) {
opts := &AlterAccountOptions{
Unset: &AccountUnset{
Expand All @@ -140,6 +150,15 @@ func TestAccountAlter(t *testing.T) {
assertOptsValidAndSQLEquals(t, opts, `ALTER ACCOUNT UNSET SESSION POLICY`)
})

t.Run("with unset authentication policy", func(t *testing.T) {
opts := &AlterAccountOptions{
Unset: &AccountUnset{
AuthenticationPolicy: Bool(true),
},
}
assertOptsValidAndSQLEquals(t, opts, `ALTER ACCOUNT UNSET AUTHENTICATION POLICY`)
})

t.Run("with set tag", func(t *testing.T) {
tagId1 := randomSchemaObjectIdentifier()
tagId2 := randomSchemaObjectIdentifierInSchema(tagId1.SchemaId())
Expand Down
126 changes: 126 additions & 0 deletions pkg/sdk/authentication_policies_def.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package sdk

import g "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk/poc/generator"

//go:generate go run ./poc/main.go

var AuthenticationMethodsOptionDef = g.NewQueryStruct("AuthenticationMethods").Text("Method", g.KeywordOptions().SingleQuotes())
var MfaAuthenticationMethodsOptionDef = g.NewQueryStruct("MfaAuthenticationMethods").Text("Method", g.KeywordOptions().SingleQuotes())
var ClientTypesOptionDef = g.NewQueryStruct("ClientTypes").Text("ClientType", g.KeywordOptions().SingleQuotes())
var SecurityIntegrationsOptionDef = g.NewQueryStruct("SecurityIntegrationsOption").Text("Name", g.KeywordOptions().SingleQuotes())

var (
AuthenticationPoliciesDef = g.NewInterface(
"AuthenticationPolicies",
"AuthenticationPolicy",
g.KindOfT[SchemaObjectIdentifier](),
).
CreateOperation(
"https://docs.snowflake.com/en/sql-reference/sql/create-authentication-policy",
g.NewQueryStruct("CreateAuthenticationPolicy").
Create().
OrReplace().
SQL("AUTHENTICATION POLICY").
sfc-gh-jcieslak marked this conversation as resolved.
Show resolved Hide resolved
Name().
ListAssignment("AUTHENTICATION_METHODS", "AuthenticationMethods", g.ParameterOptions().Parentheses()).
ListAssignment("MFA_AUTHENTICATION_METHODS", "MfaAuthenticationMethods", g.ParameterOptions().Parentheses()).
OptionalTextAssignment("MFA_ENROLLMENT", g.ParameterOptions()).
ListAssignment("CLIENT_TYPES", "ClientTypes", g.ParameterOptions().Parentheses()).
ListAssignment("SECURITY_INTEGRATIONS", "SecurityIntegrationsOption", g.ParameterOptions().Parentheses()).
OptionalTextAssignment("COMMENT", g.ParameterOptions().SingleQuotes()).
WithValidation(g.ValidIdentifier, "name"),
AuthenticationMethodsOptionDef,
MfaAuthenticationMethodsOptionDef,
ClientTypesOptionDef,
SecurityIntegrationsOptionDef,
).
AlterOperation(
"https://docs.snowflake.com/en/sql-reference/sql/alter-authentication-policy",
g.NewQueryStruct("AlterAuthenticationPolicy").
Alter().
SQL("AUTHENTICATION POLICY").
IfExists().
Name().
OptionalQueryStructField(
"Set",
g.NewQueryStruct("AuthenticationPolicySet").
ListAssignment("AUTHENTICATION_METHODS", "AuthenticationMethods", g.ParameterOptions().Parentheses()).
ListAssignment("MFA_AUTHENTICATION_METHODS", "MfaAuthenticationMethods", g.ParameterOptions().Parentheses()).
OptionalTextAssignment("MFA_ENROLLMENT", g.ParameterOptions().SingleQuotes()).
ListAssignment("CLIENT_TYPES", "ClientTypes", g.ParameterOptions().Parentheses()).
ListAssignment("SECURITY_INTEGRATIONS", "SecurityIntegrationsOption", g.ParameterOptions().Parentheses()).
OptionalTextAssignment("COMMENT", g.ParameterOptions().SingleQuotes()).
WithValidation(g.AtLeastOneValueSet, "AuthenticationMethods", "MfaAuthenticationMethods", "MfaEnrollment", "ClientTypes", "SecurityIntegrations", "Comment"),
g.KeywordOptions().SQL("SET"),
).
OptionalQueryStructField(
"Unset",
g.NewQueryStruct("AuthenticationPolicyUnset").
OptionalSQL("CLIENT_TYPES").
OptionalSQL("AUTHENTICATION_METHODS").
OptionalSQL("SECURITY_INTEGRATIONS").
OptionalSQL("MFA_AUTHENTICATION_METHODS").
OptionalSQL("MFA_ENROLLMENT").
OptionalSQL("COMMENT").
WithValidation(g.AtLeastOneValueSet, "ClientTypes", "AuthenticationMethods", "Comment", "SecurityIntegrations", "MfaAuthenticationMethods", "MfaEnrollment"),
g.ListOptions().NoParentheses().SQL("UNSET"),
).
Identifier("RenameTo", g.KindOfTPointer[SchemaObjectIdentifier](), g.IdentifierOptions().SQL("RENAME TO")).
WithValidation(g.ValidIdentifier, "name").
WithValidation(g.ExactlyOneValueSet, "Set", "Unset", "RenameTo").
WithValidation(g.ValidIdentifierIfSet, "RenameTo"),
).
DropOperation(
"https://docs.snowflake.com/en/sql-reference/sql/drop-authentication-policy",
g.NewQueryStruct("DropAuthenticationPolicy").
Drop().
SQL("AUTHENTICATION POLICY").
IfExists().
Name().
WithValidation(g.ValidIdentifier, "name"),
).
ShowOperation(
"https://docs.snowflake.com/en/sql-reference/sql/show-authentication-policies",
g.DbStruct("showAuthenticationPolicyDBRow").
Field("created_on", "string").
Field("name", "string").
Field("comment", "string").
Field("database_name", "string").
Field("schema_name", "string").
Field("owner", "string").
Field("owner_role_type", "string").
Field("options", "string"),
g.PlainStruct("AuthenticationPolicy").
Field("CreatedOn", "string").
Field("Name", "string").
Field("Comment", "string").
Field("DatabaseName", "string").
Field("SchemaName", "string").
Field("Owner", "string").
Field("OwnerRoleType", "string").
Field("Options", "string"),
g.NewQueryStruct("ShowAuthenticationPolicies").
Show().
SQL("AUTHENTICATION POLICIES").
OptionalLike().
OptionalIn().
OptionalStartsWith().
OptionalLimit(),
sfc-gh-jcieslak marked this conversation as resolved.
Show resolved Hide resolved
).
ShowByIdOperation().
DescribeOperation(
g.DescriptionMappingKindSlice,
"https://docs.snowflake.com/en/sql-reference/sql/desc-authentication-policy",
g.DbStruct("describeAuthenticationPolicyDBRow").
Field("property", "string").
Field("value", "string"),
sfc-gh-jcieslak marked this conversation as resolved.
Show resolved Hide resolved
g.PlainStruct("AuthenticationPolicyDescription").
Field("Property", "string").
Field("Value", "string"),
g.NewQueryStruct("DescribeAuthenticationPolicy").
Describe().
SQL("AUTHENTICATION POLICY").
Name().
WithValidation(g.ValidIdentifier, "name"),
)
)
Loading
Loading