mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 00:47:33 +00:00
feat: new es testing2 (#1428)
* fix: org tests * fix: org tests * fix: user grant test * fix: user grant test * fix: project and project role test * fix: project grant test * fix: project grant test * fix: project member, grant member, app changed tests * fix: application tests * fix: application tests * fix: add oidc app test * fix: add oidc app test * fix: add api keys test * fix: iam policies * fix: iam and org member tests * fix: idp config tests * fix: iam tests * fix: user tests * fix: user tests * fix: user tests * fix: user tests * fix: user tests * fix: user tests * fix: user tests * fix: user tests * fix: user tests * fix: user tests * fix: org domain test * fix: org tests * fix: org tests * fix: implement org idps * fix: pr requests * fix: email tests * fix: fix idp check * fix: fix user profile
This commit is contained in:
@@ -221,6 +221,17 @@ func ModelIDPProviderTypeToPb(typ iam_model.IDPProviderType) idp_pb.IDPOwnerType
|
||||
}
|
||||
}
|
||||
|
||||
func IDPProviderTypeFromPb(typ idp_pb.IDPOwnerType) domain.IdentityProviderType {
|
||||
switch typ {
|
||||
case idp_pb.IDPOwnerType_IDP_OWNER_TYPE_ORG:
|
||||
return domain.IdentityProviderTypeOrg
|
||||
case idp_pb.IDPOwnerType_IDP_OWNER_TYPE_SYSTEM:
|
||||
return domain.IdentityProviderTypeSystem
|
||||
default:
|
||||
return domain.IdentityProviderTypeOrg
|
||||
}
|
||||
}
|
||||
|
||||
func IDPIDQueryToModel(query *idp_pb.IDPIDQuery) *iam_model.IDPConfigSearchQuery {
|
||||
return &iam_model.IDPConfigSearchQuery{
|
||||
Key: iam_model.IDPConfigSearchKeyIdpConfigID, //TODO: whats the difference between idpconfigid and aggregateid search key?
|
||||
|
@@ -6,29 +6,84 @@ import (
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
idp_grpc "github.com/caos/zitadel/internal/api/grpc/idp"
|
||||
object_pb "github.com/caos/zitadel/internal/api/grpc/object"
|
||||
mgmt_pb "github.com/caos/zitadel/pkg/grpc/management"
|
||||
)
|
||||
|
||||
func (s *Server) GetOrgIDPByID(ctx context.Context, req *mgmt_pb.GetOrgIDPByIDRequest) (*mgmt_pb.GetOrgIDPByIDResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetOrgIDPByID not implemented")
|
||||
idp, err := s.org.IDPConfigByID(ctx, req.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mgmt_pb.GetOrgIDPByIDResponse{Idp: idp_grpc.ModelIDPViewToPb(idp)}, nil
|
||||
}
|
||||
func (s *Server) ListOrgIDPs(ctx context.Context, req *mgmt_pb.ListOrgIDPsRequest) (*mgmt_pb.ListOrgIDPsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ListOrgIDPs not implemented")
|
||||
resp, err := s.org.SearchIDPConfigs(ctx, listIDPsToModel(req))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mgmt_pb.ListOrgIDPsResponse{
|
||||
Result: idp_grpc.IDPViewsToPb(resp.Result),
|
||||
Details: object_pb.ToListDetails(resp.TotalResult, resp.Sequence, resp.Timestamp),
|
||||
}, nil
|
||||
}
|
||||
func (s *Server) AddOrgOIDCIDP(ctx context.Context, req *mgmt_pb.AddOrgOIDCIDPRequest) (*mgmt_pb.AddOrgOIDCIDPResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method AddOrgOIDCIDP not implemented")
|
||||
config, err := s.command.AddDefaultIDPConfig(ctx, addOIDCIDPRequestToDomain(req))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mgmt_pb.AddOrgOIDCIDPResponse{
|
||||
IdpId: config.AggregateID,
|
||||
Details: object_pb.ToDetailsPb(
|
||||
config.Sequence,
|
||||
config.ChangeDate,
|
||||
config.ResourceOwner,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
func (s *Server) DeactivateOrgIDP(ctx context.Context, req *mgmt_pb.DeactivateOrgIDPRequest) (*mgmt_pb.DeactivateOrgIDPResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method DeactivateOrgIDP not implemented")
|
||||
objectDetails, err := s.command.DeactivateDefaultIDPConfig(ctx, req.IdpId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mgmt_pb.DeactivateOrgIDPResponse{Details: object_pb.DomainToDetailsPb(objectDetails)}, nil
|
||||
}
|
||||
func (s *Server) ReactivateOrgIDP(ctx context.Context, req *mgmt_pb.ReactivateOrgIDPRequest) (*mgmt_pb.ReactivateOrgIDPResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ReactivateOrgIDP not implemented")
|
||||
objectDetails, err := s.command.ReactivateDefaultIDPConfig(ctx, req.IdpId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mgmt_pb.ReactivateOrgIDPResponse{Details: object_pb.DomainToDetailsPb(objectDetails)}, nil
|
||||
}
|
||||
func (s *Server) RemoveOrgIDP(ctx context.Context, req *mgmt_pb.RemoveOrgIDPRequest) (*mgmt_pb.RemoveOrgIDPResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RemoveOrgIDP not implemented")
|
||||
idpProviders, err := s.org.GetIDPProvidersByIDPConfigID(ctx, authz.GetCtxData(ctx).OrgID, req.IdpId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
externalIDPs, err := s.user.ExternalIDPsByIDPConfigID(ctx, req.IdpId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = s.command.RemoveDefaultIDPConfig(ctx, req.IdpId, idpProviderViewsToDomain(idpProviders), externalIDPViewsToDomain(externalIDPs)...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mgmt_pb.RemoveOrgIDPResponse{}, nil
|
||||
}
|
||||
func (s *Server) UpdateOrgIDP(ctx context.Context, req *mgmt_pb.UpdateOrgIDPRequest) (*mgmt_pb.UpdateOrgIDPResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method UpdateOrgIDP not implemented")
|
||||
config, err := s.command.ChangeDefaultIDPConfig(ctx, updateIDPToDomain(req))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mgmt_pb.UpdateOrgIDPResponse{
|
||||
Details: object_pb.ToDetailsPb(
|
||||
config.Sequence,
|
||||
config.ChangeDate,
|
||||
config.ResourceOwner,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
func (s *Server) UpdateOrgIDPOIDCConfig(ctx context.Context, req *mgmt_pb.UpdateOrgIDPOIDCConfigRequest) (*mgmt_pb.UpdateOrgIDPOIDCConfigResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method UpdateOrgIDPOIDCConfig not implemented")
|
||||
|
121
internal/api/grpc/management/idp_converter.go
Normal file
121
internal/api/grpc/management/idp_converter.go
Normal file
@@ -0,0 +1,121 @@
|
||||
package management
|
||||
|
||||
import (
|
||||
idp_grpc "github.com/caos/zitadel/internal/api/grpc/idp"
|
||||
"github.com/caos/zitadel/internal/api/grpc/object"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
user_model "github.com/caos/zitadel/internal/user/model"
|
||||
mgmt_pb "github.com/caos/zitadel/pkg/grpc/management"
|
||||
)
|
||||
|
||||
func addOIDCIDPRequestToDomain(req *mgmt_pb.AddOrgOIDCIDPRequest) *domain.IDPConfig {
|
||||
return &domain.IDPConfig{
|
||||
Name: req.Name,
|
||||
OIDCConfig: addOIDCIDPRequestToDomainOIDCIDPConfig(req),
|
||||
StylingType: idp_grpc.IDPStylingTypeToDomain(req.StylingType),
|
||||
Type: domain.IDPConfigTypeOIDC,
|
||||
}
|
||||
}
|
||||
|
||||
func addOIDCIDPRequestToDomainOIDCIDPConfig(req *mgmt_pb.AddOrgOIDCIDPRequest) *domain.OIDCIDPConfig {
|
||||
return &domain.OIDCIDPConfig{
|
||||
ClientID: req.ClientId,
|
||||
ClientSecretString: req.ClientSecret,
|
||||
Issuer: req.Issuer,
|
||||
Scopes: req.Scopes,
|
||||
IDPDisplayNameMapping: idp_grpc.MappingFieldToDomain(req.DisplayNameMapping),
|
||||
UsernameMapping: idp_grpc.MappingFieldToDomain(req.UsernameMapping),
|
||||
}
|
||||
}
|
||||
|
||||
func updateIDPToDomain(req *mgmt_pb.UpdateOrgIDPRequest) *domain.IDPConfig {
|
||||
return &domain.IDPConfig{
|
||||
IDPConfigID: req.IdpId,
|
||||
Name: req.Name,
|
||||
StylingType: idp_grpc.IDPStylingTypeToDomain(req.StylingType),
|
||||
}
|
||||
}
|
||||
|
||||
func updateOIDCConfigToDomain(req *mgmt_pb.UpdateOrgIDPOIDCConfigRequest) *domain.OIDCIDPConfig {
|
||||
return &domain.OIDCIDPConfig{
|
||||
IDPConfigID: req.IdpId,
|
||||
ClientID: req.ClientId,
|
||||
ClientSecretString: req.ClientSecret,
|
||||
Issuer: req.Issuer,
|
||||
Scopes: req.Scopes,
|
||||
IDPDisplayNameMapping: idp_grpc.MappingFieldToDomain(req.DisplayNameMapping),
|
||||
UsernameMapping: idp_grpc.MappingFieldToDomain(req.UsernameMapping),
|
||||
}
|
||||
}
|
||||
|
||||
func listIDPsToModel(req *mgmt_pb.ListOrgIDPsRequest) *iam_model.IDPConfigSearchRequest {
|
||||
offset, limit, asc := object.ListQueryToModel(req.Query)
|
||||
return &iam_model.IDPConfigSearchRequest{
|
||||
Offset: offset,
|
||||
Limit: limit,
|
||||
Asc: asc,
|
||||
SortingColumn: idp_grpc.FieldNameToModel(req.SortingColumn),
|
||||
Queries: idpQueriesToModel(req.Queries),
|
||||
}
|
||||
}
|
||||
|
||||
func idpQueriesToModel(queries []*mgmt_pb.IDPQuery) []*iam_model.IDPConfigSearchQuery {
|
||||
q := make([]*iam_model.IDPConfigSearchQuery, len(queries))
|
||||
for i, query := range queries {
|
||||
q[i] = idpQueryToModel(query)
|
||||
}
|
||||
|
||||
return q
|
||||
}
|
||||
|
||||
func idpQueryToModel(query *mgmt_pb.IDPQuery) *iam_model.IDPConfigSearchQuery {
|
||||
switch q := query.Query.(type) {
|
||||
case *mgmt_pb.IDPQuery_IdpNameQuery:
|
||||
return idp_grpc.IDPNameQueryToModel(q.IdpNameQuery)
|
||||
case *mgmt_pb.IDPQuery_IdpIdQuery:
|
||||
return idp_grpc.IDPIDQueryToModel(q.IdpIdQuery)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func idpProviderViewsToDomain(idps []*iam_model.IDPProviderView) []*domain.IDPProvider {
|
||||
idpProvider := make([]*domain.IDPProvider, len(idps))
|
||||
for i, idp := range idps {
|
||||
idpProvider[i] = &domain.IDPProvider{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: idp.AggregateID,
|
||||
},
|
||||
IDPConfigID: idp.IDPConfigID,
|
||||
Type: idpConfigTypeToDomain(idp.IDPProviderType),
|
||||
}
|
||||
}
|
||||
return idpProvider
|
||||
}
|
||||
|
||||
func idpConfigTypeToDomain(idpType iam_model.IDPProviderType) domain.IdentityProviderType {
|
||||
switch idpType {
|
||||
case iam_model.IDPProviderTypeOrg:
|
||||
return domain.IdentityProviderTypeOrg
|
||||
default:
|
||||
return domain.IdentityProviderTypeSystem
|
||||
}
|
||||
}
|
||||
|
||||
func externalIDPViewsToDomain(idps []*user_model.ExternalIDPView) []*domain.ExternalIDP {
|
||||
externalIDPs := make([]*domain.ExternalIDP, len(idps))
|
||||
for i, idp := range idps {
|
||||
externalIDPs[i] = &domain.ExternalIDP{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: idp.UserID,
|
||||
ResourceOwner: idp.ResourceOwner,
|
||||
},
|
||||
IDPConfigID: idp.IDPConfigID,
|
||||
ExternalUserID: idp.ExternalUserID,
|
||||
DisplayName: idp.UserDisplayName,
|
||||
}
|
||||
}
|
||||
return externalIDPs
|
||||
}
|
149
internal/api/grpc/management/idp_converter_test.go
Normal file
149
internal/api/grpc/management/idp_converter_test.go
Normal file
@@ -0,0 +1,149 @@
|
||||
package management
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/caos/zitadel/internal/test"
|
||||
"github.com/caos/zitadel/pkg/grpc/idp"
|
||||
mgmt_pb "github.com/caos/zitadel/pkg/grpc/management"
|
||||
)
|
||||
|
||||
func Test_addOIDCIDPRequestToDomain(t *testing.T) {
|
||||
type args struct {
|
||||
req *mgmt_pb.AddOrgOIDCIDPRequest
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
}{
|
||||
{
|
||||
name: "all fields filled",
|
||||
args: args{
|
||||
req: &mgmt_pb.AddOrgOIDCIDPRequest{
|
||||
Name: "ZITADEL",
|
||||
StylingType: idp.IDPStylingType_STYLING_TYPE_GOOGLE,
|
||||
ClientId: "test1234",
|
||||
ClientSecret: "test4321",
|
||||
Issuer: "zitadel.ch",
|
||||
Scopes: []string{"email", "profile"},
|
||||
DisplayNameMapping: idp.OIDCMappingField_OIDC_MAPPING_FIELD_EMAIL,
|
||||
UsernameMapping: idp.OIDCMappingField_OIDC_MAPPING_FIELD_PREFERRED_USERNAME,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := addOIDCIDPRequestToDomain(tt.args.req)
|
||||
test.AssertFieldsMapped(t, got,
|
||||
"ObjectRoot",
|
||||
"OIDCConfig.ClientSecret",
|
||||
"OIDCConfig.ObjectRoot",
|
||||
"OIDCConfig.IDPConfigID",
|
||||
"IDPConfigID",
|
||||
"State",
|
||||
"Type", //TODO: default (0) is oidc
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_addOIDCIDPRequestToDomainOIDCIDPConfig(t *testing.T) {
|
||||
type args struct {
|
||||
req *mgmt_pb.AddOrgOIDCIDPRequest
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
}{
|
||||
{
|
||||
name: "all fields filled",
|
||||
args: args{
|
||||
req: &mgmt_pb.AddOrgOIDCIDPRequest{
|
||||
ClientId: "test1234",
|
||||
ClientSecret: "test4321",
|
||||
Issuer: "zitadel.ch",
|
||||
Scopes: []string{"email", "profile"},
|
||||
DisplayNameMapping: idp.OIDCMappingField_OIDC_MAPPING_FIELD_EMAIL,
|
||||
UsernameMapping: idp.OIDCMappingField_OIDC_MAPPING_FIELD_PREFERRED_USERNAME,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := addOIDCIDPRequestToDomainOIDCIDPConfig(tt.args.req)
|
||||
test.AssertFieldsMapped(t, got,
|
||||
"ObjectRoot",
|
||||
"ClientSecret", //TODO: is client secret string enough for backend?
|
||||
"IDPConfigID",
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_updateIDPToDomain(t *testing.T) {
|
||||
type args struct {
|
||||
req *mgmt_pb.UpdateOrgIDPRequest
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
}{
|
||||
{
|
||||
name: "all fields filled",
|
||||
args: args{
|
||||
req: &mgmt_pb.UpdateOrgIDPRequest{
|
||||
IdpId: "13523",
|
||||
Name: "new name",
|
||||
StylingType: idp.IDPStylingType_STYLING_TYPE_GOOGLE,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := updateIDPToDomain(tt.args.req)
|
||||
test.AssertFieldsMapped(t, got,
|
||||
"ObjectRoot",
|
||||
"OIDCConfig",
|
||||
"State",
|
||||
"Type", //TODO: type should not be changeable
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_updateOIDCConfigToDomain(t *testing.T) {
|
||||
type args struct {
|
||||
req *mgmt_pb.UpdateOrgIDPOIDCConfigRequest
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
}{
|
||||
{
|
||||
name: "all fields filled",
|
||||
args: args{
|
||||
req: &mgmt_pb.UpdateOrgIDPOIDCConfigRequest{
|
||||
IdpId: "4208",
|
||||
Issuer: "zitadel.ch",
|
||||
ClientId: "ZITEADEL",
|
||||
ClientSecret: "i'm so secret",
|
||||
Scopes: []string{"profile"},
|
||||
DisplayNameMapping: idp.OIDCMappingField_OIDC_MAPPING_FIELD_EMAIL,
|
||||
UsernameMapping: idp.OIDCMappingField_OIDC_MAPPING_FIELD_PREFERRED_USERNAME,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := updateOIDCConfigToDomain(tt.args.req)
|
||||
test.AssertFieldsMapped(t, got,
|
||||
"ObjectRoot",
|
||||
"ClientSecret",
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
@@ -79,7 +79,7 @@ func (s *Server) ListLoginPolicyIDPs(ctx context.Context, req *mgmt_pb.ListLogin
|
||||
}
|
||||
|
||||
func (s *Server) AddIDPToLoginPolicy(ctx context.Context, req *mgmt_pb.AddIDPToLoginPolicyRequest) (*mgmt_pb.AddIDPToLoginPolicyResponse, error) {
|
||||
idp, err := s.command.AddIDPProviderToLoginPolicy(ctx, authz.GetCtxData(ctx).OrgID, &domain.IDPProvider{IDPConfigID: req.IdpId}) //TODO: old way was to also add type but this doesnt make sense in my point of view
|
||||
idp, err := s.command.AddIDPProviderToLoginPolicy(ctx, authz.GetCtxData(ctx).OrgID, &domain.IDPProvider{IDPConfigID: req.IdpId, Type: idp.IDPProviderTypeFromPb(req.OwnerType)})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
Reference in New Issue
Block a user