feat: idp v2 api GetIDPByID (#8425)

# 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>
This commit is contained in:
Stefan Benz
2024-08-14 20:18:29 +02:00
committed by GitHub
parent 64a3bb3149
commit 3e3d46ac0d
18 changed files with 1348 additions and 22 deletions

View File

@@ -157,7 +157,7 @@ func (s *Server) GetProviderByID(ctx context.Context, req *admin_pb.GetProviderB
if err != nil {
return nil, err
}
idp, err := s.query.IDPTemplateByID(ctx, true, req.Id, false, instanceIDQuery)
idp, err := s.query.IDPTemplateByID(ctx, true, req.Id, false, nil, instanceIDQuery)
if err != nil {
return nil, err
}

View File

@@ -0,0 +1,369 @@
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
}
}

View File

@@ -0,0 +1,235 @@
//go:build integration
package idp_test
import (
"context"
"fmt"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/types/known/timestamppb"
"github.com/zitadel/zitadel/internal/integration"
"github.com/zitadel/zitadel/pkg/grpc/idp/v2"
"github.com/zitadel/zitadel/pkg/grpc/object/v2"
)
type idpAttr struct {
ID string
Name string
Details *object.Details
}
func TestServer_GetIDPByID(t *testing.T) {
type args struct {
ctx context.Context
req *idp.GetIDPByIDRequest
dep func(ctx context.Context, request *idp.GetIDPByIDRequest) *idpAttr
}
tests := []struct {
name string
args args
want *idp.GetIDPByIDResponse
wantErr bool
}{
{
name: "idp by ID, no id provided",
args: args{
IamCTX,
&idp.GetIDPByIDRequest{
Id: "",
},
func(ctx context.Context, request *idp.GetIDPByIDRequest) *idpAttr {
return nil
},
},
wantErr: true,
},
{
name: "idp by ID, not found",
args: args{
IamCTX,
&idp.GetIDPByIDRequest{
Id: "unknown",
},
func(ctx context.Context, request *idp.GetIDPByIDRequest) *idpAttr {
return nil
},
},
wantErr: true,
},
{
name: "idp by ID, instance, ok",
args: args{
IamCTX,
&idp.GetIDPByIDRequest{},
func(ctx context.Context, request *idp.GetIDPByIDRequest) *idpAttr {
name := fmt.Sprintf("GetIDPByID%d", time.Now().UnixNano())
resp := Tester.AddGenericOAuthIDP(ctx, name)
request.Id = resp.Id
return &idpAttr{
resp.GetId(),
name,
&object.Details{
Sequence: resp.Details.Sequence,
ChangeDate: resp.Details.ChangeDate,
ResourceOwner: resp.Details.ResourceOwner,
}}
},
},
want: &idp.GetIDPByIDResponse{
Idp: &idp.IDP{
Details: &object.Details{
ChangeDate: timestamppb.Now(),
},
State: idp.IDPState_IDP_STATE_ACTIVE,
Type: idp.IDPType_IDP_TYPE_OAUTH,
Config: &idp.IDPConfig{
Config: &idp.IDPConfig_Oauth{
Oauth: &idp.OAuthConfig{
ClientId: "clientID",
AuthorizationEndpoint: "https://example.com/oauth/v2/authorize",
TokenEndpoint: "https://example.com/oauth/v2/token",
UserEndpoint: "https://api.example.com/user",
Scopes: []string{"openid", "profile", "email"},
IdAttribute: "id",
},
},
Options: &idp.Options{
IsLinkingAllowed: true,
IsCreationAllowed: true,
IsAutoCreation: true,
IsAutoUpdate: true,
AutoLinking: idp.AutoLinkingOption_AUTO_LINKING_OPTION_USERNAME,
},
},
},
},
},
{
name: "idp by ID, instance, no permission",
args: args{
UserCTX,
&idp.GetIDPByIDRequest{},
func(ctx context.Context, request *idp.GetIDPByIDRequest) *idpAttr {
name := fmt.Sprintf("GetIDPByID%d", time.Now().UnixNano())
resp := Tester.AddGenericOAuthIDP(IamCTX, name)
request.Id = resp.Id
return &idpAttr{
resp.GetId(),
name,
&object.Details{
Sequence: resp.Details.Sequence,
ChangeDate: resp.Details.ChangeDate,
ResourceOwner: resp.Details.ResourceOwner,
}}
},
},
wantErr: true,
},
{
name: "idp by ID, org, ok",
args: args{
CTX,
&idp.GetIDPByIDRequest{},
func(ctx context.Context, request *idp.GetIDPByIDRequest) *idpAttr {
name := fmt.Sprintf("GetIDPByID%d", time.Now().UnixNano())
resp := Tester.AddOrgGenericOAuthIDP(ctx, name)
request.Id = resp.Id
return &idpAttr{
resp.GetId(),
name,
&object.Details{
Sequence: resp.Details.Sequence,
ChangeDate: resp.Details.ChangeDate,
ResourceOwner: resp.Details.ResourceOwner,
}}
},
},
want: &idp.GetIDPByIDResponse{
Idp: &idp.IDP{
Details: &object.Details{
ChangeDate: timestamppb.Now(),
},
State: idp.IDPState_IDP_STATE_ACTIVE,
Type: idp.IDPType_IDP_TYPE_OAUTH,
Config: &idp.IDPConfig{
Config: &idp.IDPConfig_Oauth{
Oauth: &idp.OAuthConfig{
ClientId: "clientID",
AuthorizationEndpoint: "https://example.com/oauth/v2/authorize",
TokenEndpoint: "https://example.com/oauth/v2/token",
UserEndpoint: "https://api.example.com/user",
Scopes: []string{"openid", "profile", "email"},
IdAttribute: "id",
},
},
Options: &idp.Options{
IsLinkingAllowed: true,
IsCreationAllowed: true,
IsAutoCreation: true,
IsAutoUpdate: true,
AutoLinking: idp.AutoLinkingOption_AUTO_LINKING_OPTION_USERNAME,
},
},
},
},
},
{
name: "idp by ID, org, no permission",
args: args{
UserCTX,
&idp.GetIDPByIDRequest{},
func(ctx context.Context, request *idp.GetIDPByIDRequest) *idpAttr {
name := fmt.Sprintf("GetIDPByID%d", time.Now().UnixNano())
resp := Tester.AddOrgGenericOAuthIDP(CTX, name)
request.Id = resp.Id
return &idpAttr{
resp.GetId(),
name,
&object.Details{
Sequence: resp.Details.Sequence,
ChangeDate: resp.Details.ChangeDate,
ResourceOwner: resp.Details.ResourceOwner,
}}
},
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
idpAttr := tt.args.dep(tt.args.ctx, tt.args.req)
retryDuration := time.Minute
if ctxDeadline, ok := CTX.Deadline(); ok {
retryDuration = time.Until(ctxDeadline)
}
require.EventuallyWithT(t, func(ttt *assert.CollectT) {
got, getErr := Client.GetIDPByID(tt.args.ctx, tt.args.req)
assertErr := assert.NoError
if tt.wantErr {
assertErr = assert.Error
}
assertErr(ttt, getErr)
if getErr != nil {
return
}
// set provided info from creation
tt.want.Idp.Details = idpAttr.Details
tt.want.Idp.Name = idpAttr.Name
tt.want.Idp.Id = idpAttr.ID
// first check for details, mgmt and admin api don't fill the details correctly
integration.AssertDetails(t, tt.want.Idp, got.Idp)
// then set details
tt.want.Idp.Details = got.Idp.Details
// to check the rest of the content
assert.Equal(ttt, tt.want.Idp, got.Idp)
}, retryDuration, time.Second)
})
}
}

View File

@@ -0,0 +1,56 @@
package idp
import (
"google.golang.org/grpc"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/api/grpc/server"
"github.com/zitadel/zitadel/internal/command"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/query"
"github.com/zitadel/zitadel/pkg/grpc/idp/v2"
)
var _ idp.IdentityProviderServiceServer = (*Server)(nil)
type Server struct {
idp.UnimplementedIdentityProviderServiceServer
command *command.Commands
query *query.Queries
checkPermission domain.PermissionCheck
}
type Config struct{}
func CreateServer(
command *command.Commands,
query *query.Queries,
checkPermission domain.PermissionCheck,
) *Server {
return &Server{
command: command,
query: query,
checkPermission: checkPermission,
}
}
func (s *Server) RegisterServer(grpcServer *grpc.Server) {
idp.RegisterIdentityProviderServiceServer(grpcServer, s)
}
func (s *Server) AppName() string {
return idp.IdentityProviderService_ServiceDesc.ServiceName
}
func (s *Server) MethodPrefix() string {
return idp.IdentityProviderService_ServiceDesc.ServiceName
}
func (s *Server) AuthMethods() authz.MethodMapping {
return idp.IdentityProviderService_AuthMethods
}
func (s *Server) RegisterGateway() server.RegisterGatewayFunc {
return idp.RegisterIdentityProviderServiceHandler
}

View File

@@ -0,0 +1,40 @@
//go:build integration
package idp_test
import (
"context"
"os"
"testing"
"time"
"github.com/zitadel/zitadel/internal/integration"
idp_pb "github.com/zitadel/zitadel/pkg/grpc/idp/v2"
)
var (
CTX context.Context
IamCTX context.Context
UserCTX context.Context
SystemCTX context.Context
ErrCTX context.Context
Tester *integration.Tester
Client idp_pb.IdentityProviderServiceClient
)
func TestMain(m *testing.M) {
os.Exit(func() int {
ctx, errCtx, cancel := integration.Contexts(time.Hour)
defer cancel()
Tester = integration.NewTester(ctx)
defer Tester.Done()
UserCTX = Tester.WithAuthorization(ctx, integration.Login)
IamCTX = Tester.WithAuthorization(ctx, integration.IAMOwner)
SystemCTX = Tester.WithAuthorization(ctx, integration.SystemUser)
CTX, ErrCTX = Tester.WithAuthorization(ctx, integration.OrgOwner), errCtx
Client = Tester.Client.IDPv2
return m.Run()
}())
}

View File

@@ -149,7 +149,7 @@ func (s *Server) GetProviderByID(ctx context.Context, req *mgmt_pb.GetProviderBy
if err != nil {
return nil, err
}
idp, err := s.query.IDPTemplateByID(ctx, true, req.Id, false, orgIDQuery)
idp, err := s.query.IDPTemplateByID(ctx, true, req.Id, false, nil, orgIDQuery)
if err != nil {
return nil, err
}

View File

@@ -18,7 +18,7 @@ func (l *Login) getOrgDomainPolicy(r *http.Request, orgID string) (*query.Domain
}
func (l *Login) getIDPByID(r *http.Request, id string) (*query.IDPTemplate, error) {
return l.query.IDPTemplateByID(r.Context(), false, id, false)
return l.query.IDPTemplateByID(r.Context(), false, id, false, nil)
}
func (l *Login) getLoginPolicy(r *http.Request, orgID string) (*query.LoginPolicy, error) {