Клиент Python для доступа к CalDAV через OAuth2 в Nextcloud - PullRequest
0 голосов
/ 09 мая 2018

Канонические примеры для использования CalDAV всегда используют аутентификацию по имени пользователя и паролю. Однако Nextcloud поддерживает OAuth2, поэтому я хотел бы использовать CalDAV через oauth.

Я уже сделал то же самое с API календаря Google, но просто адаптировал образец oauth2client, предоставленный Google:

client_secrets = 'client_secrets.json'
flow = client.flow_from_clientsecrets(client_secrets, scope="",
                                      message=tools.message_if_missing(client_secrets))
storage = file.Storage('calendar_credentials.dat')
credentials = storage.get()
if credentials is None or credentials.invalid:
    credentials = tools.run_flow(flow, storage)

http = credentials.authorize(http=build_http())

путем замены build_http() на экземпляр caldav.DAVClient не работает. Внутренние request() API-интерфейсы весьма различны, и вызов любого метода клиента caldav с треском провалится, если обернут в authorize(). Итак, вопрос: как интегрировать caldav.DAVClient с oauth2client?

Также недостаточно документации по использованию OAuth с nextCloud. Я нашел это сообщение , но до сих пор не ясно, что и куда.

1 Ответ

0 голосов
/ 09 мая 2018

Давайте начнем с конфигурации. В Nextcloud перейдите в настройки безопасности (https://mycloud.example.com/settings/admin/security).. Есть раздел OAuth 2.0 clients. Добавить клиента. Вы можете использовать любое имя, например, calendar, но важно, чтобы URI перенаправления был http://localhost:8080 Почему? tools.run_flow() создаст экземпляр http-сервера для получения аутентификационного вызова по этому адресу по умолчанию. Нажмите «добавить». Теперь вы должны увидеть новый идентификатор клиента. Скопируйте идентификатор клиента и секрет (щелкните значок глаза, чтобы открыть ) до client_secrets.json , который должен выглядеть следующим образом:

{
  "web": {
    "client_id": "stuff copied from Client Identifier",
    "client_secret": "stuff copied from secret",
    "auth_uri": "https://mycloud.example.com/index.php/apps/oauth2/authorize",
    "token_uri": "https://mycloud.example.com/index.php/apps/oauth2/api/v1/token",
    "redirect_uris": []
  }
}

Когда вы сейчас запускаете пример из раздела вопросов, ваш браузер должен автоматически перейти к экземпляру mycloud.example.com, и должно появиться сообщение «Вы собираетесь предоставить календарь доступ к ваш аккаунт mycloud.example.com. " Нажмите «Предоставить доступ». После ввода вашего имени пользователя и пароля браузер должен быть перенаправлен на http://localhost:8080, и вы должны увидеть сообщение «Процесс аутентификации завершен».

Примечания:

  • Я не нашел разницы, начинается ли client_secrets.json с web или с installed. Однако это должен быть один из этих двоих.
  • очевидно, redirect_uris может оставаться пустым.

Теперь вопрос программирования (это ведь форум программиста ...)

Конструктор caldav.DAVClient допускает параметр auth, который должен быть экземпляром requests.auth.AuthBase. Итак, давайте создадим один:

from requests.auth import AuthBase


class OAuth(AuthBase):
    def __init__(self, credentials):
        self.credentials = credentials

    def __call__(self, r):
        self.credentials.apply(r.headers)
        return r

Теперь вместо вызова credentials.authorize(http=build_http()), как в исходном примере от Google, мы пишем

caldav_client = caldav.DAVClient(
    "https://mycloud.example.com/remote.php/dav/",
    auth=OAuth(credentials))

Вот и все! Теперь мы можем написать

principal = caldav_client.principal()
calendars = principal.calendars()

как в оригинальном примере .

...