==================================
 Авторизация с помощью Директории
==================================

.. note:: Это внутренний документ, так как ссылается на наши интранет-сервисы.
          Из него можно будет сделать раздел для внешней документации, когда мы будем делать marketplace.
          

Правильный способ организовать авторизацию в вашем сервисе – использовать Директорию и такое понятие, как Ресурс.

Ресурс, это способ завести в Директории id объекта из вашего сервиса. Когда вы создаёте ресурс, директория узнаёт, о том, что в вашем сервисе есть нечто, у чего есть некий id. Этим id может быть любая строка, уникальная в рамках вашего сервиса. К примеру, ресурсом может быть папка на Диске, очередь в Трекере, проект в Облаке или Лунапарке.

Когда Директория узнала про ваш Ресурс,  вы можете связать его с другими объектами Директории – Людьми, Отделами и Командами. Тип связи вы задаёте сами в зависимости от потребностей сервиса. Скажем, Трекер может связать Ресурс своей очереди с конкретным Человеком и указать в названии связи, “admin”. А потом связать этот же Ресурc с Отделом связью с названием “user”.

Когда связи установлены, можно запросить у Директории всё Людей, которые имеют связь с Ресурсом заданного типа. В описанной выше ситуации, можно “спросить” всех Людей, у которых есть связь “user” с определённой Очередью. При этом Директория сама учтёт, что в Отделе могут быть вложенные подотделы, и выдаст вам конечный список людей с учётом всей иерархии. Список их uid этих Людей необходимо закэшировать и использовать для авторизации на своей стороне уже не обращаясь к Директории на каждый запрос.

Итого, поддержка авторизации требует трёх действий
==================================================

1) Позволить пользователю выбрать кому он даёт доступ:
   
   * ``/suggest/``
     
2) Связать Ресурс с другими сущностями Директории (создание ресурса и установку связей можно сделать одним действием):
   
   * ``POST /resources/{resource_id}/relations/bulk-update/``;
   * ``PUT /resources/{resource_id}/relations/``.
     
3) Закэшировать у себя список uid, имеющих доступ:

   * ``GET /users/?resource={resource_id}&resouce_name=admin&fields=id``.


Остаётся вопрос – как подновлять кэш?
=====================================

Структура компании со временем может изменяться, поэтому должны изменяться и доступы. Поэтому кэш нужно подновлять.

**Самое простое решение** – установить кэшу ttl. Рекомендуемое значение – 1 час.

Но если вы хотите, чтобы изменения в структуре отражались на авторизации почти мгновенно, то ttl будет недостаточно. В этом случае, нужно будет подписать свой web-hook на событие ``resource_grant_changed``. В данных, доставляемых в web-hook, есть id вашего ресурса,  чей кэш нужно обновить. (Сейчас этот id можно вынуть из payload как ``payload[‘object’][‘external_id’]``, но это не порядок, в одной из следующих версий API мы будем упрощать структуру событий и формат поменяется).
