Type-GraphQL: разрешить владельцу документа и администратору / модератору доступ с помощью декоратора @Authorized () - PullRequest
0 голосов
/ 25 апреля 2020

Подробности

Я использую 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;
}

1 Ответ

1 голос
/ 26 апреля 2020

Попробуйте изменить сигнатуру и логи c, чтобы разрешить передачу обратного вызова в декоратор, что разрешит условие "владелец":

@ObjectType
class User {
  @Authorized({ 
    roles: ["MODERATOR", "ADMIN"],
    owner: ({ root, context }) => {
      return root.id === context.user.id;
    },
  })
  @Field()
  email: string;
}

Имейте в виду, что вы не всегда можете это сделать внутри authChecker или промежуточного программного обеспечения, поскольку они запускаются перед вашим кодом распознавателя, поэтому в случае deleteEstablishment не существует универсального способа сопоставить establishmentId с user.id, чтобы определить, является ли он владельцем или нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...