Remove default role configuration

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
Bryan Frimin
2025-10-29 20:03:06 +01:00
parent eb49e27724
commit 8bf82331e8
17 changed files with 27 additions and 221 deletions

View File

@@ -38,7 +38,6 @@ type (
AttributeFirstname string
AttributeLastname string
AttributeRole string
DefaultRole string
AutoSignupEnabled bool
}
@@ -54,7 +53,6 @@ type (
AttributeFirstname *string
AttributeLastname *string
AttributeRole *string
DefaultRole *string
AutoSignupEnabled *bool
}
)
@@ -64,18 +62,8 @@ func (s TenantAuthService) CreateSAMLConfiguration(
req CreateSAMLConfigurationRequest,
) (*coredata.SAMLConfiguration, error) {
// Validate only the IdP configuration (user-provided data)
validationErrors := ValidateIdPConfiguration(
req.IdPEntityID,
req.IdPSsoURL,
req.IdPCertificate,
)
if len(validationErrors) > 0 {
var errMsgs []string
for _, err := range validationErrors {
errMsgs = append(errMsgs, err.Error())
}
return nil, fmt.Errorf("SAML configuration validation failed: %s", strings.Join(errMsgs, "; "))
if err := ValidateIdPConfiguration(req.IdPEntityID, req.IdPSsoURL, req.IdPCertificate); err != nil {
return nil, fmt.Errorf("SAML configuration validation failed: %w", err)
}
var config *coredata.SAMLConfiguration
@@ -105,7 +93,6 @@ func (s TenantAuthService) CreateSAMLConfiguration(
AttributeFirstname: req.AttributeFirstname,
AttributeLastname: req.AttributeLastname,
AttributeRole: req.AttributeRole,
DefaultRole: req.DefaultRole,
AutoSignupEnabled: req.AutoSignupEnabled,
CreatedAt: now,
UpdatedAt: now,
@@ -169,9 +156,6 @@ func (s TenantAuthService) UpdateSAMLConfiguration(
if req.AttributeRole != nil {
cfg.AttributeRole = *req.AttributeRole
}
if req.DefaultRole != nil {
cfg.DefaultRole = *req.DefaultRole
}
if req.AutoSignupEnabled != nil {
cfg.AutoSignupEnabled = *req.AutoSignupEnabled
}

View File

@@ -74,16 +74,13 @@ func ExtractEmailDomain(email string) (string, error) {
return domain, nil
}
func MapSAMLRoleToSystemRole(samlRole string, defaultRole string) (string, error) {
func MapSAMLRoleToSystemRole(samlRole string) string {
if samlRole != "" && isValidRole(samlRole) {
return samlRole, nil
return samlRole
}
if !isValidRole(defaultRole) {
return "", fmt.Errorf("invalid default role %q", defaultRole)
}
return defaultRole, nil
// Default to MEMBER role if SAML role is missing or invalid
return "MEMBER"
}
func isValidRole(role string) bool {

View File

@@ -547,10 +547,7 @@ func (s *SAMLService) HandleSAMLAssertion(
return nil, fmt.Errorf("email domain mismatch: assertion contains email with domain %s but SAML config is for domain %s", actualEmailDomain, config.EmailDomain)
}
systemRole, err := MapSAMLRoleToSystemRole(samlRole, config.DefaultRole)
if err != nil {
return nil, ErrCannotMapRole{Err: err}
}
systemRole := MapSAMLRoleToSystemRole(samlRole)
samlSubject := ""
if assertion.Subject != nil && assertion.Subject.NameID != nil {

View File

@@ -1155,7 +1155,6 @@ func (s Service) InitiateDomainVerification(
AttributeFirstname: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname",
AttributeLastname: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname",
AttributeRole: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role",
DefaultRole: "MEMBER",
AutoSignupEnabled: false,
CreatedAt: now,
UpdatedAt: now,

View File

@@ -0,0 +1,5 @@
-- Remove default_role column from auth_saml_configurations
-- The default role is now hardcoded to 'MEMBER' in the application code
-- when the SAML role attribute is missing or invalid
ALTER TABLE auth_saml_configurations DROP COLUMN default_role;

View File

@@ -39,7 +39,6 @@ type SAMLConfiguration struct {
AttributeFirstname string `db:"attribute_firstname"`
AttributeLastname string `db:"attribute_lastname"`
AttributeRole string `db:"attribute_role"`
DefaultRole string `db:"default_role"`
AutoSignupEnabled bool `db:"auto_signup_enabled"`
DomainVerified bool `db:"domain_verified"`
DomainVerificationToken *string `db:"domain_verification_token"`
@@ -70,7 +69,6 @@ SELECT
attribute_firstname,
attribute_lastname,
attribute_role,
default_role,
auto_signup_enabled,
domain_verified,
domain_verification_token,
@@ -130,7 +128,6 @@ SELECT
attribute_firstname,
attribute_lastname,
attribute_role,
default_role,
auto_signup_enabled,
domain_verified,
domain_verification_token,
@@ -186,7 +183,6 @@ INSERT INTO auth_saml_configurations (
attribute_firstname,
attribute_lastname,
attribute_role,
default_role,
auto_signup_enabled,
domain_verified,
domain_verification_token,
@@ -208,7 +204,6 @@ INSERT INTO auth_saml_configurations (
@attribute_firstname,
@attribute_lastname,
@attribute_role,
@default_role,
@auto_signup_enabled,
@domain_verified,
@domain_verification_token,
@@ -233,7 +228,6 @@ INSERT INTO auth_saml_configurations (
"attribute_firstname": s.AttributeFirstname,
"attribute_lastname": s.AttributeLastname,
"attribute_role": s.AttributeRole,
"default_role": s.DefaultRole,
"auto_signup_enabled": s.AutoSignupEnabled,
"domain_verified": s.DomainVerified,
"domain_verification_token": s.DomainVerificationToken,
@@ -268,7 +262,6 @@ SET
attribute_firstname = @attribute_firstname,
attribute_lastname = @attribute_lastname,
attribute_role = @attribute_role,
default_role = @default_role,
auto_signup_enabled = @auto_signup_enabled,
domain_verified = @domain_verified,
domain_verification_token = @domain_verification_token,
@@ -293,7 +286,6 @@ WHERE
"attribute_firstname": s.AttributeFirstname,
"attribute_lastname": s.AttributeLastname,
"attribute_role": s.AttributeRole,
"default_role": s.DefaultRole,
"auto_signup_enabled": s.AutoSignupEnabled,
"domain_verified": s.DomainVerified,
"domain_verification_token": s.DomainVerificationToken,
@@ -357,7 +349,6 @@ SELECT
attribute_firstname,
attribute_lastname,
attribute_role,
default_role,
auto_signup_enabled,
domain_verified,
domain_verification_token,
@@ -417,7 +408,6 @@ SELECT
attribute_firstname,
attribute_lastname,
attribute_role,
default_role,
auto_signup_enabled,
domain_verified,
domain_verification_token,

View File

@@ -4880,9 +4880,6 @@ type SAMLConfiguration implements Node {
attributeLastname: String!
attributeRole: String!
# Default role for users when role attribute is missing or invalid
defaultRole: String!
# Auto-signup
autoSignupEnabled: Boolean!
@@ -4927,7 +4924,6 @@ input CreateSAMLConfigurationInput {
attributeLastname: String
attributeRole: String
defaultRole: String
autoSignupEnabled: Boolean
}
@@ -4946,7 +4942,6 @@ input UpdateSAMLConfigurationInput {
attributeFirstname: String
attributeLastname: String
attributeRole: String
defaultRole: String
autoSignupEnabled: Boolean
}

View File

@@ -1238,7 +1238,6 @@ type ComplexityRoot struct {
AttributeRole func(childComplexity int) int
AutoSignupEnabled func(childComplexity int) int
CreatedAt func(childComplexity int) int
DefaultRole func(childComplexity int) int
DomainVerificationToken func(childComplexity int) int
DomainVerified func(childComplexity int) int
DomainVerifiedAt func(childComplexity int) int
@@ -7502,13 +7501,6 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
return e.complexity.SAMLConfiguration.CreatedAt(childComplexity), true
case "SAMLConfiguration.defaultRole":
if e.complexity.SAMLConfiguration.DefaultRole == nil {
break
}
return e.complexity.SAMLConfiguration.DefaultRole(childComplexity), true
case "SAMLConfiguration.domainVerificationToken":
if e.complexity.SAMLConfiguration.DomainVerificationToken == nil {
break
@@ -14628,9 +14620,6 @@ type SAMLConfiguration implements Node {
attributeLastname: String!
attributeRole: String!
# Default role for users when role attribute is missing or invalid
defaultRole: String!
# Auto-signup
autoSignupEnabled: Boolean!
@@ -14675,7 +14664,6 @@ input CreateSAMLConfigurationInput {
attributeLastname: String
attributeRole: String
defaultRole: String
autoSignupEnabled: Boolean
}
@@ -14694,7 +14682,6 @@ input UpdateSAMLConfigurationInput {
attributeFirstname: String
attributeLastname: String
attributeRole: String
defaultRole: String
autoSignupEnabled: Boolean
}
@@ -29048,8 +29035,6 @@ func (ec *executionContext) fieldContext_CreateSAMLConfigurationPayload_samlConf
return ec.fieldContext_SAMLConfiguration_attributeLastname(ctx, field)
case "attributeRole":
return ec.fieldContext_SAMLConfiguration_attributeRole(ctx, field)
case "defaultRole":
return ec.fieldContext_SAMLConfiguration_defaultRole(ctx, field)
case "autoSignupEnabled":
return ec.fieldContext_SAMLConfiguration_autoSignupEnabled(ctx, field)
case "testLoginUrl":
@@ -33183,8 +33168,6 @@ func (ec *executionContext) fieldContext_DisableSAMLPayload_samlConfiguration(_
return ec.fieldContext_SAMLConfiguration_attributeLastname(ctx, field)
case "attributeRole":
return ec.fieldContext_SAMLConfiguration_attributeRole(ctx, field)
case "defaultRole":
return ec.fieldContext_SAMLConfiguration_defaultRole(ctx, field)
case "autoSignupEnabled":
return ec.fieldContext_SAMLConfiguration_autoSignupEnabled(ctx, field)
case "testLoginUrl":
@@ -35701,8 +35684,6 @@ func (ec *executionContext) fieldContext_EnableSAMLPayload_samlConfiguration(_ c
return ec.fieldContext_SAMLConfiguration_attributeLastname(ctx, field)
case "attributeRole":
return ec.fieldContext_SAMLConfiguration_attributeRole(ctx, field)
case "defaultRole":
return ec.fieldContext_SAMLConfiguration_defaultRole(ctx, field)
case "autoSignupEnabled":
return ec.fieldContext_SAMLConfiguration_autoSignupEnabled(ctx, field)
case "testLoginUrl":
@@ -37939,8 +37920,6 @@ func (ec *executionContext) fieldContext_InitiateDomainVerificationPayload_samlC
return ec.fieldContext_SAMLConfiguration_attributeLastname(ctx, field)
case "attributeRole":
return ec.fieldContext_SAMLConfiguration_attributeRole(ctx, field)
case "defaultRole":
return ec.fieldContext_SAMLConfiguration_defaultRole(ctx, field)
case "autoSignupEnabled":
return ec.fieldContext_SAMLConfiguration_autoSignupEnabled(ctx, field)
case "testLoginUrl":
@@ -51814,8 +51793,6 @@ func (ec *executionContext) fieldContext_Organization_samlConfigurations(_ conte
return ec.fieldContext_SAMLConfiguration_attributeLastname(ctx, field)
case "attributeRole":
return ec.fieldContext_SAMLConfiguration_attributeRole(ctx, field)
case "defaultRole":
return ec.fieldContext_SAMLConfiguration_defaultRole(ctx, field)
case "autoSignupEnabled":
return ec.fieldContext_SAMLConfiguration_autoSignupEnabled(ctx, field)
case "testLoginUrl":
@@ -57480,50 +57457,6 @@ func (ec *executionContext) fieldContext_SAMLConfiguration_attributeRole(_ conte
return fc, nil
}
func (ec *executionContext) _SAMLConfiguration_defaultRole(ctx context.Context, field graphql.CollectedField, obj *types.SAMLConfiguration) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_SAMLConfiguration_defaultRole(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DefaultRole, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(string)
fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_SAMLConfiguration_defaultRole(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "SAMLConfiguration",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type String does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _SAMLConfiguration_autoSignupEnabled(ctx context.Context, field graphql.CollectedField, obj *types.SAMLConfiguration) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_SAMLConfiguration_autoSignupEnabled(ctx, field)
if err != nil {
@@ -64303,8 +64236,6 @@ func (ec *executionContext) fieldContext_UpdateSAMLConfigurationPayload_samlConf
return ec.fieldContext_SAMLConfiguration_attributeLastname(ctx, field)
case "attributeRole":
return ec.fieldContext_SAMLConfiguration_attributeRole(ctx, field)
case "defaultRole":
return ec.fieldContext_SAMLConfiguration_defaultRole(ctx, field)
case "autoSignupEnabled":
return ec.fieldContext_SAMLConfiguration_autoSignupEnabled(ctx, field)
case "testLoginUrl":
@@ -71053,8 +70984,6 @@ func (ec *executionContext) fieldContext_VerifyDomainPayload_samlConfiguration(_
return ec.fieldContext_SAMLConfiguration_attributeLastname(ctx, field)
case "attributeRole":
return ec.fieldContext_SAMLConfiguration_attributeRole(ctx, field)
case "defaultRole":
return ec.fieldContext_SAMLConfiguration_defaultRole(ctx, field)
case "autoSignupEnabled":
return ec.fieldContext_SAMLConfiguration_autoSignupEnabled(ctx, field)
case "testLoginUrl":
@@ -75174,7 +75103,7 @@ func (ec *executionContext) unmarshalInputCreateSAMLConfigurationInput(ctx conte
asMap[k] = v
}
fieldsInOrder := [...]string{"organizationId", "emailDomain", "enforcementPolicy", "spCertificate", "spPrivateKey", "idpMetadataXml", "idpEntityId", "idpSsoUrl", "idpCertificate", "idpMetadataUrl", "attributeEmail", "attributeFirstname", "attributeLastname", "attributeRole", "defaultRole", "autoSignupEnabled"}
fieldsInOrder := [...]string{"organizationId", "emailDomain", "enforcementPolicy", "spCertificate", "spPrivateKey", "idpMetadataXml", "idpEntityId", "idpSsoUrl", "idpCertificate", "idpMetadataUrl", "attributeEmail", "attributeFirstname", "attributeLastname", "attributeRole", "autoSignupEnabled"}
for _, k := range fieldsInOrder {
v, ok := asMap[k]
if !ok {
@@ -75279,13 +75208,6 @@ func (ec *executionContext) unmarshalInputCreateSAMLConfigurationInput(ctx conte
return it, err
}
it.AttributeRole = data
case "defaultRole":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("defaultRole"))
data, err := ec.unmarshalOString2ᚖstring(ctx, v)
if err != nil {
return it, err
}
it.DefaultRole = data
case "autoSignupEnabled":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("autoSignupEnabled"))
data, err := ec.unmarshalOBoolean2ᚖbool(ctx, v)
@@ -79763,7 +79685,7 @@ func (ec *executionContext) unmarshalInputUpdateSAMLConfigurationInput(ctx conte
asMap[k] = v
}
fieldsInOrder := [...]string{"id", "enabled", "enforcementPolicy", "spCertificate", "spPrivateKey", "idpEntityId", "idpSsoUrl", "idpCertificate", "idpMetadataUrl", "attributeEmail", "attributeFirstname", "attributeLastname", "attributeRole", "defaultRole", "autoSignupEnabled"}
fieldsInOrder := [...]string{"id", "enabled", "enforcementPolicy", "spCertificate", "spPrivateKey", "idpEntityId", "idpSsoUrl", "idpCertificate", "idpMetadataUrl", "attributeEmail", "attributeFirstname", "attributeLastname", "attributeRole", "autoSignupEnabled"}
for _, k := range fieldsInOrder {
v, ok := asMap[k]
if !ok {
@@ -79861,13 +79783,6 @@ func (ec *executionContext) unmarshalInputUpdateSAMLConfigurationInput(ctx conte
return it, err
}
it.AttributeRole = data
case "defaultRole":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("defaultRole"))
data, err := ec.unmarshalOString2ᚖstring(ctx, v)
if err != nil {
return it, err
}
it.DefaultRole = data
case "autoSignupEnabled":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("autoSignupEnabled"))
data, err := ec.unmarshalOBoolean2ᚖbool(ctx, v)
@@ -93233,11 +93148,6 @@ func (ec *executionContext) _SAMLConfiguration(ctx context.Context, sel ast.Sele
if out.Values[i] == graphql.Null {
atomic.AddUint32(&out.Invalids, 1)
}
case "defaultRole":
out.Values[i] = ec._SAMLConfiguration_defaultRole(ctx, field, obj)
if out.Values[i] == graphql.Null {
atomic.AddUint32(&out.Invalids, 1)
}
case "autoSignupEnabled":
out.Values[i] = ec._SAMLConfiguration_autoSignupEnabled(ctx, field, obj)
if out.Values[i] == graphql.Null {

View File

@@ -37,7 +37,6 @@ func NewSAMLConfigurationWithURLs(c *coredata.SAMLConfiguration, spEntityID, spA
AttributeFirstname: c.AttributeFirstname,
AttributeLastname: c.AttributeLastname,
AttributeRole: c.AttributeRole,
DefaultRole: c.DefaultRole,
AutoSignupEnabled: c.AutoSignupEnabled,
CreatedAt: c.CreatedAt,
UpdatedAt: c.UpdatedAt,

View File

@@ -520,7 +520,6 @@ type CreateSAMLConfigurationInput struct {
AttributeFirstname *string `json:"attributeFirstname,omitempty"`
AttributeLastname *string `json:"attributeLastname,omitempty"`
AttributeRole *string `json:"attributeRole,omitempty"`
DefaultRole *string `json:"defaultRole,omitempty"`
AutoSignupEnabled *bool `json:"autoSignupEnabled,omitempty"`
}
@@ -1659,7 +1658,6 @@ type SAMLConfiguration struct {
AttributeFirstname string `json:"attributeFirstname"`
AttributeLastname string `json:"attributeLastname"`
AttributeRole string `json:"attributeRole"`
DefaultRole string `json:"defaultRole"`
AutoSignupEnabled bool `json:"autoSignupEnabled"`
TestLoginURL string `json:"testLoginUrl"`
CreatedAt time.Time `json:"createdAt"`
@@ -2076,7 +2074,6 @@ type UpdateSAMLConfigurationInput struct {
AttributeFirstname *string `json:"attributeFirstname,omitempty"`
AttributeLastname *string `json:"attributeLastname,omitempty"`
AttributeRole *string `json:"attributeRole,omitempty"`
DefaultRole *string `json:"defaultRole,omitempty"`
AutoSignupEnabled *bool `json:"autoSignupEnabled,omitempty"`
}

View File

@@ -3665,11 +3665,6 @@ func (r *mutationResolver) CreateSAMLConfiguration(ctx context.Context, input ty
attributeRole = *input.AttributeRole
}
defaultRole := "MEMBER"
if input.DefaultRole != nil {
defaultRole = *input.DefaultRole
}
autoSignupEnabled := false
if input.AutoSignupEnabled != nil {
autoSignupEnabled = *input.AutoSignupEnabled
@@ -3687,7 +3682,6 @@ func (r *mutationResolver) CreateSAMLConfiguration(ctx context.Context, input ty
AttributeFirstname: attributeFirstname,
AttributeLastname: attributeLastname,
AttributeRole: attributeRole,
DefaultRole: defaultRole,
AutoSignupEnabled: autoSignupEnabled,
})
if err != nil {
@@ -3725,7 +3719,6 @@ func (r *mutationResolver) UpdateSAMLConfiguration(ctx context.Context, input ty
AttributeFirstname: input.AttributeFirstname,
AttributeLastname: input.AttributeLastname,
AttributeRole: input.AttributeRole,
DefaultRole: input.DefaultRole,
AutoSignupEnabled: input.AutoSignupEnabled,
})
if err != nil {