Skip to content

Commit

Permalink
feat: Remove create admin token from API (#9090)
Browse files Browse the repository at this point in the history
Admin tokens have been [deprecated in previous
versions](https://docs.getunleash.io/reference/api-tokens-and-client-keys#admin-tokens)
encouraging the usage of personal access tokens for better traceability
of changes within Unleash.

This removes the ability of creating them from the API
  • Loading branch information
gastonfournier authored Jan 13, 2025
1 parent ce73190 commit fea3d89
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 125 deletions.
2 changes: 1 addition & 1 deletion src/lib/types/experimental.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ const flags: IFlags = {
),
adminTokenKillSwitch: parseEnvVarBoolean(
process.env.UNLEASH_EXPERIMENTAL_ADMIN_TOKEN_KILL_SWITCH,
false,
true,
),
outdatedSdksBanner: parseEnvVarBoolean(
process.env.UNLEASH_EXPERIMENTAL_OUTDATED_SDKS_BANNER,
Expand Down
15 changes: 4 additions & 11 deletions src/test/e2e/api/admin/api-token.auth.e2e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import getLogger from '../../../fixtures/no-logger';
import { ApiTokenType } from '../../../../lib/types/models/api-token';
import { RoleName } from '../../../../lib/types/model';
import {
ADMIN_TOKEN_USER,
CREATE_CLIENT_API_TOKEN,
CREATE_PROJECT_API_TOKEN,
DELETE_CLIENT_API_TOKEN,
Expand Down Expand Up @@ -195,7 +194,7 @@ test('Only token-admins should be allowed to create token', async () => {
await destroy();
});

test('Token-admin should be allowed to create token', async () => {
test('Token-admin should not be allowed to create token', async () => {
expect.assertions(0);

const preHook = (app, config, { userService, accessService }) => {
Expand Down Expand Up @@ -223,14 +222,12 @@ test('Token-admin should be allowed to create token', async () => {
type: 'admin',
})
.set('Content-Type', 'application/json')
.expect(201);
.expect(403);

await destroy();
});

test('An admin token should be allowed to create a token', async () => {
expect.assertions(2);

test('An admin should be forbidden to create an admin token', async () => {
const { request, destroy, services } = await setupAppWithAuth(
stores,
undefined,
Expand All @@ -256,11 +253,7 @@ test('An admin token should be allowed to create a token', async () => {
})
.set('Authorization', secret)
.set('Content-Type', 'application/json')
.expect(201);

const event = await getLastEvent();
expect(event.createdBy).toBe('default-admin');
expect(event.createdByUserId).toBe(ADMIN_TOKEN_USER.id);
.expect(403);
await destroy();
});

Expand Down
113 changes: 0 additions & 113 deletions src/test/e2e/api/admin/api-token.e2e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,62 +65,6 @@ test('creates new client token', async () => {
});
});

test('creates new admin token', async () => {
return app.request
.post('/api/admin/api-tokens')
.send({
username: 'default-admin',
type: 'admin',
})
.set('Content-Type', 'application/json')
.expect(201)
.expect((res) => {
expect(res.body.username).toBe('default-admin');
expect(res.body.tokenName).toBe(res.body.username);
expect(res.body.type).toBe('admin');
expect(res.body.environment).toBe(ALL);
expect(res.body.createdAt).toBeTruthy();
expect(res.body.expiresAt).toBeFalsy();
expect(res.body.secret.length > 16).toBe(true);
});
});

test('creates new ADMIN token should fix casing', async () => {
return app.request
.post('/api/admin/api-tokens')
.send({
username: 'default-admin',
type: 'ADMIN',
})
.set('Content-Type', 'application/json')
.expect(201)
.expect((res) => {
expect(res.body.username).toBe('default-admin');
expect(res.body.tokenName).toBe(res.body.username);
expect(res.body.type).toBe('admin');
expect(res.body.createdAt).toBeTruthy();
expect(res.body.expiresAt).toBeFalsy();
expect(res.body.secret.length > 16).toBe(true);
});
});

test('creates new admin token with expiry', async () => {
const expiresAt = new Date();
const expiresAtAsISOStr = JSON.parse(JSON.stringify(expiresAt));
return app.request
.post('/api/admin/api-tokens')
.send({
username: 'default-admin',
type: 'admin',
expiresAt,
})
.set('Content-Type', 'application/json')
.expect(201)
.expect((res) => {
expect(res.body.expiresAt).toBe(expiresAtAsISOStr);
});
});

test('update client token with expiry', async () => {
const tokenSecret = '*:environment.random-secret-update';

Expand Down Expand Up @@ -312,32 +256,6 @@ test('should not create token for invalid environment', async () => {
});
});

test('should not create token for invalid project & environment', async () => {
return app.request
.post('/api/admin/api-tokens')
.send({
username: 'default-admin',
type: 'admin',
project: 'bogus-project-something',
environment: 'bogus-environment-something',
})
.set('Content-Type', 'application/json')
.expect(400);
});

test('admin token only supports ALL projects', async () => {
return app.request
.post('/api/admin/api-tokens')
.send({
username: 'default-admin',
type: 'admin',
project: 'default',
environment: '*',
})
.set('Content-Type', 'application/json')
.expect(400);
});

test('needs one of the username and tokenName properties set', async () => {
return app.request
.post('/api/admin/api-tokens')
Expand All @@ -349,24 +267,6 @@ test('needs one of the username and tokenName properties set', async () => {
.expect(400);
});

test('can create with tokenName only', async () => {
return app.request
.post('/api/admin/api-tokens')
.send({
tokenName: 'default-admin',
type: 'admin',
environment: '*',
})
.set('Content-Type', 'application/json')
.expect(201)
.expect((res) => {
expect(res.body.type).toBe('admin');
expect(res.body.secret.length > 16).toBe(true);
expect(res.body.username).toBe('default-admin');
expect(res.body.tokenName).toBe('default-admin');
});
});

test('only one of tokenName and username can be set', async () => {
return app.request
.post('/api/admin/api-tokens')
Expand All @@ -380,19 +280,6 @@ test('only one of tokenName and username can be set', async () => {
.expect(400);
});

test('admin token only supports ALL environments', async () => {
return app.request
.post('/api/admin/api-tokens')
.send({
username: 'default-admin',
type: 'admin',
project: '*',
environment: DEFAULT_ENV,
})
.set('Content-Type', 'application/json')
.expect(400);
});

test('client tokens cannot span all environments', async () => {
return app.request
.post('/api/admin/api-tokens')
Expand Down

0 comments on commit fea3d89

Please sign in to comment.