Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Адаптер keto-grpc #289

Closed
7 tasks done
Nelfimov opened this issue Dec 15, 2023 · 18 comments · Fixed by #290
Closed
7 tasks done

Адаптер keto-grpc #289

Nelfimov opened this issue Dec 15, 2023 · 18 comments · Fixed by #290
Assignees
Labels
feature New feature or request

Comments

@Nelfimov
Copy link
Member

Nelfimov commented Dec 15, 2023

С чем связан запрос на фичу?

Необходимо добавить адаптер и гард для использования keto-grpc-client

Расскажите как вы это себе видите

  • используем @ory/keto-grpc-client
  • необходимы клиенты для
    • чтения
    • записи
  • УРЛ для отправки запросов должен быть кастомизируем
  • посмотреть в каком формате передавать тупли
  • тесты

Definition of done (критерий готовности)

Тесты проходят, пакет предоставляет гард, есть кастомизация УРЛа запросов

Приложите пример реализаций

No response

Приложите материалы задачи

No response

@Nelfimov Nelfimov added the feature New feature or request label Dec 15, 2023
@Nelfimov Nelfimov self-assigned this Dec 15, 2023
@Nelfimov
Copy link
Member Author

@SlumberyDude посмотри пожалуйста тест в @atls/grpc-keto - не могу понять почему падает

@SlumberyDude
Copy link
Contributor

@Nelfimov Нашел вот тут похожий кейс, что глобальную константу нестовую не нужно экспортировать, если убрать guardProvider из экспортируемых переменных, то ошибки не будет. Ну или создать под гард отдельную свою константу, а не APP_GUARD хотя скорее всего это будет уже не то.

Наверное глобальный гард можно не экспортировать, потому что в доке написано, что они распространяются на все приложение. (вот непонятно, где это приложение заканчивается) https://docs.nestjs.com/guards и будут работать для всего приложения наверное

Global guards are used across the whole application, for every controller and every route handler. In terms of dependency injection, global guards registered from outside of any module

When using this approach to perform dependency injection for the guard, note that regardless of the module where this construction is employed, the guard is, in fact, global.

@Nelfimov
Copy link
Member Author

@SlumberyDude столкнулся с другой проблемой - в интеграционном тесте KetoGuard не видит свою зависимость KetoReadClientService, хотя она поставляется модулем.

Воспроизведение: yarn test integration client-read.test

Nest can't resolve dependencies of the KetoGuard (Reflector, ?). Please make sure that the argument dependency at index [1] is available in the KetoIntegrationModule context.

    Potential solutions:
    - Is KetoIntegrationModule a valid NestJS module?
    - If dependency is a provider, is it part of the current KetoIntegrationModule?
    - If dependency is exported from a separate @Module, is that module imported within KetoIntegrationModule?
      @Module({
        imports: [ /* the Module containing dependency */ ]
      })

Сам тест находится тут: /packages/grpc-keto/integration/test

@TorinAsakura
Copy link
Member

@SlumberyDude столкнулся с другой проблемой - в интеграционном тесте KetoGuard не видит свою зависимость KetoReadClientService, хотя она поставляется модулем.

Воспроизведение: yarn test integration client-read.test

Nest can't resolve dependencies of the KetoGuard (Reflector, ?). Please make sure that the argument dependency at index [1] is available in the KetoIntegrationModule context.

    Potential solutions:
    - Is KetoIntegrationModule a valid NestJS module?
    - If dependency is a provider, is it part of the current KetoIntegrationModule?
    - If dependency is exported from a separate @Module, is that module imported within KetoIntegrationModule?
      @Module({
        imports: [ /* the Module containing dependency */ ]
      })

Сам тест находится тут: /packages/grpc-keto/integration/test

пересобери ярн

@Nelfimov
Copy link
Member Author

Снос yarn.lock и пересборка не помогли.

После этого повалились все тайпчеки по репе из-за нефиксированных версий.

@TorinAsakura
Copy link
Member

@Nelfimov папку кеш, а не ярн лок

@Nelfimov
Copy link
Member Author

не помогло

@SlumberyDude
Copy link
Contributor

@Nelfimov Проблема в том, что из модуля KetoModule гард экспортируется в виде

{
    provide: KETO_GUARD,
    useFactory: (reflector: Reflector, ketoReadClient: KetoReadClientService) =>
      new KetoGuard(reflector, ketoReadClient),
    inject: [KETO_READ_CLIENT],
},

То есть он привязывается к токену-константе KETO_GUARD

А потом уже в контроллере клиент (у нас KetoIntegrationController) использует @UseGuards(KetoGuard) что не прокатывает потому что экспортируется не KetoGuard, а KETO_GUARD. Вот ищу как это обойти, пока что не могу загуглить как экспортированный в виде токена гард потом использовать в декораторе @UseGuards. Обычно эти экспортированные в виде токенов-констант провайдеры инжектят в другие провайдеры через @Inject(OTHER_PROVIDER_TOKEN) otherProvider: OtherProvider, но тут другой случай.

@SlumberyDude
Copy link
Contributor

@Nelfimov Если явно добавить CheckServiceClient, KetoReadClientService, KetoGuard в список провайдеров в кето модуль, то вроде ошибка импорта чинится,

return {
      global: options?.global ?? true,
      module: KetoModule,
      providers: [...optionsProvider, ...exportsProvider, CheckServiceClient, KetoReadClientService, KetoGuard],
      exports: [...exportsProvider]
}

Другого способа пока что не нашел

@Nelfimov
Copy link
Member Author

@SlumberyDude сделал рефактор кода, добавил много чего в провайдеры. Сейчас ошибка такая:

Nest can't resolve dependencies of the KetoCheckClientService (?). Please make sure that the argument dependency at index [0] is available in the KetoModule context.

Речь о вот этом провайдере:

export class KetoCheckClientService extends CheckServiceClient {
  constructor(@Inject(KETO_MODULE_OPTIONS) private readonly options: KetoModuleOptions) {
    super(options.read, options.credentials)
  }
}

И что странно, KETO_MODULE_OPTIONS он якобы не находит, хотя они есть в модуле:

export const createKetoOptionsProvider = (options: KetoModuleOptions): Provider[] => [
  {
    provide: KETO_MODULE_OPTIONS,
    useValue: options,
  },
]

Можешь плиз посмотреть?

@SlumberyDude
Copy link
Contributor

@Nelfimov Исправил провайдеры на вот это

export const createKetoExportsProvider = (): Provider[] => [
  {
    provide: KETO_CHECK_CLIENT,
    // useClass: KetoCheckClientService,
    useFactory: (options: KetoModuleOptions) =>
      new KetoCheckClientService(options),
    inject: [KETO_MODULE_OPTIONS]
  },
  {
    provide: KETO_WRITE_NATIVE_CLIENT,
    // useClass: KetoWriteNativeClientService,
    useFactory: (options: KetoModuleOptions) =>
      new KetoWriteNativeClientService(options),
    inject: [KETO_MODULE_OPTIONS]
  },

  {
    provide: KETO_READ_CLIENT,
    // useClass: KetoReadClientService,
    useFactory: (checkClientService: KetoCheckClientService) =>
      new KetoReadClientService(checkClientService),
    inject: [KETO_WRITE_NATIVE_CLIENT]
  },
  {
    provide: KETO_WRITE_CLIENT,
    // useClass: KetoWriteClientService,
    useFactory: (ketoWriteNativeClientService: KetoWriteNativeClientService) =>
      new KetoWriteClientService(ketoWriteNativeClientService),
    inject: [KETO_CHECK_CLIENT]
  },
  {
    provide: KETO_GUARD,
    useFactory: (reflector: Reflector, ketoReadClient: KetoReadClientService) =>
      new KetoGuard(reflector, ketoReadClient),
    inject: [KETO_READ_CLIENT],
  },
]

Прокатило, чтобы yarn test integration grpc-keto перестал выдавать ошибки связанные с зависимостями, но в решении я не уверен.

@Nelfimov
Copy link
Member Author

Теперь будто прошлись по кругу и вернулись обратно:

Nest can't resolve dependencies of the KetoGuard (Reflector, ?). Please make sure that the argument dependency at index [1] is available in the KetoIntegrationModule context.

@Module({
  imports: [
    KetoModule.register({
      read: 'http://localhost:4466',
      write: 'http://localhost:4467',
    }),
  ],
  controllers: [KetoIntegrationController],
})
export class KetoIntegrationModule {}
@Injectable()
export class KetoGuard implements CanActivate {
  constructor(
    private readonly reflector: Reflector,
    @Inject(KETO_READ_CLIENT) private readonly ketoReadClient: KetoReadClientService
  ) {}
...

@SlumberyDude
Copy link
Contributor

SlumberyDude commented Dec 26, 2023

@Nelfimov Может действительно было правильно (как изначально было) сделать guard провайдер как-то вроде

{
    provide: APP_GUARD,
    useFactory: (reflector: Reflector, ketoReadClient: KetoReadClientService) =>
      new KetoGuard(reflector, ketoReadClient),
    inject: [KETO_READ_CLIENT],
  }

Чтобы сделать его глобальным. Тогда вроде его не нужно экспортировать, а только записать в провайдеры. И убрать @UseGuards(KetoGuard) из контроллера KetoIntegrationController (потому что по идее глобальный гард должен работать и так - то есть без декоратора).

Нужно проверить, будет ли такой глобальный гард работать.

@Nelfimov
Copy link
Member Author

Проверю, однако цель у этого адаптера сделать локальный гард чтобы покрывать только часть контроллера.

@SlumberyDude
Copy link
Contributor

SlumberyDude commented Dec 27, 2023

@Nelfimov А как в прошлый раз получилось преодолеть ошибку, когда такая же была? Ты говоришь мы сделали круг.

@Nelfimov
Copy link
Member Author

Решил проблему - гарды нельзя экспортировать, иначе они не увидят скоуп модуля куда импортируются. Поэтому просто убрал гард из экспортируемых провайдеров.

Тут подробнее: nestjs/nest#3856 (comment)

@SlumberyDude
Copy link
Contributor

@Nelfimov А если их не экспортировать, то тогда как ими пользоваться?

@Nelfimov
Copy link
Member Author

Брать напрямую из пакета и использовать в UseGuards

@Nelfimov Nelfimov linked a pull request Dec 29, 2023 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants