Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 5 additions & 77 deletions src/helpers/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { BadRequestError, PermissionError } from '../exceptions';
import { EnvType } from '../models/environment';
import { ActionTypes, RouterTypes } from '../models/permission';
import { getDomainById } from '../services/domain';
import { getEnvironments } from '../services/environment';
import { getTeams } from '../services/team';
import { getPermission, getPermissions } from '../services/permission';
import { verifyPermissions, verifyPermissionsCascade } from './permission';

export async function checkEnvironmentStatusRemoval(domainId, environmentName, strategy = false) {
const environment = await getEnvironments({ domain: domainId }, ['_id', 'name']);
Expand Down Expand Up @@ -41,6 +40,10 @@ export function parseJSON(str) {
}
}

export function containsValue(arr, value) {
return arr?.filter(item => item.match(value)).length > 0;
}

export function formatInput(input,
options = {
toUpper: false,
Expand Down Expand Up @@ -105,79 +108,4 @@ export async function verifyOwnership(admin, element, domainId, action, routerTy
}

return element;
}

async function verifyPermissions(team, element, action, routerType) {
const permission = await getPermission({
_id: { $in: team.permissions },
action: { $in: [action, ActionTypes.ALL] },
active: true,
router: { $in: [routerType, RouterTypes.ALL] }
});

if (permission) {
return verifyIdentifiers(permission, element);
} else {
throw new PermissionError(`Permission not found for this operation: '${action}' - '${routerType}'`);
}
}

async function verifyPermissionsCascade(team, element, action, routerType) {
let orStatement = [];
if (routerType === RouterTypes.DOMAIN) {
orStatement = [
{ router: routerType },
{ router: RouterTypes.GROUP },
{ router: RouterTypes.CONFIG },
{ router: RouterTypes.STRATEGY },
{ router: RouterTypes.ALL }
];
} else if (routerType === RouterTypes.GROUP) {
orStatement = [
{ router: routerType },
{ router: RouterTypes.CONFIG },
{ router: RouterTypes.STRATEGY },
{ router: RouterTypes.ALL }
];
} else if (routerType === RouterTypes.CONFIG || routerType === RouterTypes.STRATEGY) {
orStatement = [
{ router: routerType },
{ router: RouterTypes.STRATEGY },
{ router: RouterTypes.ALL }
];
}

const foundPermission = await getPermissions({
_id: { $in: team.permissions },
action: { $in: [action, ActionTypes.ALL] },
active: true,
$or: orStatement
});

const matchedPermission = foundPermission.filter(value => value.router === routerType);
if (matchedPermission.length) {
return verifyIdentifiers(matchedPermission[0], element);
} else if (foundPermission[0]) {
return element;
}
}

function verifyIdentifiers(permission, element) {
if (permission.identifiedBy) {
if (Array.isArray(element)) {
if (permission.values.length) {
element = element.filter(child => permission.values.includes(child[`${permission.identifiedBy}`]));
if (element.length) {
return element;
}
}
} else {
if (permission.values.includes(element[`${permission.identifiedBy}`])) {
return element;
}
}
} else {
return element;
}
throw new PermissionError('It was not possible to match the requiring element to the current permission');
}
78 changes: 78 additions & 0 deletions src/helpers/permission.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { PermissionError } from '../exceptions';
import { ActionTypes, RouterTypes } from '../models/permission';
import { getPermission, getPermissions } from '../services/permission';

export async function verifyPermissions(team, element, action, routerType) {
const permission = await getPermission({
_id: { $in: team.permissions },
action: { $in: [action, ActionTypes.ALL] },
active: true,
router: { $in: [routerType, RouterTypes.ALL] }
});

if (permission) {
return verifyIdentifiers(permission, element);
} else {
throw new PermissionError(`Permission not found for this operation: '${action}' - '${routerType}'`);
}
}

export async function verifyPermissionsCascade(team, element, action, routerType) {
let orStatement = [];
if (routerType === RouterTypes.DOMAIN) {
orStatement = [
{ router: routerType },
{ router: RouterTypes.GROUP },
{ router: RouterTypes.CONFIG },
{ router: RouterTypes.STRATEGY },
{ router: RouterTypes.ALL }
];
} else if (routerType === RouterTypes.GROUP) {
orStatement = [
{ router: routerType },
{ router: RouterTypes.CONFIG },
{ router: RouterTypes.STRATEGY },
{ router: RouterTypes.ALL }
];
} else if (routerType === RouterTypes.CONFIG || routerType === RouterTypes.STRATEGY) {
orStatement = [
{ router: routerType },
{ router: RouterTypes.STRATEGY },
{ router: RouterTypes.ALL }
];
}

const foundPermission = await getPermissions({
_id: { $in: team.permissions },
action: { $in: [action, ActionTypes.ALL] },
active: true,
$or: orStatement
});

const matchedPermission = foundPermission.filter(value => value.router === routerType);
if (matchedPermission.length) {
return verifyIdentifiers(matchedPermission[0], element);
} else if (foundPermission[0]) {
return element;
}
}

function verifyIdentifiers(permission, element) {
if (permission.identifiedBy) {
if (Array.isArray(element)) {
if (permission.values.length) {
element = element.filter(child => permission.values.includes(child[`${permission.identifiedBy}`]));
if (element.length) {
return element;
}
}
} else {
if (permission.values.includes(element[`${permission.identifiedBy}`])) {
return element;
}
}
} else {
return element;
}
throw new PermissionError('It was not possible to match the requiring element to the current permission');
}
5 changes: 3 additions & 2 deletions src/services/slack.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { getConfig } from './config';
import { getDomainById } from './domain';
import { getEnvironment } from './environment';
import { getGroupConfig } from './group-config';
import { containsValue } from '../helpers';

/**
* Validates if ticket already exists, if so, return it.
Expand Down Expand Up @@ -160,10 +161,10 @@ export async function validateTicket(ticket_content, enterprise_id, team_id) {
const ticket = await canCreateTicket(slack, ticket_content);
const { ignored_environments, frozen_environments } = slack.settings;

if (frozen_environments?.includes(ticket_content.environment))
if (containsValue(frozen_environments, ticket_content.environment))
return { result: TicketValidationType.FROZEN_ENVIRONMENT };

if (ignored_environments?.includes(ticket_content.environment)) {
if (containsValue(ignored_environments, ticket_content.environment)) {
await approveChange(slack.domain, ticket_content);
return { result: TicketValidationType.IGNORED_ENVIRONMENT };
}
Expand Down
71 changes: 71 additions & 0 deletions tests/unit-test/helpers.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
const { formatInput, containsValue } = require('../../src/helpers');

describe('Test formatInput', () => {

test('Should return error - Non alphanumeric input', () => {
try {
formatInput('Spaces are not allowed here');
} catch (e) {
expect(e.message).toBe('Invalid input format. Use only alphanumeric digits.');
}
});

test('Should NOT return error - Spaces allowed', () => {
try {
const input = formatInput('Spaces are not allowed here', { allowSpace: true });
expect(input).toBe('Spaces are not allowed here');
} catch (e) {
expect(e.message).toBe(null);
}
});

test('Should format input - To upper case', () => {
const input = formatInput('uppercaseme', { toUpper: true });
expect(input).toBe('UPPERCASEME');
});

test('Should format input - To lower case', () => {
const input = formatInput('UPPERCASEME', { toLower: true });
expect(input).toBe('uppercaseme');
});

test('Should format input - Replace spaces for underscore', () => {
const input = formatInput('NEW SCORE', { autoUnderscore: true });
expect(input).toBe('NEW_SCORE');
});

});

describe('Test containsValue', () => {

test('Should return true when value exists in array', () => {
const result = containsValue(['value1', 'value2'], 'value1');
expect(result).toBeTruthy();
});

test('Should return false when value does not exist in array', () => {
const result = containsValue(['value1', 'value2'], 'value3');
expect(result).toBeFalsy();
});

test('Should return true when partial value exists in array', () => {
const result = containsValue(['value1', 'value2'], 'value');
expect(result).toBeTruthy();
});

test('Should return false for case sensitive values', () => {
const result = containsValue(['value1', 'value2'], 'Value1');
expect(result).toBeFalsy();
});

test('Should return false when array is empty', () => {
const result = containsValue([], 'value1');
expect(result).toBeFalsy();
});

test('Should return false when array is undefined', () => {
const result = containsValue(undefined, 'value1');
expect(result).toBeFalsy();
});

});
37 changes: 0 additions & 37 deletions tests/unit-test/router-index.test.js

This file was deleted.