Skip to content

Commit

Permalink
Merge pull request #567 from curveball/identity-privileges
Browse files Browse the repository at this point in the history
Adding a specialized privilige for dealing with identities.
  • Loading branch information
evert authored Jan 9, 2025
2 parents 045a6e6 + d5132f4 commit a3573b8
Show file tree
Hide file tree
Showing 9 changed files with 52 additions and 27 deletions.
7 changes: 7 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
Changelog
=========

0.28.2 (????-??-??)
-------------------

* Add a new privilege for managing user identities. Before this change it was
required to have the 'admin' privilege to do this.


0.28.1 (2025-01-08)
-------------------

Expand Down
18 changes: 18 additions & 0 deletions src/migrations/20250109120700_new_privileges.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Knex } from 'knex';

const privilege = 'a12n:user:manage-identities';

export async function up(knex: Knex): Promise<void> {
await knex('privileges')
.insert({privilege, description: 'Full control over a user identities, including adding, deleting, setting and removing verification status.'});

}

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

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

}

4 changes: 2 additions & 2 deletions src/principal-identity/controller/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ class PrincipalIdentityCollection extends Controller {
const principal = await principalService.findByExternalId(ctx.params.id, 'user');
const identities = await services.principalIdentity.findByPrincipal(principal);

if (ctx.auth.equals(principal) && !ctx.privileges.has('admin')) {
throw new Forbidden('You can only use this API for yourself, or if you have \'admin\' privileges');
if (ctx.auth.equals(principal) && !ctx.privileges.has('a12n:user:manage-identities')) {
throw new Forbidden('You can only use this API for yourself, or if you have the \'a12n:user:manage-identities\'privilege');
}

ctx.response.body = hal.collection(
Expand Down
8 changes: 4 additions & 4 deletions src/principal-identity/controller/item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ class PrincipalIdentityItem extends Controller {

const identity = await services.principalIdentity.findByExternalId(principal,ctx.params.identityId);

if (ctx.auth.equals(principal) && !ctx.privileges.has('admin')) {
throw new Forbidden('You can only use this API for yourself, or if you have \'admin\' privileges');
if (ctx.auth.equals(principal) && !ctx.privileges.has('a12n:user:manage-identities')) {
throw new Forbidden('You can only use this API for yourself, or if you have the \'a12n:user:manage-identities\'privilege');
}

ctx.response.body = hal.item(
Expand All @@ -33,8 +33,8 @@ class PrincipalIdentityItem extends Controller {

const identity = await services.principalIdentity.findByExternalId(principal,ctx.params.identityId);

if (ctx.auth.equals(principal) && !ctx.privileges.has('admin')) {
throw new Forbidden('You can only use this API for yourself, or if you have \'admin\' privileges');
if (ctx.auth.equals(principal) && !ctx.privileges.has('a12n:user:manage-identities')) {
throw new Forbidden('You can only use this API for yourself, or if you have the \'a12n:user:manage-identities\'privilege');
}

const isMfa = !!(+ctx.request.body.isMfa);
Expand Down
8 changes: 4 additions & 4 deletions src/principal-identity/controller/verify-response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ class PrincipalIdentityVerify extends Controller {

const identity = await services.principalIdentity.findByExternalId(principal,ctx.params.identityId);

if (ctx.auth.equals(principal) && !ctx.privileges.has('admin')) {
throw new Forbidden('You can only use this API for yourself, or if you have \'admin\' privileges');
if (ctx.auth.equals(principal) && !ctx.privileges.has('a12n:user:manage-identities')) {
throw new Forbidden('You can only use this API for yourself, or if you have the \'a12n:user:manage-identities\'privilege');
}
ctx.response.body = hal.verifyResponseForm(identity);

Expand All @@ -29,8 +29,8 @@ class PrincipalIdentityVerify extends Controller {

const identity = await services.principalIdentity.findByExternalId(principal,ctx.params.identityId);

if (ctx.auth.equals(principal) && !ctx.privileges.has('admin')) {
throw new Forbidden('You can only use this API for yourself, or if you have \'admin\' privileges');
if (ctx.auth.equals(principal) && !ctx.privileges.has('a12n:user:manage-identities')) {
throw new Forbidden('You can only use this API for yourself, or if you have the \'a12n:user:manage-identities\'privilege');
}

try {
Expand Down
4 changes: 2 additions & 2 deletions src/principal-identity/controller/verify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ class PrincipalIdentityVerify extends Controller {

const identity = await services.principalIdentity.findByExternalId(principal,ctx.params.identityId);

if (ctx.auth.equals(principal) && !ctx.privileges.has('admin')) {
throw new Forbidden('You can only use this API for yourself, or if you have \'admin\' privileges');
if (ctx.auth.equals(principal) && !ctx.privileges.has('a12n:user:manage-identities')) {
throw new Forbidden('You can only use this API for yourself, or if you have the \'a12n:user:manage-identities\'privilege');
}

await services.principalIdentity.sendVerificationRequest(identity, ctx.ip()!);
Expand Down
1 change: 1 addition & 0 deletions src/privilege/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ export type InternalPrivilege =
| 'a12n:one-time-token:generate'
| 'a12n:one-time-token:exchange'
| 'a12n:user:change-password'
| 'a12n:user:manage-identities'
| 'a12n:access-token:generate';
2 changes: 0 additions & 2 deletions src/user/controller/item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ class UserController extends Controller {
ctx.status = 204;

}


}

export default new UserController();
27 changes: 14 additions & 13 deletions src/user/formats/hal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ export function item(user: User, privileges: PrivilegeMap, hasControl: boolean,
};

}
if (hasControl || currentUserPrivileges.has('a12n:user:manage-identities', user.href)) {
hal._links['identity-collection'] = {
href: `${user.href}/identity`,
title: 'List of identities the user is associated with'
};
}

if (hasControl) {
hal.hasPassword = hasPassword;
Expand All @@ -98,9 +104,14 @@ export function item(user: User, privileges: PrivilegeMap, hasControl: boolean,
href: `${user.href}/app-permission`,
title: 'App Permissions',
};
hal._links['identity-collection'] = {
href: `${user.href}/identity`,
title: 'List of identities the user is associated with'
hal._links['edit-form'] = {
href: `${user.href}/edit`,
title: `Edit ${user.nickname}`
};

hal._links['privileges'] = {
href: `${user.href}/edit/privileges`,
title: 'Change privilege policy',
};
}
if (currentUserPrivileges.has('a12n:user:change-password', user.href)) {
Expand All @@ -111,16 +122,6 @@ export function item(user: User, privileges: PrivilegeMap, hasControl: boolean,
allow: ['PUT'],
}
};

hal._links['edit-form'] = {
href: `${user.href}/edit`,
title: `Edit ${user.nickname}`
};

hal._links['privileges'] = {
href: `${user.href}/edit/privileges`,
title: 'Change privilege policy',
};
}

return hal;
Expand Down

0 comments on commit a3573b8

Please sign in to comment.