diff --git a/go.mod b/go.mod index 1f84d9b..96b5f60 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.24.0 require ( github.com/Masterminds/sprig/v3 v3.2.3 - github.com/cloudentity/acp-client-go v0.0.0-20260527095100-008ff5049411 + github.com/cloudentity/acp-client-go v0.0.0-20260825070526-1de34904f06f github.com/corvus-ch/zbase32 v1.0.0 github.com/go-json-experiment/json v0.0.0-20240524174822-2d9f40f7385b github.com/go-openapi/strfmt v0.24.0 diff --git a/go.sum b/go.sum index 953952e..a395216 100644 --- a/go.sum +++ b/go.sum @@ -7,8 +7,8 @@ github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/cloudentity/acp-client-go v0.0.0-20260527095100-008ff5049411 h1:oty7npFWtmLAegF5gYXQAAsY2DOZ7WxcCZVVqBSeIwE= -github.com/cloudentity/acp-client-go v0.0.0-20260527095100-008ff5049411/go.mod h1:Hr2WHHXmp+DC4B2oprhgP47yl/dsCAyj9HcG6P3z4m0= +github.com/cloudentity/acp-client-go v0.0.0-20260825070526-1de34904f06f h1:EVEtG2VSF7NojXtgOeWjUQtgwOGvnBlTWmVpD24LEVQ= +github.com/cloudentity/acp-client-go v0.0.0-20260825070526-1de34904f06f/go.mod h1:Hr2WHHXmp+DC4B2oprhgP47yl/dsCAyj9HcG6P3z4m0= github.com/corvus-ch/zbase32 v1.0.0 h1:pDV0qZ1g+HYA8P0PbULsgUg/tZue1FIjsZ7r7h4nZeU= github.com/corvus-ch/zbase32 v1.0.0/go.mod h1:A7KLRecF1tysURyoqiJBvMJFmt/ccqkRdDTLjlQeVsU= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= diff --git a/internal/cac/storage/server_storage_test.go b/internal/cac/storage/server_storage_test.go index 14213e2..997fca8 100644 --- a/internal/cac/storage/server_storage_test.go +++ b/internal/cac/storage/server_storage_test.go @@ -98,6 +98,7 @@ client_secret_expires_at: 0 created_at: 0001-01-01T00:00:00.000Z dpop_bound_access_tokens: false dynamically_registered: false +enforce_application_membership: false grant_types: [] hashed_rotated_secrets: [] id: demo-demo @@ -111,6 +112,7 @@ saml_idp_override_enabled: false saml_metadata_updated_at: 0001-01-01T00:00:00.000Z saml_override_attributes: false scopes: [] +skip_dbfp: false system: false tls_client_certificate_bound_access_tokens: false trusted: false diff --git a/internal/cac/storage/tenant_storage.go b/internal/cac/storage/tenant_storage.go index 4611221..b94d9ca 100644 --- a/internal/cac/storage/tenant_storage.go +++ b/internal/cac/storage/tenant_storage.go @@ -37,6 +37,10 @@ func (t *TenantStorage) Write(ctx context.Context, data models.Rfc7396PatchOpera return err } + if err = writeFile(model.PhoneProviderConfig, filepath.Join(path, "phone_provider_config")); err != nil { + return err + } + if err = writeFiles(model.Pools, filepath.Join(path, "pools"), func(id string, it models.TreePool) string { return it.Name }); err != nil { @@ -109,6 +113,10 @@ func (t *TenantStorage) Read(ctx context.Context, opts ...api.SourceOpt) (models return nil, err } + if err = readFileToMap(tenant, "phone_provider_config", filepath.Join(path, "phone_provider_config")); err != nil { + return nil, err + } + if err = readFilesToMap(tenant, "pools", filepath.Join(path, "pools")); err != nil { return nil, err } diff --git a/internal/cac/storage/tenant_storage_test.go b/internal/cac/storage/tenant_storage_test.go index 6e97ff1..5a50846 100644 --- a/internal/cac/storage/tenant_storage_test.go +++ b/internal/cac/storage/tenant_storage_test.go @@ -176,6 +176,7 @@ public_registration_allowed: false second_factor_threshold: 0 system: false webauthn_settings: + require_user_interaction_before_prompt: false rp_id: example.com rp_origins: - https://www.sit2.example.com`, string(bts)) @@ -220,6 +221,36 @@ settings: } }, }, + { + desc: "phone provider config", + data: &models.TreeTenant{ + Name: "Default", + PhoneProviderConfig: &models.TreePhoneProviderConfig{ + Mode: "custom", + Providers: []*models.PhoneProvider{ + {Twilio: &models.TwilioPhoneProvider{ + Sid: "ACtest", AuthToken: "tok", From: "SecureAuth", + }}, + }, + }, + }, + files: []string{"tenant.yaml", "phone_provider_config.yaml"}, + assert: func(t *testing.T, path string, bts []byte) { + switch path { + case "tenant.yaml": + require.YAMLEq(t, `name: Default`, string(bts)) + case "phone_provider_config.yaml": + require.YAMLEq(t, `active: false +mode: custom +providers: +- twilio: + sid: ACtest + auth_token: tok + from: SecureAuth + disable_delivery_callback_url: false`, string(bts)) + } + }, + }, { desc: "themes and templates", data: &models.TreeTenant{ @@ -338,3 +369,41 @@ updated_at: 0001-01-01T00:00:00.000Z }) } } + +func TestTenantStoragePhoneProviderConfigRoundTrip(t *testing.T) { + require.NoError(t, logging.InitLogging(&logging.Configuration{Level: "debug"})) + + st, err := storage.InitMultiStorage(&storage.MultiStorageConfiguration{ + DirPath: []string{t.TempDir()}, + }, storage.InitTenantStorage) + require.NoError(t, err) + + tree := &models.TreeTenant{ + Name: "Default", + PhoneProviderConfig: &models.TreePhoneProviderConfig{ + Mode: "custom", + Providers: []*models.PhoneProvider{ + {Twilio: &models.TwilioPhoneProvider{Sid: "ACtest", AuthToken: "tok", From: "SecureAuth"}}, + }, + }, + } + + written, err := utils.FromModelToPatch(tree) + require.NoError(t, err) + + require.NoError(t, st.Write(context.Background(), written, api.WithWorkspace("demo"))) + + read, err := st.Read(context.Background(), api.WithWorkspace("demo")) + require.NoError(t, err) + + back, err := utils.FromPatchToModel[models.TreeTenant](read) + require.NoError(t, err) + + require.NotNil(t, back.PhoneProviderConfig, "phone_provider_config did not survive the round trip") + require.Equal(t, "custom", back.PhoneProviderConfig.Mode) + require.Len(t, back.PhoneProviderConfig.Providers, 1) + require.NotNil(t, back.PhoneProviderConfig.Providers[0]) + require.NotNil(t, back.PhoneProviderConfig.Providers[0].Twilio) + require.Equal(t, "ACtest", back.PhoneProviderConfig.Providers[0].Twilio.Sid) + require.Equal(t, "tok", back.PhoneProviderConfig.Providers[0].Twilio.AuthToken) +}