1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-01-25 00:07:47 +01:00

feat(cjux-278): maintenance root roles (#8875)

Custom root roles for changing maintenance mode state and banners.

Internal ticket: CJUX-278
This commit is contained in:
Tymoteusz Czech 2024-12-10 15:22:46 +01:00 committed by GitHub
parent c860d8e434
commit 5cc0e589e8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 48 additions and 9 deletions

View File

@ -3,6 +3,7 @@ import { PermissionGuard } from 'component/common/PermissionGuard/PermissionGuar
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { PremiumFeature } from 'component/common/PremiumFeature/PremiumFeature';
import { BannersTable } from './BannersTable/BannersTable';
import { UPDATE_INSTANCE_BANNERS } from '@server/types/permissions';
export const Banners = () => {
const { isEnterprise } = useUiConfig();
@ -13,7 +14,7 @@ export const Banners = () => {
return (
<div>
<PermissionGuard permissions={ADMIN}>
<PermissionGuard permissions={[ADMIN, UPDATE_INSTANCE_BANNERS]}>
<BannersTable />
</PermissionGuard>
</div>

View File

@ -6,10 +6,11 @@ import { Box, styled } from '@mui/material';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { MaintenanceTooltip } from './MaintenanceTooltip';
import { MaintenanceToggle } from './MaintenanceToggle';
import { UPDATE_MAINTENANCE_MODE } from '@server/types/permissions';
export const MaintenanceAdmin = () => (
<div>
<PermissionGuard permissions={ADMIN}>
<PermissionGuard permissions={[ADMIN, UPDATE_MAINTENANCE_MODE]}>
<MaintenancePage />
</PermissionGuard>
</div>

View File

@ -42,6 +42,9 @@ export const RolePermissionCategories = ({
});
const releasePlansEnabled = useUiFlag('releasePlans');
const granularAdminPermissionsEnabled = useUiFlag(
'granularAdminPermissions',
);
const isProjectRole = PROJECT_ROLE_TYPES.includes(type);
@ -85,10 +88,15 @@ export const RolePermissionCategories = ({
releasePlansEnabled ||
label !== 'Release plan templates',
)
.filter(
({ label }) =>
granularAdminPermissionsEnabled ||
label !== 'Instance maintenance',
)
.map(({ label, type, permissions }) => (
<RolePermissionCategory
key={label}
title={`${label} permissions`}
title={label}
context={label.toLowerCase()}
Icon={
type === PROJECT_PERMISSION_TYPE ? (

View File

@ -5,6 +5,7 @@ import {
} from './useAuthEndpoint';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import type { IUiConfig } from 'interfaces/uiConfig';
import { MAINTENANCE_MODE_PERMISSIONS } from '@server/types/permissions';
interface IUseAuthPermissionsOutput {
permissions?: IPermission[];
@ -22,8 +23,8 @@ const getPermissions = (
? auth.data.permissions
: undefined;
if (permissions && uiConfig?.maintenanceMode) {
permissions = permissions.filter(
(permission) => permission.permission === 'ADMIN',
permissions = permissions.filter((permission) =>
MAINTENANCE_MODE_PERMISSIONS.includes(permission.permission),
);
}
return permissions;

View File

@ -94,6 +94,7 @@ export type UiFlags = {
showUserDeviceCount?: boolean;
flagOverviewRedesign?: boolean;
licensedUsers?: boolean;
granularAdminPermissions?: boolean;
};
export interface IVersionInfo {

View File

@ -1,4 +1,9 @@
import { ADMIN, type IUnleashConfig, type IUnleashServices } from '../../types';
import {
ADMIN,
UPDATE_MAINTENANCE_MODE,
type IUnleashConfig,
type IUnleashServices,
} from '../../types';
import type { Request, Response } from 'express';
import Controller from '../../routes/controller';
import type { Logger } from '../../logger';
@ -38,7 +43,7 @@ export default class MaintenanceController extends Controller {
this.route({
method: 'post',
path: '',
permission: ADMIN,
permission: [ADMIN, UPDATE_MAINTENANCE_MODE],
handler: this.toggleMaintenance,
middleware: [
this.openApiService.validPath({
@ -58,7 +63,7 @@ export default class MaintenanceController extends Controller {
this.route({
method: 'get',
path: '',
permission: ADMIN,
permission: [ADMIN, UPDATE_MAINTENANCE_MODE],
handler: this.getMaintenance,
middleware: [
this.openApiService.validPath({

View File

@ -60,6 +60,7 @@ export type IFlagKey =
| 'deleteStaleUserSessions'
| 'memorizeStats'
| 'licensedUsers'
| 'granularAdminPermissions'
| 'streaming'
| 'etagVariant'
| 'oidcRedirect';
@ -282,6 +283,10 @@ const flags: IFlags = {
process.env.UNLEASH_EXPERIMENTAL_FLAG_LICENSED_USERS,
false,
),
granularAdminPermissions: parseEnvVarBoolean(
process.env.UNLEASH_EXPERIMENTAL_GRANULAR_ADMIN_PERMISSIONS,
false,
),
streaming: parseEnvVarBoolean(
process.env.UNLEASH_EXPERIMENTAL_STREAMING,
false,

View File

@ -41,6 +41,9 @@ export const CREATE_TAG_TYPE = 'CREATE_TAG_TYPE';
export const UPDATE_TAG_TYPE = 'UPDATE_TAG_TYPE';
export const DELETE_TAG_TYPE = 'DELETE_TAG_TYPE';
export const UPDATE_MAINTENANCE_MODE = 'UPDATE_MAINTENANCE_MODE';
export const UPDATE_INSTANCE_BANNERS = 'UPDATE_INSTANCE_BANNERS';
// Project
export const CREATE_FEATURE = 'CREATE_FEATURE';
export const UPDATE_FEATURE = 'UPDATE_FEATURE';
@ -83,7 +86,7 @@ export const RELEASE_PLAN_TEMPLATE_DELETE = 'RELEASE_PLAN_TEMPLATE_DELETE';
export const ROOT_PERMISSION_CATEGORIES = [
{
label: 'Addon',
label: 'Integration',
permissions: [CREATE_ADDON, UPDATE_ADDON, DELETE_ADDON],
},
{
@ -141,4 +144,17 @@ export const ROOT_PERMISSION_CATEGORIES = [
RELEASE_PLAN_TEMPLATE_UPDATE,
],
},
{
label: 'Instance maintenance',
permissions: [UPDATE_MAINTENANCE_MODE, UPDATE_INSTANCE_BANNERS],
},
];
// Used on Frontend, to allow admin panel use for users with custom root roles
export const MAINTENANCE_MODE_PERMISSIONS = [
ADMIN,
READ_ROLE,
READ_CLIENT_API_TOKEN,
READ_FRONTEND_API_TOKEN,
UPDATE_MAINTENANCE_MODE,
];

View File

@ -57,6 +57,7 @@ process.nextTick(async () => {
showUserDeviceCount: true,
flagOverviewRedesign: false,
licensedUsers: true,
granularAdminPermissions: true,
},
},
authentication: {