Skip to content

Commit

Permalink
feat(custom_provider): Add new Data Source for Custom Providers (#70)
Browse files Browse the repository at this point in the history
* feat(custom_provider): Add new Data Source for Custom Providers

- Fix the Persistance Issue of Roles on Registration

* fix go versions
  • Loading branch information
EldoranDev authored Mar 13, 2024
1 parent 185b001 commit 40c3cae
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci-go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
go-version: [ '1.19' ]
go-version: [ '1.21' ]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module github.com/real-digital/terraform-provider-cidaas

go 1.21

toolchain go1.22.1
toolchain go1.21.6

require (
github.com/hashicorp/terraform-plugin-docs v0.16.0
Expand Down
2 changes: 2 additions & 0 deletions internal/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ type Client interface {

GetSocialProvider(providerName string, name string) (*SocialProvider, error)

GetCustomProvider(providerName string) (*CustomProvider, error)

GetConsentInstance(name string) (*ConsentInstance, error)

UpdatePasswordPolicy(policy PasswordPolicy) (*PasswordPolicy, error)
Expand Down
36 changes: 36 additions & 0 deletions internal/client/custom_provider.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package client

import (
"encoding/json"
"fmt"
"net/http"
)

type customProvidersResponse struct {
Status int `json:"status"`
Data CustomProvider `json:"data"`
}

func (c *client) GetCustomProvider(providerName string) (*CustomProvider, error) {
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/providers-srv/custom/%s", c.HostUrl, providerName), nil)

if err != nil {
return nil, err
}

body, err := c.doRequest(req)

if err != nil {
return nil, err
}

var response customProvidersResponse
err = json.Unmarshal(body, &response)

if err != nil {
return nil, err
}

return &response.Data, nil

}
6 changes: 6 additions & 0 deletions internal/client/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ type App struct {
AllowedLogoutUrls []string `json:"allowed_logout_urls"`
AllowedScopes []string `json:"allowed_scopes"`
SocialProviders []SocialProvider `json:"social_providers"`
CustomProviders []CustomProvider `json:"custom_providers"`
AdditionalAccessTokenPayload []string `json:"additional_access_token_payload"`
AllowedFields []string `json:"allowed_fields"`
RequiredFields []string `json:"required_fields"`
Expand Down Expand Up @@ -209,3 +210,8 @@ type Template struct {
Subject string `json:"subject"`
Content string `json:"content"`
}

type CustomProvider struct {
DisplayName string `json:"display_name"`
ProviderName string `json:"provider_name"`
}
73 changes: 73 additions & 0 deletions internal/provider/data_source_custom_provider.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package provider

import (
"context"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/types"
)

type customProviderDataSource struct {
provider *cidaasProvider
}

var _ datasource.DataSource = (*customProviderDataSource)(nil)

func NewCustomProviderDataSource() datasource.DataSource {
return &customProviderDataSource{}
}

func (d *customProviderDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Description: "Allows reading custom login providers that are configured",
Attributes: map[string]schema.Attribute{
"display_name": schema.StringAttribute{
Computed: true,
},
"provider_name": schema.StringAttribute{
Required: true,
},
},
}
}

func (d *customProviderDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_custom_provider"
}

func (d *customProviderDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
d.provider, resp.Diagnostics = toProvider(req.ProviderData)
}

func (d customProviderDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var providerName string

var state CustomProvider

diags := req.Config.GetAttribute(ctx, path.Root("provider_name"), &providerName)
resp.Diagnostics.Append(diags...)

if resp.Diagnostics.HasError() {
return
}

customProvider, err := d.provider.client.GetCustomProvider(providerName)

if err != nil {
resp.Diagnostics.AddError("Could not fetch custom provider",
err.Error(),
)
return
}

state.ProviderName = types.StringValue(customProvider.ProviderName)
state.DisplayName = types.StringValue(customProvider.DisplayName)

diags = resp.State.Set(ctx, &state)
resp.Diagnostics.Append(diags...)

if resp.Diagnostics.HasError() {
return
}
}
7 changes: 7 additions & 0 deletions internal/provider/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ type SocialProvider struct {
Name types.String `tfsdk:"name"`
}

type CustomProvider struct {
DisplayName types.String `tfsdk:"display_name"`
ProviderName types.String `tfsdk:"provider_name"`
}

type ConsentInstance struct {
ID types.String `tfsdk:"id"`
ConsentName types.String `tfsdk:"consent_name"`
Expand Down Expand Up @@ -69,6 +74,7 @@ type App struct {
EnablePasswordlessAuth types.Bool `tfsdk:"enable_passwordless_auth"`
EnableDeduplication types.Bool `tfsdk:"enable_deduplication"`
MobileNumberVerificationRequired types.Bool `tfsdk:"mobile_number_verification_required"`
AcceptRolesInTheRegistration types.Bool `tfsdk:"accept_roles_in_the_registration"`
HostedPageGroup types.String `tfsdk:"hosted_page_group"`
PrimaryColor types.String `tfsdk:"primary_color"`
AccentColor types.String `tfsdk:"accent_color"`
Expand Down Expand Up @@ -96,6 +102,7 @@ type App struct {
RedirectUris []string `tfsdk:"redirect_uris"`
AllowedLogoutUrls []string `tfsdk:"allowed_logout_urls"`
SocialProviders []SocialProvider `tfsdk:"social_providers"`
CustomProviders []CustomProvider `tfsdk:"custom_providers"`
AdditionalAccessTokenPayload []string `tfsdk:"additional_access_token_payload"`
Scopes []string `tfsdk:"allowed_scopes"`
AllowedFields []string `tfsdk:"allowed_fields"`
Expand Down
1 change: 1 addition & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ func (p *cidaasProvider) DataSources(context.Context) []func() datasource.DataSo
NewPasswordPolicyDataSource,
NewSocialProviderDataSource,
NewTenantInfoDataSource,
NewCustomProviderDataSource,
}
}

Expand Down
38 changes: 38 additions & 0 deletions internal/provider/resource_app.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,20 @@ func (r *appResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *
Required: true,
},

"custom_providers": schema.ListNestedAttribute{
Required: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"display_name": schema.StringAttribute{
Required: true,
},
"provider_name": schema.StringAttribute{
Required: true,
},
},
},
},

// Login Provider
"social_providers": schema.ListNestedAttribute{
Required: true,
Expand Down Expand Up @@ -301,6 +315,9 @@ func (r *appResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *
},
},
},
"accept_roles_in_the_registration": schema.BoolAttribute{
Required: true,
},
"operations_allowed_groups": schema.ListNestedAttribute{
Optional: true,
NestedObject: schema.NestedAttributeObject{
Expand Down Expand Up @@ -592,6 +609,7 @@ func applyAppToState(ctx context.Context, state *App, app *client.App) diag.Diag
state.PrimaryColor = types.StringValue(app.PrimaryColor)
state.AccentColor = types.StringValue(app.AccentColor)
state.AutoLoginAfterRegister = types.BoolValue(app.AutoLoginAfterRegister)
state.AcceptRolesInTheRegistration = types.BoolValue(app.AcceptRolesInTheRegistration)
state.CompanyName = types.StringValue(app.CompanyName)
state.CompanyAddress = types.StringValue(app.CompanyAddress)
state.CompanyWebsite = types.StringValue(app.CompanyWebsite)
Expand Down Expand Up @@ -650,6 +668,14 @@ func applyAppToState(ctx context.Context, state *App, app *client.App) diag.Diag
})
}

state.CustomProviders = []CustomProvider{}
for _, item := range app.CustomProviders {
state.CustomProviders = append(state.CustomProviders, CustomProvider{
DisplayName: types.StringValue(item.DisplayName),
ProviderName: types.StringValue(item.ProviderName),
})
}

state.AppKey, diags = types.ObjectValue(
map[string]attr.Type{
"id": types.StringType,
Expand Down Expand Up @@ -703,6 +729,7 @@ func planToApp(ctx context.Context, plan *App, state *App) (*client.App, diag.Di
JweEnabled: plan.JweEnabled.ValueBool(),
AlwaysAskMfa: plan.AlwaysAskMfa.ValueBool(),
RegisterWithLoginInformation: plan.RegisterWithLoginInformation.ValueBool(),
AcceptRolesInTheRegistration: plan.AcceptRolesInTheRegistration.ValueBool(),

AllowLoginWith: plan.AllowLoginWith,
RedirectUris: plan.RedirectUris,
Expand All @@ -719,6 +746,7 @@ func planToApp(ctx context.Context, plan *App, state *App) (*client.App, diag.Di
AllowedMfa: plan.AllowedMfa,

SocialProviders: []client.SocialProvider{},
CustomProviders: []client.CustomProvider{},
}

for _, socialProvider := range plan.SocialProviders {
Expand All @@ -731,6 +759,16 @@ func planToApp(ctx context.Context, plan *App, state *App) (*client.App, diag.Di
)
}

for _, customProvider := range plan.CustomProviders {
plannedApp.CustomProviders = append(
plannedApp.CustomProviders,
client.CustomProvider{
DisplayName: customProvider.DisplayName.ValueString(),
ProviderName: customProvider.ProviderName.ValueString(),
},
)
}

diags = tfsdk.ValueAs(ctx, plan.AllowedGroups, &plannedApp.AllowedGroups)
ret.Append(diags...)

Expand Down

0 comments on commit 40c3cae

Please sign in to comment.