2021-03-11 22:51:58 +01:00
|
|
|
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
|
|
|
import {
|
|
|
|
CREATE_FEATURE,
|
|
|
|
DELETE_FEATURE,
|
|
|
|
ADMIN,
|
2021-11-04 21:24:55 +01:00
|
|
|
UPDATE_FEATURE,
|
2021-05-02 20:58:02 +02:00
|
|
|
} from '../types/permissions';
|
2021-04-22 10:07:10 +02:00
|
|
|
import { IUnleashConfig } from '../types/option';
|
|
|
|
import { IUnleashStores } from '../types/stores';
|
2021-04-22 23:40:52 +02:00
|
|
|
import User from '../types/user';
|
2021-03-11 22:51:58 +01:00
|
|
|
|
2021-04-22 10:07:10 +02:00
|
|
|
interface PermissionChecker {
|
|
|
|
hasPermission(
|
|
|
|
user: User,
|
|
|
|
permission: string,
|
|
|
|
projectId?: string,
|
2022-01-13 11:14:17 +01:00
|
|
|
environment?: string,
|
2021-04-22 10:07:10 +02:00
|
|
|
): Promise<boolean>;
|
|
|
|
}
|
|
|
|
|
|
|
|
const rbacMiddleware = (
|
|
|
|
config: Pick<IUnleashConfig, 'getLogger'>,
|
|
|
|
{ featureToggleStore }: Pick<IUnleashStores, 'featureToggleStore'>,
|
|
|
|
accessService: PermissionChecker,
|
|
|
|
): any => {
|
2021-09-15 20:28:10 +02:00
|
|
|
const logger = config.getLogger('/middleware/rbac-middleware.ts');
|
|
|
|
logger.debug('Enabling RBAC middleware');
|
2021-03-11 22:51:58 +01:00
|
|
|
|
|
|
|
return (req, res, next) => {
|
|
|
|
req.checkRbac = async (permission: string) => {
|
|
|
|
const { user, params } = req;
|
|
|
|
|
|
|
|
if (!user) {
|
|
|
|
logger.error('RBAC requires a user to exist on the request.');
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (user.isAPI) {
|
|
|
|
return user.permissions.includes(ADMIN);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!user.id) {
|
|
|
|
logger.error('RBAC requires the user to have a unique id.');
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// For /api/admin/projects/:projectId we will find it as part of params
|
2022-01-13 11:14:17 +01:00
|
|
|
let { projectId, environment } = params;
|
2021-03-11 22:51:58 +01:00
|
|
|
|
2021-05-05 22:32:25 +02:00
|
|
|
// Temporary workaround to figure out projectId for feature toggle updates.
|
2021-11-04 21:24:55 +01:00
|
|
|
// will be removed in Unleash v5.0
|
|
|
|
if ([DELETE_FEATURE, UPDATE_FEATURE].includes(permission)) {
|
2021-05-05 22:32:25 +02:00
|
|
|
const { featureName } = params;
|
|
|
|
projectId = await featureToggleStore.getProjectId(featureName);
|
2021-03-11 22:51:58 +01:00
|
|
|
} else if (permission === CREATE_FEATURE) {
|
2021-04-12 20:25:03 +02:00
|
|
|
projectId = req.body.project || 'default';
|
2021-03-11 22:51:58 +01:00
|
|
|
}
|
|
|
|
|
2022-01-13 11:14:17 +01:00
|
|
|
return accessService.hasPermission(
|
|
|
|
user,
|
|
|
|
permission,
|
|
|
|
projectId,
|
|
|
|
environment,
|
|
|
|
);
|
2021-03-11 22:51:58 +01:00
|
|
|
};
|
|
|
|
return next();
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
export default rbacMiddleware;
|