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:
parent
d7b7d93533
commit
79dd508485
@ -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,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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 () => {
|
||||
|
Loading…
Reference in New Issue
Block a user