Сервисные приложения

Сервисные приложения используются, чтобы управлять ресурсами пользователей в организации по API. Например, с их помощью вы сможете создать резервную копию писем или управлять событиями в Календаре пользователя. Всего можно создать до 20 сервисных приложений.

Работа с сервисными приложениями доступна, если для организации подключен тариф Оптимальный или Расширенный. При отключении тарифов управлять приложениями не получится — в течение месяца можно будет только очистить их список. Когда месяц закончится, приложения будут удалены из организации.

Внимание

Согласно пункту 3.7 оферты, после подключения доступа администратор обязан уведомить об этом всех пользователей и при необходимости получить их письменное согласие (если они не давали его ранее).

Подключение сервисных приложений

  1. Войдите в аккаунт владельца организации.

  2. Зарегистрируйте приложение, которое будет управлять списком сервисных приложений в организации.

    1. Откройте страницу создания OAuth-приложения.

    2. Укажите название вашего сервиса и при необходимости прикрепите иконку.

    3. В блоке Платформы приложения выберите Веб-сервисы. В поле Redirect URI нажмите ссылку Подставить URL для отладки.

    4. В разделе Доступ к данным укажите права доступа, которые необходимы для управления сервисными приложениями в организации:

      • ya360_security:service_applications_read — чтение списка сервисных приложений;

      • ya360_security:service_applications_write — управление списком сервисных приложений (чтение и запись).

    5. Добавьте электронную почту для связи. Внизу страницы нажмите Создать приложение. На экране появятся его описание.

    6. Скопируйте идентификатор приложения из поля ClientID — он потребуется для получения OAuth-токена. В дальнейшем открыть страницу со всеми вашими приложениями вы сможете по ссылке oauth.yandex.ru/.

  3. Запросите OAuth-токен любым подходящим способом. Он понадобится для дальнейшей регистрации всех сервисных приложений в организации.

    Отладочный OAuth-токен можно получить вручную:

    1. Перейдите по ссылке

      https://oauth.yandex.ru/authorize?response_type=token&client_id=<main_app_client_id>
      

      Вместо <main_app_client_id> подставьте значение ClientID из п. 2.6.

    2. Если OAuth-токен вашему приложению выдается впервые, откроется экран авторизации. После входа Яндекс OAuth перенаправит вас на страницу с токеном. Подробнее об отладочных токенах.

  4. Уведомите пользователей и получите от них согласие, если они не давали его ранее, на доступ администратора к управлению их ресурсами согласно пункту 3.7 оферты.

  5. Активируйте функцию сервисных приложений с помощью запроса:

    POST https://api360.yandex.net/security/v1/org/<org_id>/service_applications/activate
    

    Вместо <org_id> подставьте идентификатор вашей организации.

  6. Зарегистрируйте сервисное приложение. С его помощью можно будет получать временные OAuth-токены пользователей. Срок действия временного токена — 1 час.

    1. Создайте отдельное OAuth-приложение по аналогии с созданием основного приложения (п. 2). В качестве прав доступа этого приложения укажите те, которые будут использоваться в API-запросах .

    2. Сделайте приложение из предыдущего шага сервисным для организации.

      Пример
      curl --location \
      --request POST 'https://api360.yandex.net/security/v1/org/<org_id>/service_applications' \
      --header 'Authorization: OAuth <owner_token_to_manage_service_app>’ \
      --header 'Content-Type: application/json' \
      --data-raw '{ \
        "applications": [ \
          { \
            "id": “<OAuth_service_app_client_id>”, \
            "scopes": [ \
              "cloud_api:disk.app_folder", \
              "cloud_api:disk.read", \
              "cloud_api:disk.write", \
              "cloud_api:disk.info" \
            ] \
          } \
        ] \
      }'
      

      В код подставьте значения:

      • <org_id> — идентификатор вашей организации;

      • <owner_token_to_manage_service_app> — OAuth-токен из п. 3;

      • <OAuth_service_app_client_id> — ClientID сервисного приложения из п. 6.1.

    3. Проверьте, что приложение добавилось как сервисное корректно.

      Пример
      curl --location  \
      --request GET 'https://api360.yandex.net/security/v1/org/<org_id>/service_applications'  \
      --header 'Authorization: OAuth <owner_token_to_manage_service_app>'
      

    Чтобы подключить другие сервисные приложения, повторите шаги п. 6.

  7. Получите временный токен пользователя. Это можно сделать с помощью API-запроса:

    POST /token HTTP/1.1
       Host: http://oauth.yandex.ru
       Content-type: application/x-www-form-urlencoded
    
    Пример
    curl --location \
    --request POST 'https://oauth.yandex.ru/token' \
    --header 'Content-Type: application/x-www-form-urlencoded' \
    --data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:token-exchange' \
    --data-urlencode 'client_id=<OAuth_service_app_client_id>' \
    --data-urlencode 'client_secret=<OAuth_service_app_client_secret>' \
    --data-urlencode 'subject_token=<user_id>' \
    --data-urlencode 'subject_token_type=urn:yandex:params:oauth:token-type:uid'
    

    или

    curl --location
    --request POST 'https://oauth.yandex.ru/token' \
    --header 'Content-Type: application/x-www-form-urlencoded' \
    --data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:token-exchange' \
    --data-urlencode 'client_id=<OAuth_service_app_client_id>' \
    --data-urlencode 'client_secret=<OAuth_service_app_client_secret>' \
    --data-urlencode 'subject_token=<user_email>' \
    --data-urlencode 'subject_token_type=urn:yandex:params:oauth:token-type:email'
    

    В код подставьте значения:

    • <OAuth_service_app_client_id> — ClientID сервисного приложения из п. 6.1.

    • <OAuth_service_app_client_secret> — Client secret сервисного приложения;

    • <user_id> — идентификатор пользователя, для которого необходимо получить токен;

    • <user_email> — электронный адрес пользователя вида username@domain.ru, для которого необходимо получить токен.

    Ответ будет содержать токен, который надо использовать в запросах к API сервисов Яндекс 360.

Подробнее программная работа с сервисными приложениями описана в Cправочнике API 360.

Примеры запросов для работы с ресурсами пользователей

Временные токены, полученные с помощью сервисных приложений, позволяют обращаться по API к некоторым ресурсам пользователей в организации, например для бэкапа данных, аудита или поиска информации.

Яндекс Диск

API Яндекс Диска предназначен для работы с файлами и управления доступом к ним. Вы можете направлять запросы к API Диска при помощи сервиса Полигон.

Пример

Запрос метаинформации о Диске сотрудника:

curl --request GET 'https://cloud-api.yandex.net/v1/disk' \
--header 'Accept: application/json' \
--header 'Authorization: OAuth <oauth_token>'

Вместо <oauth_token> подставьте значение временного токена пользователя из п. 7.

Подробнее о работе с REST-API Диска.

Яндекс Почта

Приложения могут получать доступ к ящикам Яндекс Почты по протоколу OAuth. OAuth-авторизацию поддерживают IMAP- и SMTP-серверы Яндекс Почты.

Пример

Скрипт Python для подсчета писем у пользователя по протоколу IMAP:

import imaplib

def generate_oauth2_string(username, access_token):
    auth_string = 'user=%s\1auth=Bearer %s\1\1' % (username, access_token)
    return auth_string

def get_imap_connector(username="<user_email>", token="<oauth_token>"):
    auth_string = generate_oauth2_string(username, token)
    imap_connector = imaplib.IMAP4_SSL("imap.yandex.com", 993)
    imap_connector.authenticate('XOAUTH2', lambda x: auth_string)
    return imap_connector

def get_total_emails(imap_connector):
    mailboxes = []
    ttl_emails = 0
    for mailbox in imap_connector.list()[1]:
        mailboxes.append(mailbox.decode("utf-8").split()[-1].replace('"', ''))
        for mailbox in mailboxes:
            try:
                imap_connector.select(mailbox)
                resp_code, mail_count = imap_connector.select(mailbox=mailbox, readonly=True)
                ttl_emails += int(mail_count[0].decode("utf-8"))
            except imaplib.IMAP4.error:
                print(f"Folder: {folder} Error reading emails")
            except ValueError:
                print(f"Folder: {folder} Error reading emails")
    user_logout(imap_connector)
    return ttl_emails

get_total_emails(get_imap_connector())

В код подставьте значения:

  • <user_email> — электронный адрес пользователя вида username@domain.ru, для которого необходимо получить данные;
  • <oauth_token> — временный токен пользователя из п. 7.

Подробнее о работе почтовых протоколов см. в описании IMAP и в спецификации SMTP.

Яндекс Календарь

С использованием OAuth-токенов можно взаимодействовать с Яндекс Календарем пользователей по протоколу CalDAV.

Пример 1

Cкрипт Python для удаления выбранного Календаря пользователя:

import caldav

def get_principal(username, leg_token):
    client = caldav.DAVClient(url="https://caldav.yandex.ru/", username=username, password=leg_token)
    principal = client.principal()
    return principal

my_principal = get_principal("<user_email>", "<oauth_token>")

def find_delete_calendar(my_principal, calendar_name="Мой календарь"):
    try:
        calendar = my_principal.calendar(name=calendar_name)
        assert calendar
        print(f"We found an existing calendar with name {calendar_name}, now deleting it")
        calendar.delete()
    except caldav.error.NotFoundError:
        print("Calendar was not found")

find_delete_calendar(my_principal)

В код подставьте значения:

  • <user_email> — электронный адрес пользователя вида username@domain.ru, для которого необходимо получить данные;

  • <oauth_token> — временный токен пользователя из п. 7.

Примечание

Если администратор удалит календарь пользователя, восстановить его в дальнейшем не сможет ни администратор, ни сам пользователь.

Пример 2

Запросы создания встречи в Календаре со ссылкой на видеовстречу в Телемосте:

  • Конференция для одиночного события.

    curl -v "https://caldav.yandex.ru/calendars/<user_email>/events-default/<event_uid>.ics" \
    -H "Authorization: OAuth <oauth_token>" \
    -H "Content-type: text/ics" \
    -X PUT \
    --data-binary "
      BEGIN:VCALENDAR
      BEGIN:VEVENT
      X-TELEMOST-REQUIRED:TRUE
      DESCRIPTION:Single event
      UID:<event_uid>
      DTSTART:20230417T120000Z
      END:VEVENT
      END:VCALENDAR"
    

    В код подставьте значения:

    • <user_email> — электронный адрес пользователя вида username@domain.ru, для которого необходимо получить данные;
    • <event_uid> — идентификатор встречи и имени файла (например, a5e3e7b0-dd11-11ed);
    • <oauth_token> — временный токен пользователя из п. 7.

    Пример успешного ответа:

    HTTP/1.1 201 Created
    
    curl -v "https://caldav.yandex.ru/calendars/<user_email>/events-default/<event_uid>.ics" \
      -H "Authorization: OAuth <oauth_token>"
    

    В код подставьте значения:

    • <user_email> — электронный адрес пользователя вида username@domain.ru, для которого необходимо получить данные;

    • <event_uid> — идентификатор встречи и имени файла (например, a5e3e7b0-dd11-11ed);

    • <oauth_token> — временный токен пользователя из п. 7.

    Пример успешного ответа:

    HTTP/1.1 200 OK
    BEGIN:VCALENDAR
    ...
    BEGIN:VEVENT
    DTSTART:20230417T120000Z
    DTEND:20230417T120000Z
    SUMMARY:Без названия
    UID:a5e3e7b0-dd11-11ed
    DESCRIPTION:Link to video conference: https://telemost.yandex.ru/j/78566269088286\n\nSingle event
    X-TELEMOST-CONFERENCE:https://telemost.yandex.ru/j/78566269088286
    ...
    END:VEVENT
    END:VCALENDAR
    
  • Конференция для повторяющегося события.

    curl -v "https://caldav.yandex.ru/calendars/<user_email>/events-default/<event_uid>.ics" \
    -H "Authorization: OAuth <oauth_token>" \
    -H "Content-type: text/ics" \
    -X PUT \
    --data-binary "
      BEGIN:VCALENDAR
      BEGIN:VEVENT
      X-TELEMOST-REQUIRED:TRUE
      DESCRIPTION:Weekly event
      UID:<event_uid>
      DTSTART:20230411T200000Z
      RRULE:FREQ=WEEKLY
      END:VEVENT
      END:VCALENDAR"
    

    В код подставьте значения:

    • <user_email> — электронный адрес пользователя вида username@domain.ru, для которого необходимо получить данные;

    • <event_uid> — идентификатор встречи и имени файла (например, a5e3e7b0-dd11-11ed);

    • <oauth_token> — временный токен пользователя из п. 7.

    Пример успешного ответа:

    HTTP/1.1 201 Created
    
    curl -v "https://caldav.yandex.ru/calendars/<user_email>/events-default/<event_uid>.ics" \
      -H "Authorization: OAuth <oauth_token>"
    

    В код подставьте значения:

    • <user_email> — электронный адрес пользователя вида username@domain.ru, для которого необходимо получить данные;

    • <event_uid> — идентификатор встречи и имени файла (например, a5e3e7b0-dd11-11ed);

    • <oauth_token> — временный токен пользователя из п. 7.

    Пример успешного ответа:

    BEGIN:VCALENDAR
    ...
    BEGIN:VEVENT
    RECURRENCE-ID:20230411T200000Z
    X-TELEMOST-CONFERENCE:https://telemost.yandex.ru/j/39864310386563
    DESCRIPTION:Ссылка на видеовстречу: https://telemost.yandex.ru/j/39864310386563\n\nWeekly event
    ...
    END:VEVENT
    BEGIN:VEVENT
    RRULE:FREQ=WEEKLY;BYDAY=TU;INTERVAL=1
    DESCRIPTION:Ссылка на видеовстречу: https://telemost.yandex.ru/j/39864310386563\n\nWeekly event
    ...
    END:VEVENT
    

При отправке PUT-запроса для создания или изменения события в календаре клиент добавляет внутрь компонентов VEVENT нестандартное свойство X-TELEMOST-REQUIRED. Сервер, получая такой запрос, генерирует ссылку на видеовстречу в Телемосте и добавляет ее в описание встречи в виде текста.

При чтении клиентом встреч сервер не указывает свойство X-TELEMOST-REQUIRED. Но, если ссылка на видеовстречу в Телемосте была сгенерирована, возвращает эту ссылку в нестандартном свойстве X-TELEMOST-CONFERENCE.

Подробнее о работе с протоколом CalDAV см. в его спецификации.

Написать в службу поддержки