mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 20:57:31 +00:00
feat: impersonation roles (#7442)
* partial work done * test IAM membership roles * org membership tests * console :(, translations and docs * fix integration test * fix tests * add EnableImpersonation to security policy API * fix integration test timestamp checking * add security policy tests and fix projections * add impersonation setting in console * add security settings to the settings v2 API * fix typo * move impersonation to instance --------- Co-authored-by: Livio Spring <livio.a@gmail.com>
This commit is contained in:
34
internal/api/grpc/settings/v2/server_integration_test.go
Normal file
34
internal/api/grpc/settings/v2/server_integration_test.go
Normal file
@@ -0,0 +1,34 @@
|
||||
//go:build integration
|
||||
|
||||
package settings_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/integration"
|
||||
settings "github.com/zitadel/zitadel/pkg/grpc/settings/v2beta"
|
||||
)
|
||||
|
||||
var (
|
||||
CTX, AdminCTX context.Context
|
||||
Tester *integration.Tester
|
||||
Client settings.SettingsServiceClient
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(func() int {
|
||||
ctx, _, cancel := integration.Contexts(3 * time.Minute)
|
||||
defer cancel()
|
||||
|
||||
Tester = integration.NewTester(ctx)
|
||||
defer Tester.Done()
|
||||
|
||||
CTX = ctx
|
||||
AdminCTX = Tester.WithAuthorization(ctx, integration.IAMOwner)
|
||||
Client = Tester.Client.SettingsV2
|
||||
return m.Run()
|
||||
}())
|
||||
}
|
@@ -11,7 +11,7 @@ import (
|
||||
"github.com/zitadel/zitadel/internal/i18n"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
object_pb "github.com/zitadel/zitadel/pkg/grpc/object/v2beta"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/settings/v2beta"
|
||||
settings "github.com/zitadel/zitadel/pkg/grpc/settings/v2beta"
|
||||
)
|
||||
|
||||
func (s *Server) GetLoginSettings(ctx context.Context, req *settings.GetLoginSettingsRequest) (*settings.GetLoginSettingsResponse, error) {
|
||||
@@ -124,3 +124,23 @@ func (s *Server) GetGeneralSettings(ctx context.Context, _ *settings.GetGeneralS
|
||||
DefaultLanguage: instance.DefaultLanguage().String(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) GetSecuritySettings(ctx context.Context, req *settings.GetSecuritySettingsRequest) (*settings.GetSecuritySettingsResponse, error) {
|
||||
policy, err := s.query.SecurityPolicy(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &settings.GetSecuritySettingsResponse{
|
||||
Settings: securityPolicyToSettingsPb(policy),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) SetSecuritySettings(ctx context.Context, req *settings.SetSecuritySettingsRequest) (*settings.SetSecuritySettingsResponse, error) {
|
||||
details, err := s.command.SetSecurityPolicy(ctx, securitySettingsToCommand(req))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &settings.SetSecuritySettingsResponse{
|
||||
Details: object.DomainToDetailsPb(details),
|
||||
}, nil
|
||||
}
|
||||
|
@@ -3,6 +3,7 @@ package settings
|
||||
import (
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/command"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
settings "github.com/zitadel/zitadel/pkg/grpc/settings/v2beta"
|
||||
@@ -205,3 +206,21 @@ func idpTypeToPb(idpType domain.IDPType) settings.IdentityProviderType {
|
||||
return settings.IdentityProviderType_IDENTITY_PROVIDER_TYPE_UNSPECIFIED
|
||||
}
|
||||
}
|
||||
|
||||
func securityPolicyToSettingsPb(policy *query.SecurityPolicy) *settings.SecuritySettings {
|
||||
return &settings.SecuritySettings{
|
||||
EmbeddedIframe: &settings.EmbeddedIframeSettings{
|
||||
Enabled: policy.EnableIframeEmbedding,
|
||||
AllowedOrigins: policy.AllowedOrigins,
|
||||
},
|
||||
EnableImpersonation: policy.EnableImpersonation,
|
||||
}
|
||||
}
|
||||
|
||||
func securitySettingsToCommand(req *settings.SetSecuritySettingsRequest) *command.SecurityPolicy {
|
||||
return &command.SecurityPolicy{
|
||||
EnableIframeEmbedding: req.GetEmbeddedIframe().GetEnabled(),
|
||||
AllowedOrigins: req.GetEmbeddedIframe().GetAllowedOrigins(),
|
||||
EnableImpersonation: req.GetEnableImpersonation(),
|
||||
}
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@ import (
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/api/grpc"
|
||||
"github.com/zitadel/zitadel/internal/command"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
settings "github.com/zitadel/zitadel/pkg/grpc/settings/v2beta"
|
||||
@@ -450,3 +451,35 @@ func Test_idpTypeToPb(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_securityPolicyToSettingsPb(t *testing.T) {
|
||||
want := &settings.SecuritySettings{
|
||||
EmbeddedIframe: &settings.EmbeddedIframeSettings{
|
||||
Enabled: true,
|
||||
AllowedOrigins: []string{"foo", "bar"},
|
||||
},
|
||||
EnableImpersonation: true,
|
||||
}
|
||||
got := securityPolicyToSettingsPb(&query.SecurityPolicy{
|
||||
EnableIframeEmbedding: true,
|
||||
AllowedOrigins: []string{"foo", "bar"},
|
||||
EnableImpersonation: true,
|
||||
})
|
||||
assert.Equal(t, want, got)
|
||||
}
|
||||
|
||||
func Test_securitySettingsToCommand(t *testing.T) {
|
||||
want := &command.SecurityPolicy{
|
||||
EnableIframeEmbedding: true,
|
||||
AllowedOrigins: []string{"foo", "bar"},
|
||||
EnableImpersonation: true,
|
||||
}
|
||||
got := securitySettingsToCommand(&settings.SetSecuritySettingsRequest{
|
||||
EmbeddedIframe: &settings.EmbeddedIframeSettings{
|
||||
Enabled: true,
|
||||
AllowedOrigins: []string{"foo", "bar"},
|
||||
},
|
||||
EnableImpersonation: true,
|
||||
})
|
||||
assert.Equal(t, want, got)
|
||||
}
|
||||
|
174
internal/api/grpc/settings/v2/settings_integration_test.go
Normal file
174
internal/api/grpc/settings/v2/settings_integration_test.go
Normal file
@@ -0,0 +1,174 @@
|
||||
//go:build integration
|
||||
|
||||
package settings_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/integration"
|
||||
object_pb "github.com/zitadel/zitadel/pkg/grpc/object/v2beta"
|
||||
settings "github.com/zitadel/zitadel/pkg/grpc/settings/v2beta"
|
||||
)
|
||||
|
||||
func TestServer_GetSecuritySettings(t *testing.T) {
|
||||
_, err := Client.SetSecuritySettings(AdminCTX, &settings.SetSecuritySettingsRequest{
|
||||
EmbeddedIframe: &settings.EmbeddedIframeSettings{
|
||||
Enabled: true,
|
||||
AllowedOrigins: []string{"foo", "bar"},
|
||||
},
|
||||
EnableImpersonation: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
ctx context.Context
|
||||
want *settings.GetSecuritySettingsResponse
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "permission error",
|
||||
ctx: Tester.WithAuthorization(CTX, integration.OrgOwner),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "success",
|
||||
ctx: AdminCTX,
|
||||
want: &settings.GetSecuritySettingsResponse{
|
||||
Settings: &settings.SecuritySettings{
|
||||
EmbeddedIframe: &settings.EmbeddedIframeSettings{
|
||||
Enabled: true,
|
||||
AllowedOrigins: []string{"foo", "bar"},
|
||||
},
|
||||
EnableImpersonation: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
resp, err := Client.GetSecuritySettings(tt.ctx, &settings.GetSecuritySettingsRequest{})
|
||||
if tt.wantErr {
|
||||
assert.Error(t, err)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
got, want := resp.GetSettings(), tt.want.GetSettings()
|
||||
assert.Equal(t, want.GetEmbeddedIframe().GetEnabled(), got.GetEmbeddedIframe().GetEnabled(), "enable iframe embedding")
|
||||
assert.Equal(t, want.GetEmbeddedIframe().GetAllowedOrigins(), got.GetEmbeddedIframe().GetAllowedOrigins(), "allowed origins")
|
||||
assert.Equal(t, want.GetEnableImpersonation(), got.GetEnableImpersonation(), "enable impersonation")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestServer_SetSecuritySettings(t *testing.T) {
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
req *settings.SetSecuritySettingsRequest
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *settings.SetSecuritySettingsResponse
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "permission error",
|
||||
args: args{
|
||||
ctx: Tester.WithAuthorization(CTX, integration.OrgOwner),
|
||||
req: &settings.SetSecuritySettingsRequest{
|
||||
EmbeddedIframe: &settings.EmbeddedIframeSettings{
|
||||
Enabled: true,
|
||||
AllowedOrigins: []string{"foo.com", "bar.com"},
|
||||
},
|
||||
EnableImpersonation: true,
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "success allowed origins",
|
||||
args: args{
|
||||
ctx: AdminCTX,
|
||||
req: &settings.SetSecuritySettingsRequest{
|
||||
EmbeddedIframe: &settings.EmbeddedIframeSettings{
|
||||
AllowedOrigins: []string{"foo.com", "bar.com"},
|
||||
},
|
||||
},
|
||||
},
|
||||
want: &settings.SetSecuritySettingsResponse{
|
||||
Details: &object_pb.Details{
|
||||
ChangeDate: timestamppb.Now(),
|
||||
ResourceOwner: Tester.Instance.InstanceID(),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "success enable iframe embedding",
|
||||
args: args{
|
||||
ctx: AdminCTX,
|
||||
req: &settings.SetSecuritySettingsRequest{
|
||||
EmbeddedIframe: &settings.EmbeddedIframeSettings{
|
||||
Enabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
want: &settings.SetSecuritySettingsResponse{
|
||||
Details: &object_pb.Details{
|
||||
ChangeDate: timestamppb.Now(),
|
||||
ResourceOwner: Tester.Instance.InstanceID(),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "success impersonation",
|
||||
args: args{
|
||||
ctx: AdminCTX,
|
||||
req: &settings.SetSecuritySettingsRequest{
|
||||
EnableImpersonation: true,
|
||||
},
|
||||
},
|
||||
want: &settings.SetSecuritySettingsResponse{
|
||||
Details: &object_pb.Details{
|
||||
ChangeDate: timestamppb.Now(),
|
||||
ResourceOwner: Tester.Instance.InstanceID(),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "success all",
|
||||
args: args{
|
||||
ctx: AdminCTX,
|
||||
req: &settings.SetSecuritySettingsRequest{
|
||||
EmbeddedIframe: &settings.EmbeddedIframeSettings{
|
||||
Enabled: true,
|
||||
AllowedOrigins: []string{"foo.com", "bar.com"},
|
||||
},
|
||||
EnableImpersonation: true,
|
||||
},
|
||||
},
|
||||
want: &settings.SetSecuritySettingsResponse{
|
||||
Details: &object_pb.Details{
|
||||
ChangeDate: timestamppb.Now(),
|
||||
ResourceOwner: Tester.Instance.InstanceID(),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := Client.SetSecuritySettings(tt.args.ctx, tt.args.req)
|
||||
if tt.wantErr {
|
||||
assert.Error(t, err)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
integration.AssertDetails(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user