1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-01-20 00:08:02 +01:00

fix: project tokens can now be created with the correct permissions (#4165)

This commit is contained in:
Simon Hornby 2023-07-06 15:47:03 +02:00 committed by GitHub
parent d7b7d93533
commit 79dd508485
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 70 additions and 6 deletions

View File

@ -7,6 +7,7 @@ import {
ADMIN,
CREATE_FRONTEND_API_TOKEN,
CREATE_CLIENT_API_TOKEN,
CREATE_PROJECT_API_TOKEN,
} from '@server/types/permissions';
import { useHasRootAccess } from 'hooks/useHasAccess';
import { SelectOption } from './TokenTypeSelector/TokenTypeSelector';
@ -17,17 +18,28 @@ export const useApiTokenForm = (project?: string) => {
const { uiConfig } = useUiConfig();
const initialEnvironment = environments?.find(e => e.enabled)?.name;
const hasCreateTokenPermission = useHasRootAccess(CREATE_CLIENT_API_TOKEN);
const hasCreateProjectTokenPermission = useHasRootAccess(
CREATE_PROJECT_API_TOKEN,
project
);
const apiTokenTypes: SelectOption[] = [
{
key: TokenType.CLIENT,
label: `Server-side SDK (${TokenType.CLIENT})`,
title: 'Connect server-side SDK or Unleash Proxy',
enabled: useHasRootAccess(CREATE_CLIENT_API_TOKEN),
enabled:
hasCreateTokenPermission || hasCreateProjectTokenPermission,
},
];
const hasAdminAccess = useHasRootAccess(ADMIN);
const hasCreateFrontendAccess = useHasRootAccess(CREATE_FRONTEND_API_TOKEN);
const hasCreateFrontendTokenAccess = useHasRootAccess(
CREATE_PROJECT_API_TOKEN,
project
);
if (!project) {
apiTokenTypes.push({
key: TokenType.ADMIN,
@ -42,7 +54,7 @@ export const useApiTokenForm = (project?: string) => {
key: TokenType.FRONTEND,
label: `Client-side SDK (${TokenType.FRONTEND})`,
title: 'Connect web and mobile SDK directly to Unleash',
enabled: hasCreateFrontendAccess,
enabled: hasCreateFrontendAccess || hasCreateFrontendTokenAccess,
});
}

View File

@ -34,7 +34,6 @@ import { Response } from 'express';
import { timingSafeEqual } from 'crypto';
import { createApiToken } from '../../../schema/api-token-schema';
import { OperationDeniedError } from '../../../error';
import { tokenTypeToCreatePermission } from '../api-token';
interface ProjectTokenParam {
token: string;
@ -159,9 +158,7 @@ export class ProjectApiTokenController extends Controller {
): Promise<any> {
const createToken = await createApiToken.validateAsync(req.body);
const { projectId } = req.params;
const permissionRequired = tokenTypeToCreatePermission(
createToken.type,
);
const permissionRequired = CREATE_PROJECT_API_TOKEN;
const hasPermission = await this.accessService.hasPermission(
req.user,
permissionRequired,

View File

@ -5,6 +5,7 @@ import { ApiTokenType } from '../../../../lib/types/models/api-token';
import { RoleName } from '../../../../lib/types/model';
import {
CREATE_CLIENT_API_TOKEN,
CREATE_PROJECT_API_TOKEN,
DELETE_CLIENT_API_TOKEN,
READ_CLIENT_API_TOKEN,
READ_FRONTEND_API_TOKEN,
@ -171,6 +172,60 @@ test('Token-admin should be allowed to create token', async () => {
await destroy();
});
test('A role with only CREATE_PROJECT_API_TOKEN can create project tokens', async () => {
expect.assertions(0);
const preHook = (app, config, { userService, accessService }) => {
app.use('/api/admin/', async (req, res, next) => {
const role = await accessService.getRootRole(RoleName.VIEWER);
const user = await userService.createUser({
email: 'powerpuffgirls_viewer@example.com',
rootRole: role.id,
});
req.user = user;
const createClientApiTokenRole = await accessService.createRole({
name: 'project_client_token_creator',
description: 'Can create client tokens',
permissions: [],
type: 'root-custom',
});
await accessService.addPermissionToRole(
role.id,
CREATE_PROJECT_API_TOKEN,
);
await accessService.addUserToRole(
user.id,
createClientApiTokenRole.id,
'default',
);
req.user = await userService.createUser({
email: 'someguyinplaces@example.com',
rootRole: role.id,
});
next();
});
};
const { request, destroy } = await setupAppWithCustomAuth(stores, preHook, {
experimental: {
flags: {
customRootRoles: true,
},
},
});
await request
.post('/api/admin/projects/default/api-tokens')
.send({
username: 'client-token-maker',
type: 'client',
projects: ['default'],
})
.set('Content-Type', 'application/json')
.expect(201);
await destroy();
});
describe('Fine grained API token permissions', () => {
describe('A role with access to CREATE_CLIENT_API_TOKEN', () => {
test('should be allowed to create client tokens', async () => {