Skip to content

Commit

Permalink
Split OAuth validation to two phases (#56)
Browse files Browse the repository at this point in the history
  • Loading branch information
shilgapira authored Jan 9, 2025
1 parent 1825027 commit 5c82e92
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 24 deletions.
2 changes: 1 addition & 1 deletion docs/resources/project.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ description: |-
- `jwt_templates` (Attributes) Defines templates for JSON Web Tokens (JWT) used for authentication. (see [below for nested schema](#nestedatt--jwt_templates))
- `project_settings` (Attributes) General settings for the Descope project. (see [below for nested schema](#nestedatt--project_settings))
- `styles` (Attributes) Custom styles that can be applied to the project's authentication flows. (see [below for nested schema](#nestedatt--styles))
- `tags` (List of String) Descriptive tags for your Descope project. Tags can contain any character but must be no more than 50 characters long.
- `tags` (List of String) Descriptive tags for your Descope project. Each tag must be no more than 50 characters long.

### Read-Only

Expand Down
3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@ require (
github.com/stretchr/testify v1.10.0
)

require github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect

require (
github.com/ProtonMail/go-crypto v1.1.3 // indirect
github.com/agext/levenshtein v1.2.3 // indirect
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
github.com/cloudflare/circl v1.5.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
Expand Down
45 changes: 33 additions & 12 deletions internal/models/authentication/oauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,43 @@ type OAuthModel struct {
func (m *OAuthModel) Values(h *helpers.Handler) map[string]any {
data := map[string]any{}
boolattr.GetNot(m.Disabled, data, "enabled")

providers := map[string]any{}

if v := m.System; v != nil {
ensureSystemProvider(h, v.Apple, "apple")
ensureSystemProvider(h, v.Discord, "discord")
ensureSystemProvider(h, v.Facebook, "facebook")
ensureSystemProvider(h, v.Github, "github")
ensureSystemProvider(h, v.Gitlab, "gitlab")
ensureSystemProvider(h, v.Google, "google")
ensureSystemProvider(h, v.Linkedin, "linkedin")
ensureSystemProvider(h, v.Microsoft, "microsoft")
ensureSystemProvider(h, v.Slack, "slack")

maps.Copy(providers, v.Values(h))
}

for name, provider := range m.Custom {
if _, ok := provider.ClaimMapping["loginId"]; !ok && len(provider.ClaimMapping) > 0 {
h.Error("Invalid Claim Mapping", "Claim mapping set for custom provider %s but 'loginId' was not mapped", name)
}

ensureRequiredCustomProviderField(h, provider.ClientID, "client_id", name)
ensureRequiredCustomProviderField(h, provider.ClientSecret, "client_secret", name)
ensureRequiredCustomProviderField(h, provider.AllowedGrantTypes, "allowed_grant_types", name)
ensureRequiredCustomProviderField(h, provider.AuthorizationEndpoint, "authorization_endpoint", name)
ensureRequiredCustomProviderField(h, provider.TokenEndpoint, "token_endpoint", name)
ensureRequiredCustomProviderField(h, provider.UserInfoEndpoint, "user_info_endpoint", name)

data := provider.Values(h)
data["useSelfAccount"] = true
data["custom"] = true
data["useNonce"] = true
data["name"] = name
providers[name] = data
}

data["providerSettings"] = providers
return data
}
Expand Down Expand Up @@ -78,20 +103,11 @@ func (m *OAuthModel) Validate(h *helpers.Handler) {
validateSystemProvider(h, v.Microsoft, "microsoft")
validateSystemProvider(h, v.Slack, "slack")
}
for name, app := range m.Custom {
for name := range m.Custom {
if slices.Contains(systemProviderNames, name) {
h.Error("Reserved OAuth Provider Name", "The %s name is reserved for system providers and cannot be used for a custom provider", name)
continue
}
ensureRequiredCustomProviderField(h, app.ClientID, "client_id", name)
ensureRequiredCustomProviderField(h, app.ClientSecret, "client_secret", name)
ensureRequiredCustomProviderField(h, app.AllowedGrantTypes, "allowed_grant_types", name)
ensureRequiredCustomProviderField(h, app.AuthorizationEndpoint, "authorization_endpoint", name)
ensureRequiredCustomProviderField(h, app.TokenEndpoint, "token_endpoint", name)
ensureRequiredCustomProviderField(h, app.UserInfoEndpoint, "user_info_endpoint", name)
if _, ok := app.ClaimMapping["loginId"]; !ok && len(app.ClaimMapping) > 0 {
h.Error("Invalid Claim Mapping", "Claim mapping set for custom provider %s but 'loginId' was not mapped", name)
}
}
}

Expand All @@ -112,7 +128,7 @@ func ensureRequiredCustomProviderField(h *helpers.Handler, field any, fieldKey,
}
}

func validateSystemProvider(h *helpers.Handler, m *OAuthProviderModel, name string) {
func ensureSystemProvider(h *helpers.Handler, m *OAuthProviderModel, name string) {
if m == nil {
return
}
Expand All @@ -130,7 +146,12 @@ func validateSystemProvider(h *helpers.Handler, m *OAuthProviderModel, name stri
h.Error("Invalid Attribute Value", "Set a client_id and client_secret for the %s system provider in order to set the provider_token_management attribute", name)
}
}
// custom-only validation
}

func validateSystemProvider(h *helpers.Handler, m *OAuthProviderModel, name string) {
if m == nil {
return
}
ensureNoCustomProviderFields(h, m.Description, "description", name)
ensureNoCustomProviderFields(h, m.Logo, "logo", name)
ensureNoCustomProviderFields(h, m.Issuer, "issuer", name)
Expand Down
5 changes: 0 additions & 5 deletions internal/resources/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,6 @@ func (r *projectResource) ValidateConfig(ctx context.Context, req resource.Valid
return
}

_ = entity.Values(ctx)
if entity.Diagnostics.HasError() {
return
}

tflog.Info(ctx, "Project resource validated")
}

Expand Down
8 changes: 4 additions & 4 deletions tools/terragen/conngen/connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,16 @@ func (c *Connector) HasValidator() bool {
}
// a few sanity checks to make sure we support what's expected
if f.Required {
log.Fatalf("Unexpected required field with dependency " + f.Name)
log.Fatalf("Unexpected required field with dependency %s", f.Name)
}
if f.Dependency.Field == nil {
log.Fatalf("Failed to find matching field for dependency " + f.Dependency.Name + " in connector " + c.ID)
log.Fatalf("Failed to find matching field for dependency %s in connector %s", f.Dependency.Name, c.ID)
}
if f.Dependency.Field.Type != FieldTypeBool {
log.Fatalf("Field " + f.Name + " has a dependency on " + f.Dependency.Field.Name + " whose type is not a boolean (other types are not currently supported)")
log.Fatalf("Field %s has a dependency on %s whose type is not a boolean (other types are not currently supported)", f.Name, f.Dependency.Field.Name)
}
if f.Dependency.Value != true {
log.Fatalf("Field " + f.Name + " has a dependency whose value is not true (other values are not currently supported)")
log.Fatalf("Field %s has a dependency whose value is not true (other values are not currently supported)", f.Name)
}
}
}
Expand Down

0 comments on commit 5c82e92

Please sign in to comment.