1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-09-05 17:53:12 +02:00

feat: Schema validation for roles

This commit is contained in:
sighphyre 2022-01-07 11:10:48 +02:00 committed by Ivar Conradi Østhus
parent 5abe99f431
commit 95b50acdd8
No known key found for this signature in database
GPG Key ID: 31AC596886B0BD09
5 changed files with 116 additions and 7 deletions

View File

@ -0,0 +1,83 @@
import { roleSchema } from './role-schema';
test('role schema rejects a role without a name', async () => {
expect.assertions(1);
const role = {
permissions: [],
};
try {
await roleSchema.validateAsync(role);
} catch (error) {
expect(error.details[0].message).toBe('"name" is required');
}
});
test('role schema allows a role with an empty description', async () => {
const role = {
name: 'Brønsted',
description: '',
};
const value = await roleSchema.validateAsync(role);
expect(value.description).toEqual('');
});
test('role schema rejects a role with a broken permission list', async () => {
expect.assertions(1);
const role = {
name: 'Mendeleev',
permissions: [
{
aPropertyThatIsAproposToNothing: true,
},
],
};
try {
await roleSchema.validateAsync(role);
} catch (error) {
expect(error.details[0].message).toBe(
'"permissions[0].id" is required',
);
}
});
test('role schema allows a role with an empty permission list', async () => {
const role = {
name: 'Avogadro',
permissions: [],
};
const value = await roleSchema.validateAsync(role);
expect(value.permissions).toEqual([]);
});
test('role schema allows a role with a null list', async () => {
const role = {
name: 'Curie',
permissions: null,
};
const value = await roleSchema.validateAsync(role);
expect(value.permissions).toEqual(null);
});
test('role schema allows an undefined with a null list', async () => {
const role = {
name: 'Fischer',
};
const value = await roleSchema.validateAsync(role);
expect(value.permissions).toEqual(undefined);
});
test('role schema strips roleType if present', async () => {
const role = {
name: 'Grignard',
roleType: 'Organic Chemistry',
};
const value = await roleSchema.validateAsync(role);
expect(value.roleType).toEqual(undefined);
});

View File

@ -0,0 +1,22 @@
import joi from 'joi';
export const permissionRoleSchema = joi
.object()
.keys({
id: joi.number().required(),
enivronment: joi.string().allow(null).optional(),
})
.options({ stripUnknown: true, allowUnknown: false, abortEarly: false });
export const roleSchema = joi
.object()
.keys({
name: joi.string().required(),
description: joi.string().optional().allow('').allow(null).default(''),
permissions: joi
.array()
.allow(null)
.optional()
.items(permissionRoleSchema),
})
.options({ stripUnknown: true, allowUnknown: false, abortEarly: false });

View File

@ -23,6 +23,8 @@ import { IRoleStore } from 'lib/types/stores/role-store';
import NameExistsError from '../error/name-exists-error';
import { IEnvironmentStore } from 'lib/types/stores/environment-store';
import RoleInUseError from '../error/role-in-use-error';
import { roleSchema } from '../schema/role-schema';
import { CUSTOM_ROLE_TYPE } from '../util/constants';
export const ALL_PROJECTS = '*';
export const ALL_ENVS = '*';
@ -386,12 +388,11 @@ export class AccessService {
}
async createRole(role: IRoleCreation): Promise<ICustomRole> {
await this.validateRole(role);
const baseRole = {
name: role.name,
description: role.description,
roleType: 'custom',
...(await this.validateRole(role)),
roleType: CUSTOM_ROLE_TYPE,
};
const rolePermissions = role.permissions;
const newRole = await this.roleStore.create(baseRole);
if (rolePermissions) {
@ -451,8 +452,9 @@ export class AccessService {
async validateRole(
role: IRoleCreation,
existingId?: number,
): Promise<void> {
): Promise<IRoleCreation> {
const cleanedRole = await roleSchema.validateAsync(role);
await this.validateRoleIsUnique(role.name, existingId);
//Handle schema validation here...
return cleanedRole;
}
}

View File

@ -3,3 +3,5 @@ export const DEFAULT_ENV = 'default';
export const ROOT_PERMISSION_TYPE = 'root';
export const ENVIRONMENT_PERMISSION_TYPE = 'environment';
export const PROJECT_PERMISSION_TYPE = 'project';
export const CUSTOM_ROLE_TYPE = 'custom';

View File

@ -167,7 +167,7 @@ exports.up = function (db, cb) {
p.id as permission_id,
'*' environment
FROM permissions p
WHERE p.permission = 'ADMIN'
WHERE p.permission = 'ADMIN';
`,
cb,
);