0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-01-06 20:40:08 -05:00

feat(core): add koa user role guard middleware (#255)

* feat(core): add koa user role guard middleware

add user role guard middleware

* fix(core): resolve cr comments

remove getUserInfo

* fix(cr): cr fix

cr fix
This commit is contained in:
simeng-li 2022-02-23 09:41:55 +08:00 committed by GitHub
parent ab4beadd70
commit 4a80773b2d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 0 deletions

View file

@ -0,0 +1,34 @@
import { UserRole } from '@logto/schemas';
import { Context } from 'koa';
import RequestError from '@/errors/RequestError';
import { mockUser } from '@/utils/mock';
import { createContextWithRouteParameters } from '@/utils/test-utils';
import { WithAuthContext } from './koa-auth';
import koaRoleGuard from './koa-role-guard';
import { WithUserInfoContext } from './koa-user-info';
describe('koaRoleGuard middleware', () => {
const baseCtx = createContextWithRouteParameters();
const ctx: WithUserInfoContext<Context & WithAuthContext> = {
...baseCtx,
auth: 'foo',
userInfo: mockUser,
};
const unauthorizedError = new RequestError({ code: 'auth.unauthorized', status: 401 });
const next = jest.fn();
it('should throw if user dose not have admin role', async () => {
ctx.userInfo.roleNames = ['guest'];
await expect(koaRoleGuard(UserRole.admin)(ctx, next)).rejects.toMatchError(unauthorizedError);
});
it('should not throw for admin user', async () => {
ctx.userInfo.roleNames = ['admin'];
await expect(koaRoleGuard(UserRole.admin)(ctx, next)).resolves.not.toThrow();
});
});

View file

@ -0,0 +1,20 @@
import { MiddlewareType } from 'koa';
import RequestError from '@/errors/RequestError';
import assertThat from '@/utils/assert-that';
import { WithUserInfoContext } from './koa-user-info';
export default function koaRoleGuard<StateT, ContextT extends WithUserInfoContext, ResponseBodyT>(
// TODO: need to figure out how to infer enum role types from db value
role: string
): MiddlewareType<StateT, ContextT, ResponseBodyT> {
return async ({ userInfo }, next) => {
assertThat(
userInfo.roleNames?.includes(role),
new RequestError({ code: 'auth.unauthorized', status: 401 })
);
return next();
};
}

View file

@ -15,3 +15,7 @@ export type UserInfo<Keys extends keyof CreateUser = typeof userInfoSelectFields
CreateUser,
Keys
>;
export enum UserRole {
admin = 'admin',
}