fix: manage root CA for LDAP IdPs correctly (#9517)

# Which Problems Are Solved

#9292 did not correctly change the projection table to list IdPs for existing ZITADEL setups.

# How the Problems Are Solved

Fixed the projection table by an explicit setup.

# Additional Changes

To prevent user facing error when using the LDAP with a custom root CA as much as possible, the certificate is parsed when passing it to the API.

# Additional Context

- Closes https://github.com/zitadel/zitadel/issues/9514

---------

Co-authored-by: Iraq Jaber <IraqJaber@gmail.com>
(cherry picked from commit 11c9be3b8d)
This commit is contained in:
Iraq
2025-03-18 15:23:12 +00:00
committed by Livio Spring
parent 9c6394c164
commit 9f0da00cd5
11 changed files with 265 additions and 75 deletions

View File

@@ -40,7 +40,7 @@ const (
IDPTemplateGitLabSuffix = "gitlab"
IDPTemplateGitLabSelfHostedSuffix = "gitlab_self_hosted"
IDPTemplateGoogleSuffix = "google"
IDPTemplateLDAPSuffix = "ldap3"
IDPTemplateLDAPSuffix = "ldap2"
IDPTemplateAppleSuffix = "apple"
IDPTemplateSAMLSuffix = "saml"
@@ -141,7 +141,7 @@ const (
LDAPUserObjectClassesCol = "user_object_classes"
LDAPUserFiltersCol = "user_filters"
LDAPTimeoutCol = "timeout"
LDAPRootCACol = "rootCA"
LDAPRootCACol = "root_ca"
LDAPIDAttributeCol = "id_attribute"
LDAPFirstNameAttributeCol = "first_name_attribute"
LDAPLastNameAttributeCol = "last_name_attribute"

View File

@@ -2123,7 +2123,7 @@ func TestIDPTemplateProjection_reducesLDAP(t *testing.T) {
"userObjectClasses": ["object"],
"userFilters": ["filter"],
"timeout": 30000000000,
"rootcA": `+stringToJSONByte("certificate")+`,
"rootCA": `+stringToJSONByte("certificate")+`,
"idAttribute": "id",
"firstNameAttribute": "first",
"lastNameAttribute": "last",
@@ -2172,7 +2172,7 @@ func TestIDPTemplateProjection_reducesLDAP(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.idp_templates6_ldap3 (idp_id, instance_id, servers, start_tls, base_dn, bind_dn, bind_password, user_base, user_object_classes, user_filters, timeout, rootCA, id_attribute, first_name_attribute, last_name_attribute, display_name_attribute, nick_name_attribute, preferred_username_attribute, email_attribute, email_verified, phone_attribute, phone_verified_attribute, preferred_language_attribute, avatar_url_attribute, profile_attribute) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25)",
expectedStmt: "INSERT INTO projections.idp_templates6_ldap2 (idp_id, instance_id, servers, start_tls, base_dn, bind_dn, bind_password, user_base, user_object_classes, user_filters, timeout, root_ca, id_attribute, first_name_attribute, last_name_attribute, display_name_attribute, nick_name_attribute, preferred_username_attribute, email_attribute, email_verified, phone_attribute, phone_verified_attribute, preferred_language_attribute, avatar_url_attribute, profile_attribute) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25)",
expectedArgs: []interface{}{
"idp-id",
"instance-id",
@@ -2228,7 +2228,7 @@ func TestIDPTemplateProjection_reducesLDAP(t *testing.T) {
"userObjectClasses": ["object"],
"userFilters": ["filter"],
"timeout": 30000000000,
"rootcA": `+stringToJSONByte("certificate")+`,
"rootCA": `+stringToJSONByte("certificate")+`,
"idAttribute": "id",
"firstNameAttribute": "first",
"lastNameAttribute": "last",
@@ -2277,7 +2277,7 @@ func TestIDPTemplateProjection_reducesLDAP(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.idp_templates6_ldap3 (idp_id, instance_id, servers, start_tls, base_dn, bind_dn, bind_password, user_base, user_object_classes, user_filters, timeout, rootCA, id_attribute, first_name_attribute, last_name_attribute, display_name_attribute, nick_name_attribute, preferred_username_attribute, email_attribute, email_verified, phone_attribute, phone_verified_attribute, preferred_language_attribute, avatar_url_attribute, profile_attribute) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25)",
expectedStmt: "INSERT INTO projections.idp_templates6_ldap2 (idp_id, instance_id, servers, start_tls, base_dn, bind_dn, bind_password, user_base, user_object_classes, user_filters, timeout, root_ca, id_attribute, first_name_attribute, last_name_attribute, display_name_attribute, nick_name_attribute, preferred_username_attribute, email_attribute, email_verified, phone_attribute, phone_verified_attribute, preferred_language_attribute, avatar_url_attribute, profile_attribute) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25)",
expectedArgs: []interface{}{
"idp-id",
"instance-id",
@@ -2341,7 +2341,7 @@ func TestIDPTemplateProjection_reducesLDAP(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.idp_templates6_ldap3 SET base_dn = $1 WHERE (idp_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.idp_templates6_ldap2 SET base_dn = $1 WHERE (idp_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
"basedn",
"idp-id",
@@ -2375,7 +2375,7 @@ func TestIDPTemplateProjection_reducesLDAP(t *testing.T) {
"userObjectClasses": ["object"],
"userFilters": ["filter"],
"timeout": 30000000000,
"rootcA": `+stringToJSONByte("certificate")+`,
"rootCA": `+stringToJSONByte("certificate")+`,
"idAttribute": "id",
"firstNameAttribute": "first",
"lastNameAttribute": "last",
@@ -2419,7 +2419,7 @@ func TestIDPTemplateProjection_reducesLDAP(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.idp_templates6_ldap3 SET (servers, start_tls, base_dn, bind_dn, bind_password, user_base, user_object_classes, user_filters, timeout, rootCA, id_attribute, first_name_attribute, last_name_attribute, display_name_attribute, nick_name_attribute, preferred_username_attribute, email_attribute, email_verified, phone_attribute, phone_verified_attribute, preferred_language_attribute, avatar_url_attribute, profile_attribute) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23) WHERE (idp_id = $24) AND (instance_id = $25)",
expectedStmt: "UPDATE projections.idp_templates6_ldap2 SET (servers, start_tls, base_dn, bind_dn, bind_password, user_base, user_object_classes, user_filters, timeout, root_ca, id_attribute, first_name_attribute, last_name_attribute, display_name_attribute, nick_name_attribute, preferred_username_attribute, email_attribute, email_verified, phone_attribute, phone_verified_attribute, preferred_language_attribute, avatar_url_attribute, profile_attribute) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23) WHERE (idp_id = $24) AND (instance_id = $25)",
expectedArgs: []interface{}{
database.TextArray[string]{"server"},
false,