Skip to content

Commit

Permalink
chore: Adjust authentication policy (#3068)
Browse files Browse the repository at this point in the history
## Changes
* Addressed comments from
#2937
* Fixed failing tests caused by this change
* Changed and added multiple tests connected to auth policies
* Adjusted a few parts of the SDK implementation (using enums where
possible, added a few missing parts, etc.)

## TODO
* Mention in
#2880
that the SDK for Auth Policies is ready
  • Loading branch information
sfc-gh-jcieslak authored and sfc-gh-fbudzynski committed Sep 19, 2024
1 parent 6078048 commit 0981bfc
Show file tree
Hide file tree
Showing 20 changed files with 749 additions and 414 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package objectassert

import (
"fmt"
"testing"

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

func (a *AuthenticationPolicyAssert) HasCreatedOnNotEmpty() *AuthenticationPolicyAssert {
a.AddAssertion(func(t *testing.T, o *sdk.AuthenticationPolicy) error {
t.Helper()
if o.CreatedOn == "" {
return fmt.Errorf("expected create_on to be not empty")
}
return nil
})
return a
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ var allStructs = []SdkObjectDef{
ObjectType: sdk.ObjectTypeResourceMonitor,
ObjectStruct: sdk.ResourceMonitor{},
},
{
IdType: "sdk.SchemaObjectIdentifier",
ObjectType: sdk.ObjectTypeAuthenticationPolicy,
ObjectStruct: sdk.AuthenticationPolicy{},
},
}

func GetSdkObjectDetails() []genhelpers.SdkObjectDetails {
Expand Down
18 changes: 12 additions & 6 deletions pkg/acceptance/helpers/authentication_policy_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,26 @@ func (c *AuthenticationPolicyClient) client() sdk.AuthenticationPolicies {
return c.context.client.AuthenticationPolicies
}

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

func (c *AuthenticationPolicyClient) CreateAuthenticationPolicyWithOptions(t *testing.T, id sdk.SchemaObjectIdentifier, request *sdk.CreateAuthenticationPolicyRequest) (*sdk.AuthenticationPolicy, func()) {
func (c *AuthenticationPolicyClient) CreateWithOptions(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)
authenticationPolicy, err := c.client().ShowByID(ctx, id)
require.NoError(t, err)

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

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

Expand All @@ -52,3 +52,9 @@ func (c *AuthenticationPolicyClient) DropAuthenticationPolicyFunc(t *testing.T,
require.NoError(t, err)
}
}

func (c *AuthenticationPolicyClient) Show(t *testing.T, id sdk.SchemaObjectIdentifier) (*sdk.AuthenticationPolicy, error) {
t.Helper()
ctx := context.Background()
return c.client().ShowByID(ctx, id)
}
2 changes: 1 addition & 1 deletion pkg/resources/resource_monitor_acceptance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,7 @@ func TestAcc_ResourceMonitor_Issue1500_AlteringWithOnlyTriggers(t *testing.T) {
},
Config: config.FromModel(t, configModelWithoutTriggers),
// For some reason, not returning the correct error (SQL compilation error should be returned in this case; most likely update was processed incorrectly)
ExpectError: regexp.MustCompile(`at least one of AlterResourceMonitorOptions fields [Set Triggers] must be set`),
ExpectError: regexp.MustCompile(`at least one of AlterResourceMonitorOptions fields \[Set Triggers] must be set`),
},
// Upgrade to the latest version
{
Expand Down
18 changes: 3 additions & 15 deletions pkg/resources/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -548,24 +548,12 @@ func UpdateUser(ctx context.Context, d *schema.ResourceData, meta any) diag.Diag
return diag.FromErr(err)
}
}
// unset is split into two because:
// 1. this is how it's written in the docs https://docs.snowflake.com/en/sql-reference/sql/alter-user#syntax
// 2. current implementation of sdk.UserUnset makes distinction between user and session parameters,
// so adding a comma between them is not trivial in the current SQL builder implementation
if (*unset.SessionParameters != sdk.SessionParametersUnset{}) {

if (*unset.SessionParameters != sdk.SessionParametersUnset{}) || (*unset.ObjectParameters != sdk.UserObjectParametersUnset{}) {
err := client.Users.Alter(ctx, id, &sdk.AlterUserOptions{
Unset: &sdk.UserUnset{
SessionParameters: unset.SessionParameters,
},
})
if err != nil {
return diag.FromErr(err)
}
}
if (*unset.ObjectParameters != sdk.UserObjectParametersUnset{}) {
err := client.Users.Alter(ctx, id, &sdk.AlterUserOptions{
Unset: &sdk.UserUnset{
ObjectParameters: unset.ObjectParameters,
ObjectParameters: unset.ObjectParameters,
},
})
if err != nil {
Expand Down
36 changes: 36 additions & 0 deletions pkg/sdk/accounts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,42 @@ func TestAccountCreate(t *testing.T) {
}

func TestAccountAlter(t *testing.T) {
t.Run("validation: exactly one value set in AccountSet - nothing set", func(t *testing.T) {
opts := &AlterAccountOptions{
Set: &AccountSet{},
}
assertOptsInvalidJoinedErrors(t, opts, errExactlyOneOf("AccountSet", "Parameters", "ResourceMonitor", "PasswordPolicy", "SessionPolicy", "AuthenticationPolicy"))
})

t.Run("validation: exactly one value set in AccountSet - multiple set", func(t *testing.T) {
opts := &AlterAccountOptions{
Set: &AccountSet{
PasswordPolicy: randomSchemaObjectIdentifier(),
SessionPolicy: randomSchemaObjectIdentifier(),
AuthenticationPolicy: randomSchemaObjectIdentifier(),
},
}
assertOptsInvalidJoinedErrors(t, opts, errExactlyOneOf("AccountSet", "Parameters", "ResourceMonitor", "PasswordPolicy", "SessionPolicy", "AuthenticationPolicy"))
})

t.Run("validation: exactly one value set in AccountUnset - nothing set", func(t *testing.T) {
opts := &AlterAccountOptions{
Unset: &AccountUnset{},
}
assertOptsInvalidJoinedErrors(t, opts, errExactlyOneOf("AccountUnset", "Parameters", "PasswordPolicy", "SessionPolicy", "AuthenticationPolicy"))
})

t.Run("validation: exactly one value set in AccountUnset - multiple set", func(t *testing.T) {
opts := &AlterAccountOptions{
Unset: &AccountUnset{
PasswordPolicy: Bool(true),
SessionPolicy: Bool(true),
AuthenticationPolicy: Bool(true),
},
}
assertOptsInvalidJoinedErrors(t, opts, errExactlyOneOf("AccountUnset", "Parameters", "PasswordPolicy", "SessionPolicy", "AuthenticationPolicy"))
})

t.Run("with set params", func(t *testing.T) {
opts := &AlterAccountOptions{
Set: &AccountSet{
Expand Down
83 changes: 72 additions & 11 deletions pkg/sdk/authentication_policies_def.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,66 @@ import g "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk/poc/gen

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

type AuthenticationMethodsOption string

const (
AuthenticationMethodsAll AuthenticationMethodsOption = "ALL"
AuthenticationMethodsSaml AuthenticationMethodsOption = "SAML"
AuthenticationMethodsPassword AuthenticationMethodsOption = "PASSWORD"
AuthenticationMethodsOauth AuthenticationMethodsOption = "OAUTH"
AuthenticationMethodsKeyPair AuthenticationMethodsOption = "KEYPAIR"
)

var AllAuthenticationMethods = []AuthenticationMethodsOption{
AuthenticationMethodsAll,
AuthenticationMethodsSaml,
AuthenticationMethodsPassword,
AuthenticationMethodsOauth,
AuthenticationMethodsKeyPair,
}

type MfaAuthenticationMethodsOption string

const (
MfaAuthenticationMethodsAll MfaAuthenticationMethodsOption = "ALL"
MfaAuthenticationMethodsSaml MfaAuthenticationMethodsOption = "SAML"
MfaAuthenticationMethodsPassword MfaAuthenticationMethodsOption = "PASSWORD"
)

var AllMfaAuthenticationMethods = []MfaAuthenticationMethodsOption{
MfaAuthenticationMethodsAll,
MfaAuthenticationMethodsSaml,
MfaAuthenticationMethodsPassword,
}

type MfaEnrollmentOption string

const (
MfaEnrollmentRequired MfaEnrollmentOption = "REQUIRED"
MfaEnrollmentOptional MfaEnrollmentOption = "OPTIONAL"
)

type ClientTypesOption string

const (
ClientTypesAll ClientTypesOption = "ALL"
ClientTypesSnowflakeUi ClientTypesOption = "SNOWFLAKE_UI"
ClientTypesDrivers ClientTypesOption = "DRIVERS"
ClientTypesSnowSql ClientTypesOption = "SNOWSQL"
)

var AllClientTypes = []ClientTypesOption{
ClientTypesAll,
ClientTypesSnowflakeUi,
ClientTypesDrivers,
ClientTypesSnowSql,
}

var (
AuthenticationMethodsOptionDef = g.NewQueryStruct("AuthenticationMethods").Text("Method", g.KeywordOptions().SingleQuotes())
MfaAuthenticationMethodsOptionDef = g.NewQueryStruct("MfaAuthenticationMethods").Text("Method", g.KeywordOptions().SingleQuotes())
ClientTypesOptionDef = g.NewQueryStruct("ClientTypes").Text("ClientType", g.KeywordOptions().SingleQuotes())
SecurityIntegrationsOptionDef = g.NewQueryStruct("SecurityIntegrationsOption").Text("Name", g.KeywordOptions().SingleQuotes())
AuthenticationMethodsOptionDef = g.NewQueryStruct("AuthenticationMethods").PredefinedQueryStructField("Method", g.KindOfT[AuthenticationMethodsOption](), g.KeywordOptions().SingleQuotes().Required())
MfaAuthenticationMethodsOptionDef = g.NewQueryStruct("MfaAuthenticationMethods").PredefinedQueryStructField("Method", g.KindOfT[MfaAuthenticationMethods](), g.KeywordOptions().SingleQuotes().Required())
ClientTypesOptionDef = g.NewQueryStruct("ClientTypes").PredefinedQueryStructField("ClientType", g.KindOfT[ClientTypesOption](), g.KeywordOptions().SingleQuotes().Required())
SecurityIntegrationsOptionDef = g.NewQueryStruct("SecurityIntegrationsOption").Identifier("Name", g.KindOfT[AccountObjectIdentifier](), g.IdentifierOptions().Required())
)

var AuthenticationPoliciesDef = g.NewInterface(
Expand All @@ -22,14 +77,16 @@ var AuthenticationPoliciesDef = g.NewInterface(
Create().
OrReplace().
SQL("AUTHENTICATION POLICY").
IfNotExists().
Name().
ListAssignment("AUTHENTICATION_METHODS", "AuthenticationMethods", g.ParameterOptions().Parentheses()).
ListAssignment("MFA_AUTHENTICATION_METHODS", "MfaAuthenticationMethods", g.ParameterOptions().Parentheses()).
OptionalTextAssignment("MFA_ENROLLMENT", g.ParameterOptions()).
PredefinedQueryStructField("MfaEnrollment", g.KindOfTPointer[MfaEnrollmentOption](), g.ParameterOptions().SQL("MFA_ENROLLMENT")).
ListAssignment("CLIENT_TYPES", "ClientTypes", g.ParameterOptions().Parentheses()).
ListAssignment("SECURITY_INTEGRATIONS", "SecurityIntegrationsOption", g.ParameterOptions().Parentheses()).
OptionalTextAssignment("COMMENT", g.ParameterOptions().SingleQuotes()).
WithValidation(g.ValidIdentifier, "name"),
WithValidation(g.ValidIdentifier, "name").
WithValidation(g.ConflictingFields, "IfNotExists", "OrReplace"),
AuthenticationMethodsOptionDef,
MfaAuthenticationMethodsOptionDef,
ClientTypesOptionDef,
Expand All @@ -47,7 +104,7 @@ var AuthenticationPoliciesDef = g.NewInterface(
g.NewQueryStruct("AuthenticationPolicySet").
ListAssignment("AUTHENTICATION_METHODS", "AuthenticationMethods", g.ParameterOptions().Parentheses()).
ListAssignment("MFA_AUTHENTICATION_METHODS", "MfaAuthenticationMethods", g.ParameterOptions().Parentheses()).
OptionalTextAssignment("MFA_ENROLLMENT", g.ParameterOptions().SingleQuotes()).
PredefinedQueryStructField("MfaEnrollment", g.KindOfTPointer[MfaEnrollmentOption](), g.ParameterOptions().SQL("MFA_ENROLLMENT")).
ListAssignment("CLIENT_TYPES", "ClientTypes", g.ParameterOptions().Parentheses()).
ListAssignment("SECURITY_INTEGRATIONS", "SecurityIntegrationsOption", g.ParameterOptions().Parentheses()).
OptionalTextAssignment("COMMENT", g.ParameterOptions().SingleQuotes()).
Expand Down Expand Up @@ -113,11 +170,15 @@ var AuthenticationPoliciesDef = g.NewInterface(
g.DescriptionMappingKindSlice,
"https://docs.snowflake.com/en/sql-reference/sql/desc-authentication-policy",
g.DbStruct("describeAuthenticationPolicyDBRow").
Field("property", "string").
Field("value", "string"),
Text("property").
Text("value").
Text("default").
Text("description"),
g.PlainStruct("AuthenticationPolicyDescription").
Field("Property", "string").
Field("Value", "string"),
Text("Property").
Text("Value").
Text("Default").
Text("Description"),
g.NewQueryStruct("DescribeAuthenticationPolicy").
Describe().
SQL("AUTHENTICATION POLICY").
Expand Down
Loading

0 comments on commit 0981bfc

Please sign in to comment.