mirror of
https://github.com/zitadel/zitadel.git
synced 2025-02-25 18:55:27 -06:00
add feature flag to db
This commit is contained in:
parent
462eff65fa
commit
4007274346
@ -403,6 +403,34 @@
|
||||
'SETTING.FEATURES.OIDCSINGLEV1SESSIONTERMINATION_DESCRIPTION' | translate
|
||||
}}</cnsl-info-section>
|
||||
</div>
|
||||
|
||||
<div class="feature-row" *ngIf="toggleStates.consoleUseV2UserApi">
|
||||
<span>{{ 'SETTING.FEATURES.CONSOLEUSEV2USERAPI' | translate }}</span>
|
||||
<div class="row">
|
||||
<mat-button-toggle-group
|
||||
class="theme-toggle"
|
||||
class="buttongroup"
|
||||
[(ngModel)]="toggleStates.consoleUseV2UserApi.state"
|
||||
(change)="validateAndSave()"
|
||||
name="displayview"
|
||||
aria-label="Display View"
|
||||
>
|
||||
<mat-button-toggle [value]="ToggleState.DISABLED">
|
||||
<div class="toggle-row">
|
||||
<span> {{ 'SETTING.FEATURES.STATES.DISABLED' | translate }}</span>
|
||||
</div>
|
||||
</mat-button-toggle>
|
||||
<mat-button-toggle [value]="ToggleState.ENABLED">
|
||||
<div class="toggle-row">
|
||||
<span> {{ 'SETTING.FEATURES.STATES.ENABLED' | translate }}</span>
|
||||
</div>
|
||||
</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
</div>
|
||||
<cnsl-info-section class="feature-info">{{
|
||||
'SETTING.FEATURES.CONSOLEUSEV2USERAPI_DESCRIPTION' | translate
|
||||
}}</cnsl-info-section>
|
||||
</div>
|
||||
</div>
|
||||
</cnsl-card>
|
||||
</div>
|
||||
|
@ -16,13 +16,14 @@ import { InfoSectionModule } from 'src/app/modules/info-section/info-section.mod
|
||||
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
|
||||
import { Event } from 'src/app/proto/generated/zitadel/event_pb';
|
||||
import { Source } from 'src/app/proto/generated/zitadel/feature/v2beta/feature_pb';
|
||||
import {
|
||||
GetInstanceFeaturesResponse,
|
||||
SetInstanceFeaturesRequest,
|
||||
} from 'src/app/proto/generated/zitadel/feature/v2beta/instance_pb';
|
||||
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.service';
|
||||
import { FeatureService } from 'src/app/services/feature.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
import {
|
||||
GetInstanceFeaturesResponse,
|
||||
SetInstanceFeaturesRequest,
|
||||
} from '../../proto/generated/zitadel/feature/v2/instance_pb';
|
||||
import { withIdentifier } from 'codelyzer/util/astQuery';
|
||||
|
||||
enum ToggleState {
|
||||
ENABLED = 'ENABLED',
|
||||
@ -39,6 +40,7 @@ type ToggleStates = {
|
||||
oidcTokenExchange?: FeatureState;
|
||||
actions?: FeatureState;
|
||||
oidcSingleV1SessionTermination?: FeatureState;
|
||||
consoleUseV2UserApi?: FeatureState;
|
||||
};
|
||||
|
||||
@Component({
|
||||
@ -142,6 +144,7 @@ export class FeaturesComponent implements OnDestroy {
|
||||
);
|
||||
changed = true;
|
||||
}
|
||||
req.setConsoleUseV2UserApi(this.toggleStates?.consoleUseV2UserApi?.state === ToggleState.ENABLED);
|
||||
|
||||
if (changed) {
|
||||
this.featureService
|
||||
@ -232,6 +235,10 @@ export class FeaturesComponent implements OnDestroy {
|
||||
? ToggleState.ENABLED
|
||||
: ToggleState.DISABLED,
|
||||
},
|
||||
consoleUseV2UserApi: {
|
||||
source: this.featureData.consoleUseV2UserApi?.source || Source.SOURCE_INSTANCE,
|
||||
state: this.featureData.consoleUseV2UserApi?.enabled ? ToggleState.ENABLED : ToggleState.DISABLED,
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
@ -1,19 +1,19 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { GrpcService } from './grpc.service';
|
||||
|
||||
import {
|
||||
GetInstanceFeaturesRequest,
|
||||
GetInstanceFeaturesResponse,
|
||||
ResetInstanceFeaturesRequest,
|
||||
SetInstanceFeaturesRequest,
|
||||
SetInstanceFeaturesResponse,
|
||||
} from '../proto/generated/zitadel/feature/v2beta/instance_pb';
|
||||
import {
|
||||
GetOrganizationFeaturesRequest,
|
||||
GetOrganizationFeaturesResponse,
|
||||
} from '../proto/generated/zitadel/feature/v2beta/organization_pb';
|
||||
import { GetUserFeaturesRequest, GetUserFeaturesResponse } from '../proto/generated/zitadel/feature/v2beta/user_pb';
|
||||
import { GetSystemFeaturesRequest, GetSystemFeaturesResponse } from '../proto/generated/zitadel/feature/v2beta/system_pb';
|
||||
import {
|
||||
GetInstanceFeaturesRequest,
|
||||
GetInstanceFeaturesResponse,
|
||||
ResetInstanceFeaturesRequest,
|
||||
SetInstanceFeaturesRequest,
|
||||
SetInstanceFeaturesResponse,
|
||||
} from '../proto/generated/zitadel/feature/v2/instance_pb';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
|
@ -16,13 +16,13 @@ import { ExhaustedGrpcInterceptor } from './interceptors/exhausted.grpc.intercep
|
||||
import { I18nInterceptor } from './interceptors/i18n.interceptor';
|
||||
import { OrgInterceptor } from './interceptors/org.interceptor';
|
||||
import { StorageService } from './storage.service';
|
||||
import { FeatureServiceClient } from '../proto/generated/zitadel/feature/v2beta/Feature_serviceServiceClientPb';
|
||||
import { UserServiceClient } from '../proto/generated/zitadel/user/v2/User_serviceServiceClientPb';
|
||||
//@ts-ignore
|
||||
import { createUserServiceClient } from '@zitadel/client/v2';
|
||||
//@ts-ignore
|
||||
import { createAuthServiceClient, createManagementServiceClient } from '@zitadel/client/v1';
|
||||
import { createGrpcWebTransport } from '@connectrpc/connect-web';
|
||||
import { FeatureServiceClient } from '../proto/generated/zitadel/feature/v2/Feature_serviceServiceClientPb';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
|
@ -1494,7 +1494,9 @@
|
||||
"ENABLED": "\"Enabled\" is inherited",
|
||||
"DISABLED": "\"Disabled\" is inherited"
|
||||
},
|
||||
"RESET": "Set all to inherit"
|
||||
"RESET": "Set all to inherit",
|
||||
"CONSOLEUSEV2USERAPI": "Use V2 Api in Console for User creation",
|
||||
"CONSOLEUSEV2USERAPI_DESCRIPTION": "When this flag is enabled, the console uses the V2 User API to create new users. With the V2 API, newly created users start without an initial state."
|
||||
},
|
||||
"DIALOG": {
|
||||
"RESET": {
|
||||
|
@ -71,6 +71,7 @@ func instanceFeaturesToCommand(req *feature_pb.SetInstanceFeaturesRequest) (*com
|
||||
EnableBackChannelLogout: req.EnableBackChannelLogout,
|
||||
LoginV2: loginV2,
|
||||
PermissionCheckV2: req.PermissionCheckV2,
|
||||
ConsoleUseV2UserApi: req.ConsoleUseV2UserApi,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -91,10 +92,7 @@ func instanceFeaturesToPb(f *query.InstanceFeatures) *feature_pb.GetInstanceFeat
|
||||
EnableBackChannelLogout: featureSourceToFlagPb(&f.EnableBackChannelLogout),
|
||||
LoginV2: loginV2ToLoginV2FlagPb(f.LoginV2),
|
||||
PermissionCheckV2: featureSourceToFlagPb(&f.PermissionCheckV2),
|
||||
ConsoleUseV2UserApi: &feature_pb.FeatureFlag{
|
||||
Enabled: true,
|
||||
Source: feature_pb.Source_SOURCE_INSTANCE,
|
||||
},
|
||||
ConsoleUseV2UserApi: featureSourceToFlagPb(&f.ConsoleUseV2UserApi),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,10 +63,6 @@ func instanceFeaturesToPb(f *query.InstanceFeatures) *feature_pb.GetInstanceFeat
|
||||
WebKey: featureSourceToFlagPb(&f.WebKey),
|
||||
DebugOidcParentError: featureSourceToFlagPb(&f.DebugOIDCParentError),
|
||||
OidcSingleV1SessionTermination: featureSourceToFlagPb(&f.OIDCSingleV1SessionTermination),
|
||||
ConsoleUseV2UserApi: &feature_pb.FeatureFlag{
|
||||
Enabled: true,
|
||||
Source: feature_pb.Source_SOURCE_INSTANCE,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@ type InstanceFeatures struct {
|
||||
EnableBackChannelLogout *bool
|
||||
LoginV2 *feature.LoginV2
|
||||
PermissionCheckV2 *bool
|
||||
ConsoleUseV2UserApi *bool
|
||||
}
|
||||
|
||||
func (m *InstanceFeatures) isEmpty() bool {
|
||||
@ -47,7 +48,7 @@ func (m *InstanceFeatures) isEmpty() bool {
|
||||
m.DisableUserTokenEvent == nil &&
|
||||
m.EnableBackChannelLogout == nil &&
|
||||
m.LoginV2 == nil &&
|
||||
m.PermissionCheckV2 == nil
|
||||
m.PermissionCheckV2 == nil && m.ConsoleUseV2UserApi == nil
|
||||
}
|
||||
|
||||
func (c *Commands) SetInstanceFeatures(ctx context.Context, f *InstanceFeatures) (*domain.ObjectDetails, error) {
|
||||
|
@ -80,6 +80,7 @@ func (m *InstanceFeaturesWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
feature_v2.InstanceEnableBackChannelLogout,
|
||||
feature_v2.InstanceLoginVersion,
|
||||
feature_v2.InstancePermissionCheckV2,
|
||||
feature_v2.InstanceConsoleUseV2UserApi,
|
||||
).
|
||||
Builder().ResourceOwner(m.ResourceOwner)
|
||||
}
|
||||
@ -133,6 +134,9 @@ func reduceInstanceFeature(features *InstanceFeatures, key feature.Key, value an
|
||||
case feature.KeyPermissionCheckV2:
|
||||
v := value.(bool)
|
||||
features.PermissionCheckV2 = &v
|
||||
case feature.KeyConsoleUseV2UserApi:
|
||||
v := value.(bool)
|
||||
features.ConsoleUseV2UserApi = &v
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,5 +157,6 @@ func (wm *InstanceFeaturesWriteModel) setCommands(ctx context.Context, f *Instan
|
||||
cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.EnableBackChannelLogout, f.EnableBackChannelLogout, feature_v2.InstanceEnableBackChannelLogout)
|
||||
cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.LoginV2, f.LoginV2, feature_v2.InstanceLoginVersion)
|
||||
cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.PermissionCheckV2, f.PermissionCheckV2, feature_v2.InstancePermissionCheckV2)
|
||||
cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.ConsoleUseV2UserApi, f.ConsoleUseV2UserApi, feature_v2.InstanceConsoleUseV2UserApi)
|
||||
return cmds
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ const (
|
||||
KeyEnableBackChannelLogout
|
||||
KeyLoginV2
|
||||
KeyPermissionCheckV2
|
||||
KeyConsoleUseV2UserApi
|
||||
)
|
||||
|
||||
//go:generate enumer -type Level -transform snake -trimprefix Level
|
||||
@ -54,6 +55,7 @@ type Features struct {
|
||||
EnableBackChannelLogout bool `json:"enable_back_channel_logout,omitempty"`
|
||||
LoginV2 LoginV2 `json:"login_v2,omitempty"`
|
||||
PermissionCheckV2 bool `json:"permission_check_v2,omitempty"`
|
||||
ConsoleUseV2UserApi bool `json:"console_use_v2_user_api,omitempty"`
|
||||
}
|
||||
|
||||
type ImprovedPerformanceType int32
|
||||
|
@ -7,11 +7,11 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
const _KeyName = "unspecifiedlogin_default_orgtrigger_introspection_projectionslegacy_introspectionuser_schematoken_exchangeactionsimproved_performanceweb_keydebug_oidc_parent_erroroidc_single_v1_session_terminationdisable_user_token_eventenable_back_channel_logoutlogin_v2permission_check_v2"
|
||||
const _KeyName = "unspecifiedlogin_default_orgtrigger_introspection_projectionslegacy_introspectionuser_schematoken_exchangeactionsimproved_performanceweb_keydebug_oidc_parent_erroroidc_single_v1_session_terminationdisable_user_token_eventenable_back_channel_logoutlogin_v2permission_check_v2console_use_v2_user_api"
|
||||
|
||||
var _KeyIndex = [...]uint16{0, 11, 28, 61, 81, 92, 106, 113, 133, 140, 163, 197, 221, 247, 255, 274}
|
||||
var _KeyIndex = [...]uint16{0, 11, 28, 61, 81, 92, 106, 113, 133, 140, 163, 197, 221, 247, 255, 274, 297}
|
||||
|
||||
const _KeyLowerName = "unspecifiedlogin_default_orgtrigger_introspection_projectionslegacy_introspectionuser_schematoken_exchangeactionsimproved_performanceweb_keydebug_oidc_parent_erroroidc_single_v1_session_terminationdisable_user_token_eventenable_back_channel_logoutlogin_v2permission_check_v2"
|
||||
const _KeyLowerName = "unspecifiedlogin_default_orgtrigger_introspection_projectionslegacy_introspectionuser_schematoken_exchangeactionsimproved_performanceweb_keydebug_oidc_parent_erroroidc_single_v1_session_terminationdisable_user_token_eventenable_back_channel_logoutlogin_v2permission_check_v2console_use_v2_user_api"
|
||||
|
||||
func (i Key) String() string {
|
||||
if i < 0 || i >= Key(len(_KeyIndex)-1) {
|
||||
@ -39,9 +39,10 @@ func _KeyNoOp() {
|
||||
_ = x[KeyEnableBackChannelLogout-(12)]
|
||||
_ = x[KeyLoginV2-(13)]
|
||||
_ = x[KeyPermissionCheckV2-(14)]
|
||||
_ = x[KeyConsoleUseV2UserApi-(15)]
|
||||
}
|
||||
|
||||
var _KeyValues = []Key{KeyUnspecified, KeyLoginDefaultOrg, KeyTriggerIntrospectionProjections, KeyLegacyIntrospection, KeyUserSchema, KeyTokenExchange, KeyActions, KeyImprovedPerformance, KeyWebKey, KeyDebugOIDCParentError, KeyOIDCSingleV1SessionTermination, KeyDisableUserTokenEvent, KeyEnableBackChannelLogout, KeyLoginV2, KeyPermissionCheckV2}
|
||||
var _KeyValues = []Key{KeyUnspecified, KeyLoginDefaultOrg, KeyTriggerIntrospectionProjections, KeyLegacyIntrospection, KeyUserSchema, KeyTokenExchange, KeyActions, KeyImprovedPerformance, KeyWebKey, KeyDebugOIDCParentError, KeyOIDCSingleV1SessionTermination, KeyDisableUserTokenEvent, KeyEnableBackChannelLogout, KeyLoginV2, KeyPermissionCheckV2, KeyConsoleUseV2UserApi}
|
||||
|
||||
var _KeyNameToValueMap = map[string]Key{
|
||||
_KeyName[0:11]: KeyUnspecified,
|
||||
@ -74,6 +75,8 @@ var _KeyNameToValueMap = map[string]Key{
|
||||
_KeyLowerName[247:255]: KeyLoginV2,
|
||||
_KeyName[255:274]: KeyPermissionCheckV2,
|
||||
_KeyLowerName[255:274]: KeyPermissionCheckV2,
|
||||
_KeyName[274:297]: KeyConsoleUseV2UserApi,
|
||||
_KeyLowerName[274:297]: KeyConsoleUseV2UserApi,
|
||||
}
|
||||
|
||||
var _KeyNames = []string{
|
||||
@ -92,6 +95,7 @@ var _KeyNames = []string{
|
||||
_KeyName[221:247],
|
||||
_KeyName[247:255],
|
||||
_KeyName[255:274],
|
||||
_KeyName[274:297],
|
||||
}
|
||||
|
||||
// KeyString retrieves an enum value from the enum constants string name.
|
||||
|
@ -23,6 +23,7 @@ type InstanceFeatures struct {
|
||||
EnableBackChannelLogout FeatureSource[bool]
|
||||
LoginV2 FeatureSource[*feature.LoginV2]
|
||||
PermissionCheckV2 FeatureSource[bool]
|
||||
ConsoleUseV2UserApi FeatureSource[bool]
|
||||
}
|
||||
|
||||
func (q *Queries) GetInstanceFeatures(ctx context.Context, cascade bool) (_ *InstanceFeatures, err error) {
|
||||
|
@ -76,6 +76,7 @@ func (m *InstanceFeaturesReadModel) Query() *eventstore.SearchQueryBuilder {
|
||||
feature_v2.InstanceEnableBackChannelLogout,
|
||||
feature_v2.InstanceLoginVersion,
|
||||
feature_v2.InstancePermissionCheckV2,
|
||||
feature_v2.InstanceConsoleUseV2UserApi,
|
||||
).
|
||||
Builder().ResourceOwner(m.ResourceOwner)
|
||||
}
|
||||
@ -142,6 +143,8 @@ func reduceInstanceFeatureSet[T any](features *InstanceFeatures, event *feature_
|
||||
features.LoginV2.set(level, event.Value)
|
||||
case feature.KeyPermissionCheckV2:
|
||||
features.PermissionCheckV2.set(level, event.Value)
|
||||
case feature.KeyConsoleUseV2UserApi:
|
||||
features.ConsoleUseV2UserApi.set(level, event.Value)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -116,6 +116,10 @@ func (*instanceFeatureProjection) Reducers() []handler.AggregateReducer {
|
||||
Event: feature_v2.InstancePermissionCheckV2,
|
||||
Reduce: reduceInstanceSetFeature[bool],
|
||||
},
|
||||
{
|
||||
Event: feature_v2.InstanceConsoleUseV2UserApi,
|
||||
Reduce: reduceInstanceSetFeature[bool],
|
||||
},
|
||||
{
|
||||
Event: instance.InstanceRemovedEventType,
|
||||
Reduce: reduceInstanceRemovedHelper(InstanceDomainInstanceIDCol),
|
||||
|
@ -35,4 +35,5 @@ func init() {
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, InstanceEnableBackChannelLogout, eventstore.GenericEventMapper[SetEvent[bool]])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, InstanceLoginVersion, eventstore.GenericEventMapper[SetEvent[*feature.LoginV2]])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, InstancePermissionCheckV2, eventstore.GenericEventMapper[SetEvent[bool]])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, InstanceConsoleUseV2UserApi, eventstore.GenericEventMapper[SetEvent[bool]])
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ var (
|
||||
InstanceEnableBackChannelLogout = setEventTypeFromFeature(feature.LevelInstance, feature.KeyEnableBackChannelLogout)
|
||||
InstanceLoginVersion = setEventTypeFromFeature(feature.LevelInstance, feature.KeyLoginV2)
|
||||
InstancePermissionCheckV2 = setEventTypeFromFeature(feature.LevelInstance, feature.KeyPermissionCheckV2)
|
||||
InstanceConsoleUseV2UserApi = setEventTypeFromFeature(feature.LevelInstance, feature.KeyConsoleUseV2UserApi)
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -79,13 +79,6 @@ message SetInstanceFeaturesRequest{
|
||||
description: "If the flag is enabled, you'll be able to terminate a single session from the login UI by providing an id_token with a `sid` claim as id_token_hint on the end_session endpoint. Note that currently all sessions from the same user agent (browser) are terminated in the login UI. Sessions managed through the Session API already allow the termination of single sessions.";
|
||||
}
|
||||
];
|
||||
|
||||
optional bool console_use_v2_user_api = 11 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "true";
|
||||
description: "If this is enabled the console web client will use the new User v2 API for certain calls";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message SetInstanceFeaturesResponse {
|
||||
@ -178,11 +171,4 @@ message GetInstanceFeaturesResponse {
|
||||
description: "If the flag is enabled, you'll be able to terminate a single session from the login UI by providing an id_token with a `sid` claim as id_token_hint on the end_session endpoint. Note that currently all sessions from the same user agent (browser) are terminated in the login UI. Sessions managed through the Session API already allow the termination of single sessions.";
|
||||
}
|
||||
];
|
||||
|
||||
FeatureFlag console_use_v2_user_api = 12 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "true";
|
||||
description: "If this is enabled the console web client will use the new User v2 API for certain calls";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user