mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-24 01:37:11 +00:00
feat: Feature flag for relational tables (#10599)
# Which Problems Are Solved This PR introduces a new feature flag `EnableRelationalTables` that will be used in following implementations to decide whether Zitadel should use the relational model or the event sourcing one. # TODO - [x] Implement flag at system level - [x] Display the flag on console: https://github.com/zitadel/zitadel/pull/10615 # How the Problems Are Solved - Implement loading the flag from config - Add persistence of the flag through gRPC endpoint (SetInstanceFeatures) - Implement reading of the flag through gRPC endpoint (GetInstanceFeatures) # Additional Changes Some minor refactoring to remove un-needed generics annotations # Additional Context - Closes #10574 --------- Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
This commit is contained in:
@@ -3,12 +3,15 @@ package command
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/muhlemmer/gu"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
@@ -18,6 +21,7 @@ import (
|
||||
"github.com/zitadel/zitadel/internal/crypto"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/feature"
|
||||
"github.com/zitadel/zitadel/internal/id"
|
||||
id_mock "github.com/zitadel/zitadel/internal/id/mock"
|
||||
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||
@@ -1727,3 +1731,126 @@ func TestCommandSide_RemoveInstance(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestInstanceSetupFeatures_ToInstanceFeatures(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type fields struct {
|
||||
LoginDefaultOrg *bool
|
||||
UserSchema *bool
|
||||
TokenExchange *bool
|
||||
ImprovedPerformance []feature.ImprovedPerformanceType
|
||||
DebugOIDCParentError *bool
|
||||
OIDCSingleV1SessionTermination *bool
|
||||
EnableBackChannelLogout *bool
|
||||
LoginV2 *InstanceSetupFeatureLoginV2
|
||||
PermissionCheckV2 *bool
|
||||
ConsoleUseV2UserApi *bool
|
||||
EnableRelationalTables *bool
|
||||
}
|
||||
|
||||
correctlyParsedURI, err := url.Parse("https://example.com")
|
||||
require.NoError(t, err)
|
||||
|
||||
tt := []struct {
|
||||
name string
|
||||
fields fields
|
||||
want *InstanceFeatures
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "nil features returns nil",
|
||||
fields: fields{},
|
||||
want: &InstanceFeatures{},
|
||||
},
|
||||
{
|
||||
name: "all fields no login v2",
|
||||
fields: fields{
|
||||
LoginDefaultOrg: gu.Ptr(true),
|
||||
UserSchema: gu.Ptr(false),
|
||||
TokenExchange: gu.Ptr(true),
|
||||
ImprovedPerformance: []feature.ImprovedPerformanceType{feature.ImprovedPerformanceTypeOrgDomainVerified},
|
||||
DebugOIDCParentError: gu.Ptr(true),
|
||||
OIDCSingleV1SessionTermination: gu.Ptr(false),
|
||||
EnableBackChannelLogout: gu.Ptr(true),
|
||||
PermissionCheckV2: gu.Ptr(true),
|
||||
ConsoleUseV2UserApi: gu.Ptr(false),
|
||||
EnableRelationalTables: gu.Ptr(true),
|
||||
},
|
||||
want: &InstanceFeatures{
|
||||
LoginDefaultOrg: gu.Ptr(true),
|
||||
UserSchema: gu.Ptr(false),
|
||||
TokenExchange: gu.Ptr(true),
|
||||
ImprovedPerformance: []feature.ImprovedPerformanceType{feature.ImprovedPerformanceTypeOrgDomainVerified},
|
||||
DebugOIDCParentError: gu.Ptr(true),
|
||||
OIDCSingleV1SessionTermination: gu.Ptr(false),
|
||||
EnableBackChannelLogout: gu.Ptr(true),
|
||||
LoginV2: nil,
|
||||
PermissionCheckV2: gu.Ptr(true),
|
||||
ConsoleUseV2UserApi: gu.Ptr(false),
|
||||
EnableRelationalTables: gu.Ptr(true),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with login v2 no base uri",
|
||||
fields: fields{
|
||||
LoginV2: &InstanceSetupFeatureLoginV2{
|
||||
Required: true,
|
||||
},
|
||||
},
|
||||
want: &InstanceFeatures{
|
||||
LoginV2: &feature.LoginV2{
|
||||
Required: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with login v2 valid base uri",
|
||||
fields: fields{
|
||||
LoginV2: &InstanceSetupFeatureLoginV2{
|
||||
Required: true,
|
||||
BaseURI: gu.Ptr("https://example.com"),
|
||||
},
|
||||
},
|
||||
want: &InstanceFeatures{
|
||||
LoginV2: &feature.LoginV2{
|
||||
Required: true,
|
||||
BaseURI: correctlyParsedURI,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with login v2 invalid base uri",
|
||||
fields: fields{
|
||||
LoginV2: &InstanceSetupFeatureLoginV2{
|
||||
Required: true,
|
||||
BaseURI: gu.Ptr("://invalid"),
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, tc := range tt {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
f := &InstanceSetupFeatures{
|
||||
LoginDefaultOrg: tc.fields.LoginDefaultOrg,
|
||||
UserSchema: tc.fields.UserSchema,
|
||||
TokenExchange: tc.fields.TokenExchange,
|
||||
ImprovedPerformance: tc.fields.ImprovedPerformance,
|
||||
DebugOIDCParentError: tc.fields.DebugOIDCParentError,
|
||||
OIDCSingleV1SessionTermination: tc.fields.OIDCSingleV1SessionTermination,
|
||||
EnableBackChannelLogout: tc.fields.EnableBackChannelLogout,
|
||||
LoginV2: tc.fields.LoginV2,
|
||||
PermissionCheckV2: tc.fields.PermissionCheckV2,
|
||||
ConsoleUseV2UserApi: tc.fields.ConsoleUseV2UserApi,
|
||||
EnableRelationalTables: tc.fields.EnableRelationalTables,
|
||||
}
|
||||
got, err := f.ToInstanceFeatures()
|
||||
|
||||
require.Equal(t, tc.wantErr, err != nil)
|
||||
assert.Equal(t, tc.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user