From 1a677d69d2e5ef2dc83ddeb8b6c556ee61d2ea54 Mon Sep 17 00:00:00 2001 From: Mathieu Leplatre Date: Tue, 14 Jun 2022 15:26:14 +0200 Subject: [PATCH] Add support for Bearer token strings for auth --- CHANGELOG.rst | 5 ++++- README.rst | 8 +++++++- kinto_http/session.py | 10 ++++++++++ kinto_http/tests/test_session.py | 23 +++++++++++++++++++++++ 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index bb26024..0db030f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -7,7 +7,10 @@ This document describes changes between each past release. 10.10.0 (unreleased) ==================== -- Nothing changed yet. +**New features** + +- Use Bearer token Auth object if specified string for ``auth`` contains ``Bearer`` +- Use Basic Auth if specified string for ``auth`` contains ``:`` 10.9.0 (2022-02-04) diff --git a/README.rst b/README.rst index b90deb5..4ac9dea 100644 --- a/README.rst +++ b/README.rst @@ -96,7 +96,13 @@ Using a Bearer access token to authenticate (OpenID) The authorization header is prefixed with ``Bearer`` by default. If the ``header_type`` is `customized on the server `_, -the client must specify the expected type: ``kinto_http.BearerTokenAuth("XYPJTNsFKV2" type="Bearer+OIDC")`` +the client must specify the expected type: ``kinto_http.BearerTokenAuth("XYPJTNsFKV2", type="Bearer+OIDC")`` + +.. note:: + + Passing a string containing ``Bearer`` will be instantiate a ``kinto_http.BearerTokenAuth()`` object automatically. + + In other words, ``kinto_http.Client(auth="Bearer+OIDC XYPJTNsFKV2")`` is equivalent to ``kinto_http.Client(auth=kinto_http.BearerTokenAuth("XYPJTNsFKV2", type="Bearer+OIDC"))`` Custom headers diff --git a/kinto_http/session.py b/kinto_http/session.py index 8a67dd9..61af6fc 100644 --- a/kinto_http/session.py +++ b/kinto_http/session.py @@ -5,6 +5,7 @@ import requests +import kinto_http from kinto_http import utils from kinto_http.constants import USER_AGENT from kinto_http.exceptions import BackoffException, KintoException @@ -31,6 +32,15 @@ def create_session(server_url=None, auth=None, session=None, **kwargs): if session is None and server_url is None and auth is None: msg = "You need to either set session or auth + server_url" raise AttributeError(msg) + + if auth is not None and isinstance(auth, str): + if ":" in auth: + auth = tuple(auth.split(":", 1)) + elif "bearer" in auth.lower(): + # eg, "Bearer ghruhgrwyhg" + _type, token = auth.split(" ", 1) + auth = kinto_http.BearerTokenAuth(token, type=_type) + if session is None: session = Session(server_url=server_url, auth=auth, **kwargs) return session diff --git a/kinto_http/tests/test_session.py b/kinto_http/tests/test_session.py index b04b0cc..520b1f8 100644 --- a/kinto_http/tests/test_session.py +++ b/kinto_http/tests/test_session.py @@ -9,6 +9,7 @@ import pytest from pytest_mock.plugin import MockerFixture +import kinto_http from kinto_http.constants import USER_AGENT from kinto_http.exceptions import BackoffException, KintoException from kinto_http.session import Session, create_session @@ -209,6 +210,28 @@ def test_use_given_session_if_provided(mocker: MockerFixture): assert session == mocker.sentinel.session +def test_auth_can_be_passed_as_tuple(session_setup: Tuple[MagicMock, Session]): + session = create_session(auth=("admin", "pass")) + assert session.auth == ("admin", "pass") + + +def test_auth_can_be_passed_as_colon_separate(session_setup: Tuple[MagicMock, Session]): + session = create_session(auth="admin:pass") + assert session.auth == ("admin", "pass") + + +def test_auth_can_be_passed_as_basic_header(session_setup: Tuple[MagicMock, Session]): + session = create_session(auth="Bearer+OIDC abcdef") + assert isinstance(session.auth, kinto_http.BearerTokenAuth) + assert session.auth.type == "Bearer+OIDC" + assert session.auth.token == "abcdef" + + +def test_auth_can_be_an_arbitrary_string(session_setup: Tuple[MagicMock, Session]): + session = create_session(auth="Some abcdef") + assert session.auth == "Some abcdef" + + def test_body_is_none_on_304(session_setup: Tuple[MagicMock, Session]): requests_mock, session = session_setup response = get_http_response(304)