Skip to content

Commit

Permalink
Merge pull request #542 from curveball/access-token-privilege
Browse files Browse the repository at this point in the history
Generating arbitrary access-tokens is now behind a special privilege.
  • Loading branch information
evert authored Oct 28, 2024
2 parents d600e97 + 8f99784 commit 5b30623
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 8 deletions.
18 changes: 18 additions & 0 deletions src/migrations/20241027202400_new_privileges.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Knex } from 'knex';

const privilege = 'a12n:access-token:generate';

export async function up(knex: Knex): Promise<void> {
await knex('privileges')
.insert({privilege, description: 'Allows a user to create a valid access-token for another user without consent. This privilege allows full control of other accounts and should never be given to third parties.'});

}

export async function down(knex: Knex): Promise<void> {

await knex('privileges')
.delete()
.whereIn('privileges', [privilege]);

}

4 changes: 2 additions & 2 deletions src/oauth2/controller/user-access-token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ class UserAccessTokenController extends Controller {
const principalService = new PrincipalService(ctx.privileges);
const user = await principalService.findByExternalId(ctx.params.id, 'user');

if (ctx.auth.equals(user) && !ctx.privileges.has('admin')) {
throw new Forbidden('You can only generate OAuth2 access tokens for yourself with this endpoint (unless you have the \'admin\' privilege (which you haven\'t))');
if (!ctx.auth.equals(user) && !ctx.privileges.has('a12n:access-token:generate')) {
throw new Forbidden('You can only generate OAuth2 access tokens for yourself with this endpoint (unless you have the \'a12n:access-token:generate\' privilege (which you haven\'t))');
}

const token = await oauth2Service.generateTokenDeveloperToken({
Expand Down
3 changes: 2 additions & 1 deletion src/privilege/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ export type InternalPrivilege =
| 'a12n:principals:update'
| 'a12n:one-time-token:generate'
| 'a12n:one-time-token:exchange'
| 'a12n:user:change-password';
| 'a12n:user:change-password'
| 'a12n:access-token:generate';
2 changes: 1 addition & 1 deletion src/server-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ export function requireSetting<T extends keyof Settings>(setting: T): Settings[T
} else {
msg+'There is literally no way to actually do this, and this is a bug. DM me for a prize.';
}
throw msg;
throw new Error(msg);
}

return value;
Expand Down
15 changes: 11 additions & 4 deletions src/user/formats/hal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,24 @@ export function item(user: User, privileges: PrivilegeMap, hasControl: boolean,
};
}

if (hasControl || currentUserPrivileges.has('a12n:access-token:generate', user.href)) {
hal._links['access-token'] = {
href: `${user.href}/access-token`,
title: 'Generate an access token for this user.',
hints: {
allow: ['POST'],
}
};

}

if (hasControl) {
hal.hasPassword = hasPassword;

hal._links['auth-factor-collection'] = {
href: `${user.href}/auth-factor`,
title: 'List of authentication methods / authentication factors for a user',
};
hal._links['access-token'] = {
href: `${user.href}/access-token`,
title: 'Generate an access token for this user.',
};
hal._links['active-sessions'] = {
href: `${user.href}/sessions`,
title: 'Active user sessions'
Expand Down

0 comments on commit 5b30623

Please sign in to comment.