Skip to content

Commit

Permalink
feat: Add authentication policies to SDK (#2937)
Browse files Browse the repository at this point in the history
Adds Authentication Policy methods to the SDK.

## Test Plan
* [x] unit tests
* [x] integration tests

## References

*
#2880

---------

Co-authored-by: Jan Cieślak <jan.cieslak@snowflake.com>
  • Loading branch information
cmonty-paypal and sfc-gh-jcieslak authored Sep 10, 2024
1 parent 6dd586b commit 7b49685
Show file tree
Hide file tree
Showing 18 changed files with 1,470 additions and 30 deletions.
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) {
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").
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(),
).
ShowByIdOperation().
DescribeOperation(
g.DescriptionMappingKindSlice,
"https://docs.snowflake.com/en/sql-reference/sql/desc-authentication-policy",
g.DbStruct("describeAuthenticationPolicyDBRow").
Field("property", "string").
Field("value", "string"),
g.PlainStruct("AuthenticationPolicyDescription").
Field("Property", "string").
Field("Value", "string"),
g.NewQueryStruct("DescribeAuthenticationPolicy").
Describe().
SQL("AUTHENTICATION POLICY").
Name().
WithValidation(g.ValidIdentifier, "name"),
)
)
Loading

0 comments on commit 7b49685

Please sign in to comment.