mirror of
https://github.com/Unleash/unleash.git
synced 2025-04-06 01:15:28 +02:00
fix: API improvements aligning the types to our schemas (#4650)
Some of our types in OSS have drifted apart from our OpenAPI schemas. This will help them be aligned again
This commit is contained in:
parent
2b2f5e20fa
commit
c39d815516
@ -20,6 +20,7 @@ import {
|
|||||||
ROOT_PERMISSION_TYPE,
|
ROOT_PERMISSION_TYPE,
|
||||||
} from '../util/constants';
|
} from '../util/constants';
|
||||||
import { Db } from './db';
|
import { Db } from './db';
|
||||||
|
import { IdPermissionRef } from 'lib/services/access-service';
|
||||||
|
|
||||||
const T = {
|
const T = {
|
||||||
ROLE_USER: 'role_user',
|
ROLE_USER: 'role_user',
|
||||||
@ -221,7 +222,7 @@ export class AccessStore implements IAccessStore {
|
|||||||
|
|
||||||
async addEnvironmentPermissionsToRole(
|
async addEnvironmentPermissionsToRole(
|
||||||
role_id: number,
|
role_id: number,
|
||||||
permissions: IPermission[],
|
permissions: IdPermissionRef[],
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const rows = permissions.map((permission) => {
|
const rows = permissions.map((permission) => {
|
||||||
return {
|
return {
|
||||||
|
@ -12,12 +12,29 @@ export const createStrategySchema = {
|
|||||||
description: 'The name of the strategy type. Must be unique.',
|
description: 'The name of the strategy type. Must be unique.',
|
||||||
example: 'my-custom-strategy',
|
example: 'my-custom-strategy',
|
||||||
},
|
},
|
||||||
|
title: {
|
||||||
|
type: 'string',
|
||||||
|
description: 'The title of the strategy',
|
||||||
|
example: 'My awesome strategy',
|
||||||
|
},
|
||||||
description: {
|
description: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: 'A description of the strategy type.',
|
description: 'A description of the strategy type.',
|
||||||
example:
|
example:
|
||||||
'Enable the feature for users who have not logged in before.',
|
'Enable the feature for users who have not logged in before.',
|
||||||
},
|
},
|
||||||
|
editable: {
|
||||||
|
type: 'boolean',
|
||||||
|
description:
|
||||||
|
'Whether the strategy type is editable or not. Defaults to `true`.',
|
||||||
|
example: false,
|
||||||
|
},
|
||||||
|
deprecated: {
|
||||||
|
type: 'boolean',
|
||||||
|
description:
|
||||||
|
'Whether the strategy type is deprecated or not. Defaults to `false`.',
|
||||||
|
example: true,
|
||||||
|
},
|
||||||
parameters: {
|
parameters: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
description:
|
description:
|
||||||
|
@ -238,7 +238,7 @@ class StrategyController extends Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async createStrategy(
|
async createStrategy(
|
||||||
req: IAuthRequest<unknown, CreateStrategySchema>,
|
req: IAuthRequest<unknown, unknown, CreateStrategySchema>,
|
||||||
res: Response<StrategySchema>,
|
res: Response<StrategySchema>,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const userName = extractUsername(req);
|
const userName = extractUsername(req);
|
||||||
|
@ -52,17 +52,22 @@ const PROJECT_ADMIN = [
|
|||||||
permissions.DELETE_FEATURE,
|
permissions.DELETE_FEATURE,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/** @deprecated prefer to use NamePermissionRef */
|
||||||
|
export type IdPermissionRef = Pick<IPermission, 'id' | 'environment'>;
|
||||||
|
export type NamePermissionRef = Pick<IPermission, 'name' | 'environment'>;
|
||||||
|
export type PermissionRef = IdPermissionRef | NamePermissionRef;
|
||||||
|
|
||||||
interface IRoleCreation {
|
interface IRoleCreation {
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description: string;
|
||||||
type?: 'root-custom' | 'custom';
|
type?: 'root-custom' | 'custom';
|
||||||
permissions?: IPermission[];
|
permissions?: PermissionRef[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IRoleValidation {
|
export interface IRoleValidation {
|
||||||
name: string;
|
name: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
permissions?: Pick<IPermission, 'id' | 'environment'>[];
|
permissions?: PermissionRef[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IRoleUpdate {
|
interface IRoleUpdate {
|
||||||
@ -70,7 +75,7 @@ interface IRoleUpdate {
|
|||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description: string;
|
||||||
type?: 'root-custom' | 'custom';
|
type?: 'root-custom' | 'custom';
|
||||||
permissions?: IPermission[];
|
permissions?: PermissionRef[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AccessWithRoles {
|
export interface AccessWithRoles {
|
||||||
@ -627,7 +632,7 @@ export class AccessService {
|
|||||||
if (roleType === CUSTOM_ROOT_ROLE_TYPE) {
|
if (roleType === CUSTOM_ROOT_ROLE_TYPE) {
|
||||||
await this.store.addPermissionsToRole(
|
await this.store.addPermissionsToRole(
|
||||||
newRole.id,
|
newRole.id,
|
||||||
rolePermissions.map(({ name }) => name),
|
rolePermissions.map((p: NamePermissionRef) => p.name),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
await this.store.addEnvironmentPermissionsToRole(
|
await this.store.addEnvironmentPermissionsToRole(
|
||||||
@ -668,7 +673,7 @@ export class AccessService {
|
|||||||
if (roleType === CUSTOM_ROOT_ROLE_TYPE) {
|
if (roleType === CUSTOM_ROOT_ROLE_TYPE) {
|
||||||
await this.store.addPermissionsToRole(
|
await this.store.addPermissionsToRole(
|
||||||
newRole.id,
|
newRole.id,
|
||||||
rolePermissions.map(({ name }) => name),
|
rolePermissions.map((p: NamePermissionRef) => p.name),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
await this.store.addEnvironmentPermissionsToRole(
|
await this.store.addEnvironmentPermissionsToRole(
|
||||||
|
@ -39,6 +39,7 @@ import {
|
|||||||
IProjectRoleUsage,
|
IProjectRoleUsage,
|
||||||
ProjectAccessUserRolesDeleted,
|
ProjectAccessUserRolesDeleted,
|
||||||
IFeatureNaming,
|
IFeatureNaming,
|
||||||
|
CreateProject,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
import { IProjectQuery, IProjectStore } from '../types/stores/project-store';
|
import { IProjectQuery, IProjectStore } from '../types/stores/project-store';
|
||||||
import {
|
import {
|
||||||
@ -190,10 +191,7 @@ export default class ProjectService {
|
|||||||
};
|
};
|
||||||
|
|
||||||
async createProject(
|
async createProject(
|
||||||
newProject: Pick<
|
newProject: CreateProject,
|
||||||
IProject,
|
|
||||||
'id' | 'name' | 'mode' | 'defaultStickiness'
|
|
||||||
>,
|
|
||||||
user: IUser,
|
user: IUser,
|
||||||
): Promise<IProject> {
|
): Promise<IProject> {
|
||||||
const data = await projectSchema.validateAsync(newProject);
|
const data = await projectSchema.validateAsync(newProject);
|
||||||
|
@ -320,6 +320,7 @@ test('should export strategies', async () => {
|
|||||||
await stores.strategyStore.createStrategy({
|
await stores.strategyStore.createStrategy({
|
||||||
name: 'a-strategy',
|
name: 'a-strategy',
|
||||||
editable: true,
|
editable: true,
|
||||||
|
parameters: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
const data = await stateService.export({ includeStrategies: true });
|
const data = await stateService.export({ includeStrategies: true });
|
||||||
@ -595,7 +596,10 @@ test('exporting to new format works', async () => {
|
|||||||
await stores.featureToggleStore.create('fancy', {
|
await stores.featureToggleStore.create('fancy', {
|
||||||
name: 'Some-feature',
|
name: 'Some-feature',
|
||||||
});
|
});
|
||||||
await stores.strategyStore.createStrategy({ name: 'format' });
|
await stores.strategyStore.createStrategy({
|
||||||
|
name: 'format',
|
||||||
|
parameters: [],
|
||||||
|
});
|
||||||
await stores.featureEnvironmentStore.addEnvironmentToFeature(
|
await stores.featureEnvironmentStore.addEnvironmentToFeature(
|
||||||
'Some-feature',
|
'Some-feature',
|
||||||
'dev',
|
'dev',
|
||||||
@ -650,7 +654,10 @@ test('featureStrategies can keep existing', async () => {
|
|||||||
await stores.featureToggleStore.create('fancy', {
|
await stores.featureToggleStore.create('fancy', {
|
||||||
name: 'Some-feature',
|
name: 'Some-feature',
|
||||||
});
|
});
|
||||||
await stores.strategyStore.createStrategy({ name: 'format' });
|
await stores.strategyStore.createStrategy({
|
||||||
|
name: 'format',
|
||||||
|
parameters: [],
|
||||||
|
});
|
||||||
await stores.featureEnvironmentStore.addEnvironmentToFeature(
|
await stores.featureEnvironmentStore.addEnvironmentToFeature(
|
||||||
'Some-feature',
|
'Some-feature',
|
||||||
'dev',
|
'dev',
|
||||||
@ -697,7 +704,10 @@ test('featureStrategies should not keep existing if dropBeforeImport', async ()
|
|||||||
await stores.featureToggleStore.create('fancy', {
|
await stores.featureToggleStore.create('fancy', {
|
||||||
name: 'Some-feature',
|
name: 'Some-feature',
|
||||||
});
|
});
|
||||||
await stores.strategyStore.createStrategy({ name: 'format' });
|
await stores.strategyStore.createStrategy({
|
||||||
|
name: 'format',
|
||||||
|
parameters: [],
|
||||||
|
});
|
||||||
await stores.featureEnvironmentStore.addEnvironmentToFeature(
|
await stores.featureEnvironmentStore.addEnvironmentToFeature(
|
||||||
'Some-feature',
|
'Some-feature',
|
||||||
'dev',
|
'dev',
|
||||||
|
@ -163,6 +163,7 @@ test('counts toggles', async () => {
|
|||||||
await stores.strategyStore.createStrategy({
|
await stores.strategyStore.createStrategy({
|
||||||
name: uuidv4(),
|
name: uuidv4(),
|
||||||
editable: true,
|
editable: true,
|
||||||
|
parameters: [],
|
||||||
});
|
});
|
||||||
const latest = {
|
const latest = {
|
||||||
oss: '4.0.0',
|
oss: '4.0.0',
|
||||||
@ -213,10 +214,12 @@ test('counts custom strategies', async () => {
|
|||||||
await stores.strategyStore.createStrategy({
|
await stores.strategyStore.createStrategy({
|
||||||
name: strategyName,
|
name: strategyName,
|
||||||
editable: true,
|
editable: true,
|
||||||
|
parameters: [],
|
||||||
});
|
});
|
||||||
await stores.strategyStore.createStrategy({
|
await stores.strategyStore.createStrategy({
|
||||||
name: uuidv4(),
|
name: uuidv4(),
|
||||||
editable: true,
|
editable: true,
|
||||||
|
parameters: [],
|
||||||
});
|
});
|
||||||
await stores.featureStrategiesStore.createStrategyFeatureEnv({
|
await stores.featureStrategiesStore.createStrategyFeatureEnv({
|
||||||
featureName: toggleName,
|
featureName: toggleName,
|
||||||
|
@ -402,6 +402,14 @@ export interface IImportData extends ImportCommon {
|
|||||||
data: any;
|
data: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create project aligns with #/components/schemas/createProjectSchema
|
||||||
|
// joi is providing default values when the optional inputs are not provided
|
||||||
|
// const data = await projectSchema.validateAsync(newProject);
|
||||||
|
export type CreateProject = Pick<IProject, 'id' | 'name'> & {
|
||||||
|
mode?: ProjectMode;
|
||||||
|
defaultStickiness?: string;
|
||||||
|
};
|
||||||
|
|
||||||
export interface IProject {
|
export interface IProject {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { PermissionRef } from 'lib/services/access-service';
|
||||||
import { IGroupModelWithProjectRole } from '../group';
|
import { IGroupModelWithProjectRole } from '../group';
|
||||||
import { IPermission, IUserWithRole } from '../model';
|
import { IPermission, IUserWithRole } from '../model';
|
||||||
import { Store } from './store';
|
import { Store } from './store';
|
||||||
@ -100,7 +101,7 @@ export interface IAccessStore extends Store<IRole, number> {
|
|||||||
|
|
||||||
addEnvironmentPermissionsToRole(
|
addEnvironmentPermissionsToRole(
|
||||||
role_id: number,
|
role_id: number,
|
||||||
permissions: IPermission[],
|
permissions: PermissionRef[],
|
||||||
): Promise<void>;
|
): Promise<void>;
|
||||||
|
|
||||||
addUserToRole(
|
addUserToRole(
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { CreateStrategySchema } from 'lib/openapi';
|
||||||
import { Store } from './store';
|
import { Store } from './store';
|
||||||
|
|
||||||
export interface IStrategy {
|
export interface IStrategy {
|
||||||
@ -18,24 +19,22 @@ export interface IEditableStrategy {
|
|||||||
title?: string;
|
title?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IMinimalStrategy {
|
export type IMinimalStrategy = Pick<
|
||||||
name: string;
|
CreateStrategySchema,
|
||||||
description?: string;
|
'name' | 'description' | 'editable' | 'parameters' | 'title'
|
||||||
editable?: boolean;
|
>;
|
||||||
parameters?: any[];
|
|
||||||
title?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IStrategyImport {
|
export type IStrategyImport = Pick<
|
||||||
name: string;
|
CreateStrategySchema,
|
||||||
description?: string;
|
| 'name'
|
||||||
deprecated?: boolean;
|
| 'description'
|
||||||
parameters?: object[];
|
| 'deprecated'
|
||||||
builtIn?: boolean;
|
| 'parameters'
|
||||||
sortOrder?: number;
|
| 'builtIn'
|
||||||
displayName?: string;
|
| 'sortOrder'
|
||||||
title?: string;
|
| 'displayName'
|
||||||
}
|
| 'title'
|
||||||
|
>;
|
||||||
|
|
||||||
export interface IMinimalStrategyRow {
|
export interface IMinimalStrategyRow {
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -801,18 +801,10 @@ test('should add a user to the project with a custom role', async () => {
|
|||||||
description: '',
|
description: '',
|
||||||
permissions: [
|
permissions: [
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2, // CREATE_FEATURE
|
||||||
name: 'CREATE_FEATURE',
|
|
||||||
environment: undefined,
|
|
||||||
displayName: 'Create Feature Toggles',
|
|
||||||
type: 'project',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 8,
|
id: 8, // DELETE_FEATURE
|
||||||
name: 'DELETE_FEATURE',
|
|
||||||
environment: undefined,
|
|
||||||
displayName: 'Delete Feature Toggles',
|
|
||||||
type: 'project',
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
@ -859,18 +851,10 @@ test('should delete role entries when deleting project', async () => {
|
|||||||
description: '',
|
description: '',
|
||||||
permissions: [
|
permissions: [
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2, // CREATE_FEATURE
|
||||||
name: 'CREATE_FEATURE',
|
|
||||||
environment: undefined,
|
|
||||||
displayName: 'Create Feature Toggles',
|
|
||||||
type: 'project',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 8,
|
id: 8, // DELETE_FEATURE
|
||||||
name: 'DELETE_FEATURE',
|
|
||||||
environment: undefined,
|
|
||||||
displayName: 'Delete Feature Toggles',
|
|
||||||
type: 'project',
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
@ -907,18 +891,10 @@ test('should change a users role in the project', async () => {
|
|||||||
description: '',
|
description: '',
|
||||||
permissions: [
|
permissions: [
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2, // CREATE_FEATURE
|
||||||
name: 'CREATE_FEATURE',
|
|
||||||
environment: undefined,
|
|
||||||
displayName: 'Create Feature Toggles',
|
|
||||||
type: 'project',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 8,
|
id: 8, // DELETE_FEATURE
|
||||||
name: 'DELETE_FEATURE',
|
|
||||||
environment: undefined,
|
|
||||||
displayName: 'Delete Feature Toggles',
|
|
||||||
type: 'project',
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
@ -1098,11 +1074,7 @@ test('Should allow bulk update of group permissions', async () => {
|
|||||||
description: '',
|
description: '',
|
||||||
permissions: [
|
permissions: [
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2, // CREATE_FEATURE
|
||||||
name: 'CREATE_FEATURE',
|
|
||||||
environment: undefined,
|
|
||||||
displayName: 'Create Feature Toggles',
|
|
||||||
type: 'project',
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
@ -1129,11 +1101,7 @@ test('Should bulk update of only users', async () => {
|
|||||||
description: '',
|
description: '',
|
||||||
permissions: [
|
permissions: [
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2, // CREATE_FEATURE
|
||||||
name: 'CREATE_FEATURE',
|
|
||||||
environment: undefined,
|
|
||||||
displayName: 'Create Feature Toggles',
|
|
||||||
type: 'project',
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
@ -1168,11 +1136,7 @@ test('Should allow bulk update of only groups', async () => {
|
|||||||
description: '',
|
description: '',
|
||||||
permissions: [
|
permissions: [
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2, // CREATE_FEATURE
|
||||||
name: 'CREATE_FEATURE',
|
|
||||||
environment: undefined,
|
|
||||||
displayName: 'Create Feature Toggles',
|
|
||||||
type: 'project',
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
@ -1221,10 +1185,7 @@ test('Should allow permutations of roles, groups and users when adding a new acc
|
|||||||
description: '',
|
description: '',
|
||||||
permissions: [
|
permissions: [
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2, // CREATE_FEATURE
|
||||||
name: 'CREATE_FEATURE',
|
|
||||||
displayName: 'Create feature toggles',
|
|
||||||
type: 'project',
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
@ -1234,10 +1195,7 @@ test('Should allow permutations of roles, groups and users when adding a new acc
|
|||||||
description: '',
|
description: '',
|
||||||
permissions: [
|
permissions: [
|
||||||
{
|
{
|
||||||
id: 7,
|
id: 7, // UPDATE_FEATURE
|
||||||
name: 'UPDATE_FEATURE',
|
|
||||||
displayName: 'Update feature toggles',
|
|
||||||
type: 'project',
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
3
src/test/fixtures/fake-access-store.ts
vendored
3
src/test/fixtures/fake-access-store.ts
vendored
@ -12,6 +12,7 @@ import {
|
|||||||
import { IPermission } from 'lib/types/model';
|
import { IPermission } from 'lib/types/model';
|
||||||
import { IRoleStore } from 'lib/types';
|
import { IRoleStore } from 'lib/types';
|
||||||
import FakeRoleStore from './fake-role-store';
|
import FakeRoleStore from './fake-role-store';
|
||||||
|
import { PermissionRef } from 'lib/services/access-service';
|
||||||
|
|
||||||
class AccessStoreMock implements IAccessStore {
|
class AccessStoreMock implements IAccessStore {
|
||||||
fakeRolesStore: IRoleStore;
|
fakeRolesStore: IRoleStore;
|
||||||
@ -118,7 +119,7 @@ class AccessStoreMock implements IAccessStore {
|
|||||||
|
|
||||||
addEnvironmentPermissionsToRole(
|
addEnvironmentPermissionsToRole(
|
||||||
role_id: number,
|
role_id: number,
|
||||||
permissions: IPermission[],
|
permissions: PermissionRef[],
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
return Promise.resolve(undefined);
|
return Promise.resolve(undefined);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user