mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-14 20:08:02 +00:00
3e3d46ac0d
# Which Problems Are Solved GetIDPByID as endpoint in the API v2 so that it can be available for the new login. # How the Problems Are Solved Create GetIDPByID endpoint with IDP v2 API, throught the GetProviderByID implementation from admin and management API. # Additional Changes - Remove the OwnerType attribute from the response, as the information is available through the resourceOwner. - correct refs to messages in proto which are used for doc generation - renaming of elements for API v3 # Additional Context Closes #8337 --------- Co-authored-by: Livio Spring <livio.a@gmail.com>
370 lines
12 KiB
Go
370 lines
12 KiB
Go
package idp
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/crewjam/saml"
|
|
"github.com/muhlemmer/gu"
|
|
"google.golang.org/protobuf/types/known/durationpb"
|
|
|
|
"github.com/zitadel/zitadel/internal/api/grpc/object/v2"
|
|
"github.com/zitadel/zitadel/internal/domain"
|
|
"github.com/zitadel/zitadel/internal/idp/providers/azuread"
|
|
"github.com/zitadel/zitadel/internal/query"
|
|
idp_rp "github.com/zitadel/zitadel/internal/repository/idp"
|
|
idp_pb "github.com/zitadel/zitadel/pkg/grpc/idp/v2"
|
|
)
|
|
|
|
func (s *Server) GetIDPByID(ctx context.Context, req *idp_pb.GetIDPByIDRequest) (*idp_pb.GetIDPByIDResponse, error) {
|
|
idp, err := s.query.IDPTemplateByID(ctx, true, req.Id, false, s.checkPermission)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &idp_pb.GetIDPByIDResponse{Idp: idpToPb(idp)}, nil
|
|
}
|
|
|
|
func idpToPb(idp *query.IDPTemplate) *idp_pb.IDP {
|
|
return &idp_pb.IDP{
|
|
Id: idp.ID,
|
|
Details: object.DomainToDetailsPb(
|
|
&domain.ObjectDetails{
|
|
Sequence: idp.Sequence,
|
|
EventDate: idp.ChangeDate,
|
|
ResourceOwner: idp.ResourceOwner,
|
|
}),
|
|
State: idpStateToPb(idp.State),
|
|
Name: idp.Name,
|
|
Type: idpTypeToPb(idp.Type),
|
|
Config: configToPb(idp),
|
|
}
|
|
}
|
|
|
|
func idpStateToPb(state domain.IDPState) idp_pb.IDPState {
|
|
switch state {
|
|
case domain.IDPStateActive:
|
|
return idp_pb.IDPState_IDP_STATE_ACTIVE
|
|
case domain.IDPStateInactive:
|
|
return idp_pb.IDPState_IDP_STATE_INACTIVE
|
|
case domain.IDPStateUnspecified:
|
|
return idp_pb.IDPState_IDP_STATE_UNSPECIFIED
|
|
case domain.IDPStateMigrated:
|
|
return idp_pb.IDPState_IDP_STATE_MIGRATED
|
|
case domain.IDPStateRemoved:
|
|
return idp_pb.IDPState_IDP_STATE_REMOVED
|
|
default:
|
|
return idp_pb.IDPState_IDP_STATE_UNSPECIFIED
|
|
}
|
|
}
|
|
|
|
func idpTypeToPb(idpType domain.IDPType) idp_pb.IDPType {
|
|
switch idpType {
|
|
case domain.IDPTypeOIDC:
|
|
return idp_pb.IDPType_IDP_TYPE_OIDC
|
|
case domain.IDPTypeJWT:
|
|
return idp_pb.IDPType_IDP_TYPE_JWT
|
|
case domain.IDPTypeOAuth:
|
|
return idp_pb.IDPType_IDP_TYPE_OAUTH
|
|
case domain.IDPTypeLDAP:
|
|
return idp_pb.IDPType_IDP_TYPE_LDAP
|
|
case domain.IDPTypeAzureAD:
|
|
return idp_pb.IDPType_IDP_TYPE_AZURE_AD
|
|
case domain.IDPTypeGitHub:
|
|
return idp_pb.IDPType_IDP_TYPE_GITHUB
|
|
case domain.IDPTypeGitHubEnterprise:
|
|
return idp_pb.IDPType_IDP_TYPE_GITHUB_ES
|
|
case domain.IDPTypeGitLab:
|
|
return idp_pb.IDPType_IDP_TYPE_GITLAB
|
|
case domain.IDPTypeGitLabSelfHosted:
|
|
return idp_pb.IDPType_IDP_TYPE_GITLAB_SELF_HOSTED
|
|
case domain.IDPTypeGoogle:
|
|
return idp_pb.IDPType_IDP_TYPE_GOOGLE
|
|
case domain.IDPTypeApple:
|
|
return idp_pb.IDPType_IDP_TYPE_APPLE
|
|
case domain.IDPTypeSAML:
|
|
return idp_pb.IDPType_IDP_TYPE_SAML
|
|
case domain.IDPTypeUnspecified:
|
|
return idp_pb.IDPType_IDP_TYPE_UNSPECIFIED
|
|
default:
|
|
return idp_pb.IDPType_IDP_TYPE_UNSPECIFIED
|
|
}
|
|
}
|
|
|
|
func configToPb(config *query.IDPTemplate) *idp_pb.IDPConfig {
|
|
idpConfig := &idp_pb.IDPConfig{
|
|
Options: &idp_pb.Options{
|
|
IsLinkingAllowed: config.IsLinkingAllowed,
|
|
IsCreationAllowed: config.IsCreationAllowed,
|
|
IsAutoCreation: config.IsAutoCreation,
|
|
IsAutoUpdate: config.IsAutoUpdate,
|
|
AutoLinking: autoLinkingOptionToPb(config.AutoLinking),
|
|
},
|
|
}
|
|
if config.OAuthIDPTemplate != nil {
|
|
oauthConfigToPb(idpConfig, config.OAuthIDPTemplate)
|
|
return idpConfig
|
|
}
|
|
if config.OIDCIDPTemplate != nil {
|
|
oidcConfigToPb(idpConfig, config.OIDCIDPTemplate)
|
|
return idpConfig
|
|
}
|
|
if config.JWTIDPTemplate != nil {
|
|
jwtConfigToPb(idpConfig, config.JWTIDPTemplate)
|
|
return idpConfig
|
|
}
|
|
if config.AzureADIDPTemplate != nil {
|
|
azureConfigToPb(idpConfig, config.AzureADIDPTemplate)
|
|
return idpConfig
|
|
}
|
|
if config.GitHubIDPTemplate != nil {
|
|
githubConfigToPb(idpConfig, config.GitHubIDPTemplate)
|
|
return idpConfig
|
|
}
|
|
if config.GitHubEnterpriseIDPTemplate != nil {
|
|
githubEnterpriseConfigToPb(idpConfig, config.GitHubEnterpriseIDPTemplate)
|
|
return idpConfig
|
|
}
|
|
if config.GitLabIDPTemplate != nil {
|
|
gitlabConfigToPb(idpConfig, config.GitLabIDPTemplate)
|
|
return idpConfig
|
|
}
|
|
if config.GitLabSelfHostedIDPTemplate != nil {
|
|
gitlabSelfHostedConfigToPb(idpConfig, config.GitLabSelfHostedIDPTemplate)
|
|
return idpConfig
|
|
}
|
|
if config.GoogleIDPTemplate != nil {
|
|
googleConfigToPb(idpConfig, config.GoogleIDPTemplate)
|
|
return idpConfig
|
|
}
|
|
if config.LDAPIDPTemplate != nil {
|
|
ldapConfigToPb(idpConfig, config.LDAPIDPTemplate)
|
|
return idpConfig
|
|
}
|
|
if config.AppleIDPTemplate != nil {
|
|
appleConfigToPb(idpConfig, config.AppleIDPTemplate)
|
|
return idpConfig
|
|
}
|
|
if config.SAMLIDPTemplate != nil {
|
|
samlConfigToPb(idpConfig, config.SAMLIDPTemplate)
|
|
return idpConfig
|
|
}
|
|
return idpConfig
|
|
}
|
|
|
|
func autoLinkingOptionToPb(linking domain.AutoLinkingOption) idp_pb.AutoLinkingOption {
|
|
switch linking {
|
|
case domain.AutoLinkingOptionUnspecified:
|
|
return idp_pb.AutoLinkingOption_AUTO_LINKING_OPTION_UNSPECIFIED
|
|
case domain.AutoLinkingOptionUsername:
|
|
return idp_pb.AutoLinkingOption_AUTO_LINKING_OPTION_USERNAME
|
|
case domain.AutoLinkingOptionEmail:
|
|
return idp_pb.AutoLinkingOption_AUTO_LINKING_OPTION_EMAIL
|
|
default:
|
|
return idp_pb.AutoLinkingOption_AUTO_LINKING_OPTION_UNSPECIFIED
|
|
}
|
|
}
|
|
|
|
func oauthConfigToPb(idpConfig *idp_pb.IDPConfig, template *query.OAuthIDPTemplate) {
|
|
idpConfig.Config = &idp_pb.IDPConfig_Oauth{
|
|
Oauth: &idp_pb.OAuthConfig{
|
|
ClientId: template.ClientID,
|
|
AuthorizationEndpoint: template.AuthorizationEndpoint,
|
|
TokenEndpoint: template.TokenEndpoint,
|
|
UserEndpoint: template.UserEndpoint,
|
|
Scopes: template.Scopes,
|
|
IdAttribute: template.IDAttribute,
|
|
},
|
|
}
|
|
}
|
|
|
|
func oidcConfigToPb(idpConfig *idp_pb.IDPConfig, template *query.OIDCIDPTemplate) {
|
|
idpConfig.Config = &idp_pb.IDPConfig_Oidc{
|
|
Oidc: &idp_pb.GenericOIDCConfig{
|
|
ClientId: template.ClientID,
|
|
Issuer: template.Issuer,
|
|
Scopes: template.Scopes,
|
|
IsIdTokenMapping: template.IsIDTokenMapping,
|
|
},
|
|
}
|
|
}
|
|
|
|
func jwtConfigToPb(idpConfig *idp_pb.IDPConfig, template *query.JWTIDPTemplate) {
|
|
idpConfig.Config = &idp_pb.IDPConfig_Jwt{
|
|
Jwt: &idp_pb.JWTConfig{
|
|
JwtEndpoint: template.Endpoint,
|
|
Issuer: template.Issuer,
|
|
KeysEndpoint: template.KeysEndpoint,
|
|
HeaderName: template.HeaderName,
|
|
},
|
|
}
|
|
}
|
|
|
|
func azureConfigToPb(idpConfig *idp_pb.IDPConfig, template *query.AzureADIDPTemplate) {
|
|
idpConfig.Config = &idp_pb.IDPConfig_AzureAd{
|
|
AzureAd: &idp_pb.AzureADConfig{
|
|
ClientId: template.ClientID,
|
|
Tenant: azureTenantToPb(template.Tenant),
|
|
EmailVerified: template.IsEmailVerified,
|
|
Scopes: template.Scopes,
|
|
},
|
|
}
|
|
}
|
|
|
|
func azureTenantToPb(tenant string) *idp_pb.AzureADTenant {
|
|
var tenantType idp_pb.IsAzureADTenantType
|
|
switch azuread.TenantType(tenant) {
|
|
case azuread.CommonTenant:
|
|
tenantType = &idp_pb.AzureADTenant_TenantType{TenantType: idp_pb.AzureADTenantType_AZURE_AD_TENANT_TYPE_COMMON}
|
|
case azuread.OrganizationsTenant:
|
|
tenantType = &idp_pb.AzureADTenant_TenantType{TenantType: idp_pb.AzureADTenantType_AZURE_AD_TENANT_TYPE_ORGANISATIONS}
|
|
case azuread.ConsumersTenant:
|
|
tenantType = &idp_pb.AzureADTenant_TenantType{TenantType: idp_pb.AzureADTenantType_AZURE_AD_TENANT_TYPE_CONSUMERS}
|
|
default:
|
|
tenantType = &idp_pb.AzureADTenant_TenantId{TenantId: tenant}
|
|
}
|
|
return &idp_pb.AzureADTenant{Type: tenantType}
|
|
}
|
|
|
|
func githubConfigToPb(idpConfig *idp_pb.IDPConfig, template *query.GitHubIDPTemplate) {
|
|
idpConfig.Config = &idp_pb.IDPConfig_Github{
|
|
Github: &idp_pb.GitHubConfig{
|
|
ClientId: template.ClientID,
|
|
Scopes: template.Scopes,
|
|
},
|
|
}
|
|
}
|
|
|
|
func githubEnterpriseConfigToPb(idpConfig *idp_pb.IDPConfig, template *query.GitHubEnterpriseIDPTemplate) {
|
|
idpConfig.Config = &idp_pb.IDPConfig_GithubEs{
|
|
GithubEs: &idp_pb.GitHubEnterpriseServerConfig{
|
|
ClientId: template.ClientID,
|
|
AuthorizationEndpoint: template.AuthorizationEndpoint,
|
|
TokenEndpoint: template.TokenEndpoint,
|
|
UserEndpoint: template.UserEndpoint,
|
|
Scopes: template.Scopes,
|
|
},
|
|
}
|
|
}
|
|
|
|
func gitlabConfigToPb(idpConfig *idp_pb.IDPConfig, template *query.GitLabIDPTemplate) {
|
|
idpConfig.Config = &idp_pb.IDPConfig_Gitlab{
|
|
Gitlab: &idp_pb.GitLabConfig{
|
|
ClientId: template.ClientID,
|
|
Scopes: template.Scopes,
|
|
},
|
|
}
|
|
}
|
|
|
|
func gitlabSelfHostedConfigToPb(idpConfig *idp_pb.IDPConfig, template *query.GitLabSelfHostedIDPTemplate) {
|
|
idpConfig.Config = &idp_pb.IDPConfig_GitlabSelfHosted{
|
|
GitlabSelfHosted: &idp_pb.GitLabSelfHostedConfig{
|
|
ClientId: template.ClientID,
|
|
Issuer: template.Issuer,
|
|
Scopes: template.Scopes,
|
|
},
|
|
}
|
|
}
|
|
|
|
func googleConfigToPb(idpConfig *idp_pb.IDPConfig, template *query.GoogleIDPTemplate) {
|
|
idpConfig.Config = &idp_pb.IDPConfig_Google{
|
|
Google: &idp_pb.GoogleConfig{
|
|
ClientId: template.ClientID,
|
|
Scopes: template.Scopes,
|
|
},
|
|
}
|
|
}
|
|
|
|
func ldapConfigToPb(idpConfig *idp_pb.IDPConfig, template *query.LDAPIDPTemplate) {
|
|
var timeout *durationpb.Duration
|
|
if template.Timeout != 0 {
|
|
timeout = durationpb.New(template.Timeout)
|
|
}
|
|
idpConfig.Config = &idp_pb.IDPConfig_Ldap{
|
|
Ldap: &idp_pb.LDAPConfig{
|
|
Servers: template.Servers,
|
|
StartTls: template.StartTLS,
|
|
BaseDn: template.BaseDN,
|
|
BindDn: template.BindDN,
|
|
UserBase: template.UserBase,
|
|
UserObjectClasses: template.UserObjectClasses,
|
|
UserFilters: template.UserFilters,
|
|
Timeout: timeout,
|
|
Attributes: ldapAttributesToPb(template.LDAPAttributes),
|
|
},
|
|
}
|
|
}
|
|
|
|
func ldapAttributesToPb(attributes idp_rp.LDAPAttributes) *idp_pb.LDAPAttributes {
|
|
return &idp_pb.LDAPAttributes{
|
|
IdAttribute: attributes.IDAttribute,
|
|
FirstNameAttribute: attributes.FirstNameAttribute,
|
|
LastNameAttribute: attributes.LastNameAttribute,
|
|
DisplayNameAttribute: attributes.DisplayNameAttribute,
|
|
NickNameAttribute: attributes.NickNameAttribute,
|
|
PreferredUsernameAttribute: attributes.PreferredUsernameAttribute,
|
|
EmailAttribute: attributes.EmailAttribute,
|
|
EmailVerifiedAttribute: attributes.EmailVerifiedAttribute,
|
|
PhoneAttribute: attributes.PhoneAttribute,
|
|
PhoneVerifiedAttribute: attributes.PhoneVerifiedAttribute,
|
|
PreferredLanguageAttribute: attributes.PreferredLanguageAttribute,
|
|
AvatarUrlAttribute: attributes.AvatarURLAttribute,
|
|
ProfileAttribute: attributes.ProfileAttribute,
|
|
}
|
|
}
|
|
|
|
func appleConfigToPb(idpConfig *idp_pb.IDPConfig, template *query.AppleIDPTemplate) {
|
|
idpConfig.Config = &idp_pb.IDPConfig_Apple{
|
|
Apple: &idp_pb.AppleConfig{
|
|
ClientId: template.ClientID,
|
|
TeamId: template.TeamID,
|
|
KeyId: template.KeyID,
|
|
Scopes: template.Scopes,
|
|
},
|
|
}
|
|
}
|
|
|
|
func samlConfigToPb(idpConfig *idp_pb.IDPConfig, template *query.SAMLIDPTemplate) {
|
|
nameIDFormat := idp_pb.SAMLNameIDFormat_SAML_NAME_ID_FORMAT_PERSISTENT
|
|
if template.NameIDFormat.Valid {
|
|
nameIDFormat = nameIDToPb(template.NameIDFormat.V)
|
|
}
|
|
idpConfig.Config = &idp_pb.IDPConfig_Saml{
|
|
Saml: &idp_pb.SAMLConfig{
|
|
MetadataXml: template.Metadata,
|
|
Binding: bindingToPb(template.Binding),
|
|
WithSignedRequest: template.WithSignedRequest,
|
|
NameIdFormat: nameIDFormat,
|
|
TransientMappingAttributeName: gu.Ptr(template.TransientMappingAttributeName),
|
|
},
|
|
}
|
|
}
|
|
|
|
func bindingToPb(binding string) idp_pb.SAMLBinding {
|
|
switch binding {
|
|
case "":
|
|
return idp_pb.SAMLBinding_SAML_BINDING_UNSPECIFIED
|
|
case saml.HTTPPostBinding:
|
|
return idp_pb.SAMLBinding_SAML_BINDING_POST
|
|
case saml.HTTPRedirectBinding:
|
|
return idp_pb.SAMLBinding_SAML_BINDING_REDIRECT
|
|
case saml.HTTPArtifactBinding:
|
|
return idp_pb.SAMLBinding_SAML_BINDING_ARTIFACT
|
|
default:
|
|
return idp_pb.SAMLBinding_SAML_BINDING_UNSPECIFIED
|
|
}
|
|
}
|
|
|
|
func nameIDToPb(format domain.SAMLNameIDFormat) idp_pb.SAMLNameIDFormat {
|
|
switch format {
|
|
case domain.SAMLNameIDFormatUnspecified:
|
|
return idp_pb.SAMLNameIDFormat_SAML_NAME_ID_FORMAT_UNSPECIFIED
|
|
case domain.SAMLNameIDFormatEmailAddress:
|
|
return idp_pb.SAMLNameIDFormat_SAML_NAME_ID_FORMAT_EMAIL_ADDRESS
|
|
case domain.SAMLNameIDFormatPersistent:
|
|
return idp_pb.SAMLNameIDFormat_SAML_NAME_ID_FORMAT_PERSISTENT
|
|
case domain.SAMLNameIDFormatTransient:
|
|
return idp_pb.SAMLNameIDFormat_SAML_NAME_ID_FORMAT_TRANSIENT
|
|
default:
|
|
return idp_pb.SAMLNameIDFormat_SAML_NAME_ID_FORMAT_UNSPECIFIED
|
|
}
|
|
}
|