mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-13 19:44:21 +00:00
e57a9b57c8
# Which Problems Are Solved ZITADEL currently always uses `urn:oasis:names:tc:SAML:2.0:nameid-format:persistent` in SAML requests, relying on the IdP to respect that flag and always return a peristent nameid in order to be able to map the external user with an existing user (idp link) in ZITADEL. In case the IdP however returns a `urn:oasis:names:tc:SAML:2.0:nameid-format:transient` (transient) nameid, the attribute will differ between each request and it will not be possible to match existing users. # How the Problems Are Solved This PR adds the following two options on SAML IdP: - **nameIDFormat**: allows to set the nameid-format used in the SAML Request - **transientMappingAttributeName**: allows to set an attribute name, which will be used instead of the nameid itself in case the returned nameid-format is transient # Additional Changes To reduce impact on current installations, the `idp_templates6_saml` table is altered with the two added columns by a setup job. New installations will automatically get the table with the two columns directly. All idp unit tests are updated to use `expectEventstore` instead of the deprecated `eventstoreExpect`. # Additional Context Closes #7483 Closes #7743 --------- Co-authored-by: peintnermax <max@caos.ch> Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com>
146 lines
2.7 KiB
Go
146 lines
2.7 KiB
Go
package domain
|
|
|
|
import "github.com/zitadel/logging"
|
|
|
|
type IDPState int32
|
|
|
|
const (
|
|
IDPStateUnspecified IDPState = iota
|
|
IDPStateActive
|
|
IDPStateInactive
|
|
IDPStateRemoved
|
|
IDPStateMigrated
|
|
|
|
idpStateCount
|
|
)
|
|
|
|
func (s IDPState) Valid() bool {
|
|
return s >= 0 && s < idpStateCount
|
|
}
|
|
|
|
func (s IDPState) Exists() bool {
|
|
return s != IDPStateUnspecified && s != IDPStateRemoved && s != IDPStateMigrated
|
|
}
|
|
|
|
type IDPType int32
|
|
|
|
const (
|
|
IDPTypeUnspecified IDPType = iota
|
|
IDPTypeOIDC
|
|
IDPTypeJWT
|
|
IDPTypeOAuth
|
|
IDPTypeLDAP
|
|
IDPTypeAzureAD
|
|
IDPTypeGitHub
|
|
IDPTypeGitHubEnterprise
|
|
IDPTypeGitLab
|
|
IDPTypeGitLabSelfHosted
|
|
IDPTypeGoogle
|
|
IDPTypeApple
|
|
IDPTypeSAML
|
|
)
|
|
|
|
func (t IDPType) GetCSSClass() string {
|
|
switch t {
|
|
case IDPTypeGoogle:
|
|
return "google"
|
|
case IDPTypeGitHub,
|
|
IDPTypeGitHubEnterprise:
|
|
return "github"
|
|
case IDPTypeGitLab,
|
|
IDPTypeGitLabSelfHosted:
|
|
return "gitlab"
|
|
case IDPTypeAzureAD:
|
|
return "azure"
|
|
case IDPTypeApple:
|
|
return "apple"
|
|
case IDPTypeUnspecified,
|
|
IDPTypeOIDC,
|
|
IDPTypeJWT,
|
|
IDPTypeOAuth,
|
|
IDPTypeLDAP,
|
|
IDPTypeSAML:
|
|
fallthrough
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
func IDPName(name string, idpType IDPType) string {
|
|
if name != "" {
|
|
return name
|
|
}
|
|
return idpType.DisplayName()
|
|
}
|
|
|
|
// DisplayName returns the name or a default
|
|
// to be used when always a name must be displayed (e.g. login)
|
|
func (t IDPType) DisplayName() string {
|
|
switch t {
|
|
case IDPTypeGitHub:
|
|
return "GitHub"
|
|
case IDPTypeGitLab:
|
|
return "GitLab"
|
|
case IDPTypeGoogle:
|
|
return "Google"
|
|
case IDPTypeApple:
|
|
return "Apple"
|
|
case IDPTypeUnspecified,
|
|
IDPTypeOIDC,
|
|
IDPTypeJWT,
|
|
IDPTypeOAuth,
|
|
IDPTypeLDAP,
|
|
IDPTypeAzureAD,
|
|
IDPTypeGitHubEnterprise,
|
|
IDPTypeGitLabSelfHosted,
|
|
IDPTypeSAML:
|
|
fallthrough
|
|
default:
|
|
// we should never get here, so log it
|
|
logging.Errorf("name of provider (type %d) is empty", t)
|
|
return ""
|
|
}
|
|
}
|
|
|
|
// IsSignInButton returns if the button should be displayed with a translated
|
|
// "Sign in with {{.DisplayName}}", e.g. "Sign in with Apple"
|
|
func (t IDPType) IsSignInButton() bool {
|
|
return t == IDPTypeApple
|
|
}
|
|
|
|
type IDPIntentState int32
|
|
|
|
const (
|
|
IDPIntentStateUnspecified IDPIntentState = iota
|
|
IDPIntentStateStarted
|
|
IDPIntentStateSucceeded
|
|
IDPIntentStateFailed
|
|
|
|
idpIntentStateCount
|
|
)
|
|
|
|
func (s IDPIntentState) Valid() bool {
|
|
return s >= 0 && s < idpIntentStateCount
|
|
}
|
|
|
|
func (s IDPIntentState) Exists() bool {
|
|
return s != IDPIntentStateUnspecified && s != IDPIntentStateFailed //TODO: ?
|
|
}
|
|
|
|
type AutoLinkingOption uint8
|
|
|
|
const (
|
|
AutoLinkingOptionUnspecified AutoLinkingOption = iota
|
|
AutoLinkingOptionUsername
|
|
AutoLinkingOptionEmail
|
|
)
|
|
|
|
type SAMLNameIDFormat uint8
|
|
|
|
const (
|
|
SAMLNameIDFormatUnspecified SAMLNameIDFormat = iota
|
|
SAMLNameIDFormatEmailAddress
|
|
SAMLNameIDFormatPersistent
|
|
SAMLNameIDFormatTransient
|
|
)
|