Подробности
Я использую type-graphql и пытаюсь ограничить доступ к данным или действиям для определенной группы c пользователей с помощью декоратора @Authorized()
и пользовательской аутентификации шашки в качестве охранника. Все работает, и доступ заблокирован / разрешен соответствующим образом согласно декоратору.
Проблема
Я хочу, чтобы владелец / автор документа мог редактировать / удалять даже если он помечен @Authorized(["MODERATOR", "ADMIN"])
, при желании я мог бы пометить что-то вроде @Authorized(["OWNER", "MODERATOR", "ADMIN"])
, если это облегчает реализацию.
Насколько я знаю, у меня нет никакой информации относительно того, какая модель / документ пользователь пытается получить доступ к проверке подлинности только аргументов мутации. Другими словами, у меня есть идентификатор того, к чему они хотят получить доступ, но не модель, к которой он принадлежит.
Вопрос
Могу ли я проверить, есть ли пользователь владеет документом в средстве проверки подлинности или мне нужно будет пометить его как @Authorized()
и проверить, является ли пользователь владельцем документа или администратором / модератором в каждой мутации / запросе?
код
index.d.ts
declare module "type-graphql" {
function Authorized(): MethodAndPropDecorator;
function Authorized(roles: AccessLevels[]): MethodAndPropDecorator;
function Authorized(...roles: AccessLevels[]): MethodAndPropDecorator;
}
types.ts
type AccessLevels = "MODERATOR" | "ADMIN";
authChecker.ts
const authChecker: AuthChecker<{ user: User | null }, AccessLevels> = ({ context }, roles): boolean => {
if (!context.user) {
return false;
}
if (roles.length === 0) {
return true;
}
if (context.user.accessLevel > 0 && roles.includes("MODERATOR")) {
return true;
}
return context.user.accessLevel > 1 && roles.includes("ADMIN");
};
EstablishmentResolver.ts
@Authorized(["MODERATOR", "ADMIN"])
@Mutation(() => EstablishmentType, { description: "Deletes a establishment by ID" })
async deleteEstablishment(@Args() { id }: EstablishmentIdArg): Promise<Establishment> {
const establishment = await Establishment.findOne({ where: { id } });
if (!establishment) {
throw new Error("Establishment does not exist");
}
await establishment.destroy();
return establishment;
}