Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-igwn-auth-utils for openSUSE:Factory checked in at 2022-09-19 16:03:15 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-igwn-auth-utils (Old) and /work/SRC/openSUSE:Factory/.python-igwn-auth-utils.new.2083 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-igwn-auth-utils" Mon Sep 19 16:03:15 2022 rev:2 rq:1004516 version:0.3.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-igwn-auth-utils/python-igwn-auth-utils.changes 2022-07-10 23:15:23.180953997 +0200 +++ /work/SRC/openSUSE:Factory/.python-igwn-auth-utils.new.2083/python-igwn-auth-utils.changes 2022-09-19 16:03:19.422148270 +0200 @@ -1,0 +2,10 @@ +Sun Sep 18 19:49:06 UTC 2022 - Ben Greiner <c...@bnavigator.de> + +- Update to v0.3.1 + * [!41] Python Requests interface is now not optional + * [!44] New .token attribute for the Session wrapper + * [!46] Improvements to token discovery to handle mismatching + audiences +- Remove and obsolete -requests meta subpackage + +------------------------------------------------------------------- Old: ---- igwn-auth-utils-0.2.3.tar.gz New: ---- igwn-auth-utils-0.3.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-igwn-auth-utils.spec ++++++ --- /var/tmp/diff_new_pack.Bj2eUi/_old 2022-09-19 16:03:20.002149820 +0200 +++ /var/tmp/diff_new_pack.Bj2eUi/_new 2022-09-19 16:03:20.010149842 +0200 @@ -20,7 +20,7 @@ %define skip_python2 1 %global srcname igwn-auth-utils Name: python-igwn-auth-utils -Version: 0.2.3 +Version: 0.3.1 Release: 0 Summary: Auth Utils for International Gravitational-Wave Observatory Network (IGWN) License: BSD-3-Clause @@ -32,6 +32,8 @@ BuildRequires: fdupes BuildRequires: python-rpm-macros Requires: python-cryptography >= 2.3 +Requires: python-requests >= 2.14 +Requires: python-safe-netrc >= 1.0.0 Requires: python-scitokens >= 1.7.0 BuildArch: noarch # SECTION test requirements @@ -42,6 +44,9 @@ BuildRequires: %{python_module safe-netrc >= 1.0.0} BuildRequires: %{python_module scitokens >= 1.7.0} # /SECTION +# The [requests] extra was a subpackage but is included into the main requirements since 0.3 +Provides: python-igwn-auth-utils-requests = %{version}-%{release} +Obsoletes: python-igwn-auth-utils-requests <= 0.3 %python_subpackages %description @@ -51,15 +56,6 @@ This project is primarily aimed at discovering X.509 credentials and SciTokens for use with HTTP(S) requests to IGWN-operated services. -%package requests -Summary: Authorisation utilities for IGWN - requests extra -Requires: python-igwn-auth-utils = %{version} -Requires: python-requests >= 2.14 -Requires: python-safe-netrc >= 1.0.0 - -%description requests -The [requests] extra requirements for python-igwn-auth-utils - %prep %setup -q -n %{srcname}-%{version} sed -i 's/--color=yes//' pyproject.toml @@ -80,7 +76,4 @@ %{python_sitelib}/igwn_auth_utils %{python_sitelib}/igwn_auth_utils-%{version}*-info -%files %{python_files requests} -%license LICENSE - %changelog ++++++ igwn-auth-utils-0.2.3.tar.gz -> igwn-auth-utils-0.3.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/igwn-auth-utils-0.2.3/.gitlab/ci/analysis.yml new/igwn-auth-utils-0.3.1/.gitlab/ci/analysis.yml --- old/igwn-auth-utils-0.2.3/.gitlab/ci/analysis.yml 2022-04-07 16:41:17.000000000 +0200 +++ new/igwn-auth-utils-0.3.1/.gitlab/ci/analysis.yml 2022-09-17 14:52:32.000000000 +0200 @@ -24,6 +24,11 @@ # https://computing.docs.ligo.org/gitlab-ci-templates/python/#.python:flake8 - .python:flake8 needs: [] + variables: + # don't fail the pipeline because of linting issues, + # these are presented in the code-quality box in the + # merge_request UI + FLAKE8_OPTIONS: "--exit-zero" before_script: # pick requirements out of the setup.cfg - ${PYTHON} -m pip install setuptools --upgrade-strategy=only-if-needed @@ -54,7 +59,7 @@ dist = Distribution() dist.parse_config_files() reqs = dist.setup_requires + dist.install_requires - for extra in ('requests', 'test',): + for extra in ('test',): reqs.extend(dist.extras_require[extra]) print('\n'.join(reqs)) " | sort -u > requirements.txt @@ -76,7 +81,5 @@ dist = Distribution() dist.parse_config_files() reqs = dist.setup_requires + dist.install_requires - for extra in ('requests',): - reqs.extend(dist.extras_require[extra]) print('\n'.join(reqs)) " | sort -u > requirements.txt diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/igwn-auth-utils-0.2.3/.gitlab/ci/docs.yml new/igwn-auth-utils-0.3.1/.gitlab/ci/docs.yml --- old/igwn-auth-utils-0.2.3/.gitlab/ci/docs.yml 2022-04-04 16:27:29.000000000 +0200 +++ new/igwn-auth-utils-0.3.1/.gitlab/ci/docs.yml 2022-09-17 14:52:32.000000000 +0200 @@ -20,8 +20,18 @@ extends: # https://computing.docs.ligo.org/gitlab-ci-templates/python/#.python:sphinx - .python:sphinx + rules: + # production build (uses directory URLs which look nice) + - if: '$CI_PROJECT_NAMESPACE == "computing" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' + variables: + BUILDER: "dirhtml" + # development build (doesn't use directory URLs, to support + # direct linking in gitlab CI artifacts) + - if: $CI_COMMIT_BRANCH + variables: + BUILDER: "html" before_script: - - python -m pip install .[docs,requests] + - python -m pip install .[docs] # # Publishing is done automatically diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/igwn-auth-utils-0.2.3/.gitlab/ci/python.yml new/igwn-auth-utils-0.3.1/.gitlab/ci/python.yml --- old/igwn-auth-utils-0.2.3/.gitlab/ci/python.yml 2022-04-07 15:36:38.000000000 +0200 +++ new/igwn-auth-utils-0.3.1/.gitlab/ci/python.yml 2022-09-17 14:52:32.000000000 +0200 @@ -40,7 +40,7 @@ before_script: # resolve wildcard in wheel so we specify an extra - WHEEL=$(echo igwn_auth_utils-*.whl) - - INSTALL_TARGET="${WHEEL}[requests,test]" + - INSTALL_TARGET="${WHEEL}[test]" # configure from template - !reference [".python:pytest", before_script] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/igwn-auth-utils-0.2.3/.readthedocs.yml new/igwn-auth-utils-0.3.1/.readthedocs.yml --- old/igwn-auth-utils-0.2.3/.readthedocs.yml 2021-12-20 17:24:36.000000000 +0100 +++ new/igwn-auth-utils-0.3.1/.readthedocs.yml 2022-09-17 14:52:32.000000000 +0200 @@ -1,10 +1,15 @@ +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details version: 2 + +# Build documentation in the docs/ directory with Sphinx sphinx: - builder: html + builder: dirhtml configuration: docs/conf.py - fail_on_warning: true + +# Optionally declare the Python requirements required to build your docs python: - version: 3.8 + version: "3.8" install: - method: pip path: . diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/igwn-auth-utils-0.2.3/PKG-INFO new/igwn-auth-utils-0.3.1/PKG-INFO --- old/igwn-auth-utils-0.2.3/PKG-INFO 2022-06-21 17:02:06.142180000 +0200 +++ new/igwn-auth-utils-0.3.1/PKG-INFO 2022-09-18 16:09:55.533328300 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: igwn-auth-utils -Version: 0.2.3 +Version: 0.3.1 Summary: Authorisation utilities for IGWN Home-page: https://git.ligo.org/computing/igwn-auth-utils Author: Duncan Macleod @@ -30,7 +30,6 @@ Requires-Python: >=3.6 Description-Content-Type: text/markdown Provides-Extra: docs -Provides-Extra: requests Provides-Extra: test Provides-Extra: lint License-File: LICENSE diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/igwn-auth-utils-0.2.3/RELEASE.md new/igwn-auth-utils-0.3.1/RELEASE.md --- old/igwn-auth-utils-0.2.3/RELEASE.md 1970-01-01 01:00:00.000000000 +0100 +++ new/igwn-auth-utils-0.3.1/RELEASE.md 2022-09-18 16:07:49.000000000 +0200 @@ -0,0 +1,72 @@ +# Releasing `igwn-auth-utils` + +The instructions below detail how to finalise a new release +for version `{X.Y.Z}`. + +In all commands below that placeholder should be replaced +with an actual release version. + +## 1. Update the packaging files + +- Create a new branch on which to update the OS packaging files: + + ```shell + git checkout -b finalise-{X.Y.Z} + ``` + +- Bump versions and add changelog entries in OS packaging files: + + - `debian/changelog` + - `igwn-auth-utils.spec` + + and then commit the changes to the branch. + +- Push this branch to your fork: + + ```shell + git push -u origin finalise-{X.Y.Z} + ``` + +- Open a merge request on GitLab to finalise the packaging update. + +## 2. Tag the release + +- Draft release notes by looking through the merge requests associated + with the relevant + [milestone on GitLab](https://git.ligo.org/computing/igwn-auth-utils/-/milestones). + +- Create an annotated, signed tag in `git` using the release notes + as the tag message: + + ```shell + git tag --sign {X.Y.Z} + ``` + +- Push the tag to the project on GitLab: + + ```shell + git push -u upstream {X.Y.Z} + ``` + +## 3. Create a Release on GitLab + +- Create a + [Release on GitLab](https://git.ligo.org/computing/igwn-auth-utils/-/releases/new), copying the same release notes from the tag message. + + Make sure and correctly associated the correct Tag and Milestone to + the Release. + +## 4. Publish the new release on PyPI: + +- Generate a new source distribution and binary wheel for this release: + + ```shell + git clean -dfX + python -m build --sdist --wheel + ``` + +- Upload these distributions to PyPI: + + ```shell + python -m twine upload --sign dist/igwn*auth*utils-{X.Y.Z}* + ``` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/igwn-auth-utils-0.2.3/debian/changelog new/igwn-auth-utils-0.3.1/debian/changelog --- old/igwn-auth-utils-0.2.3/debian/changelog 2022-06-21 16:54:16.000000000 +0200 +++ new/igwn-auth-utils-0.3.1/debian/changelog 2022-09-18 16:07:49.000000000 +0200 @@ -1,3 +1,10 @@ +igwn-auth-utils (0.3.1-1) unstable; urgency=low + + * update to 0.3.1, 0.3.0 was forgotten in debian + * promote requests interface requirements from suggested to depends + + -- Duncan Macleod <duncan.macl...@ligo.org> Sun, 18 Sep 2022 11:30:00 +0100 + igwn-auth-utils (0.2.3-1) unstable; urgency=low * update to 0.2.3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/igwn-auth-utils-0.2.3/debian/control new/igwn-auth-utils-0.3.1/debian/control --- old/igwn-auth-utils-0.2.3/debian/control 2022-04-07 15:36:38.000000000 +0200 +++ new/igwn-auth-utils-0.3.1/debian/control 2022-09-17 14:52:32.000000000 +0200 @@ -26,10 +26,9 @@ ${misc:Depends}, ${python3:Depends}, python3-cryptography (>= 2.3), - python3-scitokens (>= 1.7.0), -Recommends: python3-requests (>= 2.14), python3-safe-netrc (>= 1.0.0), + python3-scitokens (>= 1.7.0), Description: Authorisation utilities for IGWN Python library functions to simplify using IGWN authorisation credentials. This project is primarily aimed at discovering X.509 credentials and diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/igwn-auth-utils-0.2.3/docs/index.rst new/igwn-auth-utils-0.3.1/docs/index.rst --- old/igwn-auth-utils-0.2.3/docs/index.rst 2022-06-16 13:02:11.000000000 +0200 +++ new/igwn-auth-utils-0.3.1/docs/index.rst 2022-09-17 14:52:32.000000000 +0200 @@ -12,7 +12,7 @@ For more information on the different types of credentials that IGWN member groups use, see -`The IGWN Computing Guide <https://computing.docs.ligo.org/auth/>`_. +`The IGWN Computing Guide <https://computing.docs.ligo.org/guide/auth/>`_. ============ Installation @@ -30,61 +30,28 @@ python -m pip install igwn-auth-utils +Binary packages are also available for various Debian and RHEL +distributions supported by the LIGO Scientific Collaboration's +Computing and Software Working Group, see +`the IGWN Computing Guide <https://computing.docs.ligo.org/guide/software/>`__ +for details. + ============= Documentation ============= -------------------- -``igwn_auth_utils`` -------------------- - -The ``igwn_auth_utils`` module provides the following objects: - -.. currentmodule:: igwn_auth_utils - -.. autosummary:: - :toctree: api - :caption: igwn_auth_utils - :nosignatures: - - ~find_scitoken - find_x509_credentials - scitoken_authorization_header - IgwnAuthError - ----------------------------- -``igwn_auth_utils.requests`` ----------------------------- - -``igwn-auth-utils`` provides an optional `requests` interface in the -``igwn_auth_utils.requests`` module. - -.. admonition:: ``igwn_auth_utils.requests`` has extra requirements - - This module requires the following extra packages to be installed: - - - `requests` - - `safe-netrc` - - These can be installed with `pip` by specifying the `[requests]` - extra when installing ``igwn-auth-utils``: - - .. code-block:: shell - - python -m pip install igwn-auth-utils[requests] - -``igwn_auth_utils.requests`` provides the following classes/functions: - -.. currentmodule:: igwn_auth_utils.requests - -.. autosummary:: - :toctree: api - :caption: igwn_auth_utils.requests - :nosignatures: +.. toctree:: + :maxdepth: 1 + :caption: Using credentials + + HTTP(S) requests <requests> + +.. toctree:: + :maxdepth: 1 + :caption: Credential utilities - SessionAuthMixin - Session - get + SciTokens <scitokens> + X.509 <x509> ======= Support diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/igwn-auth-utils-0.2.3/docs/requests.rst new/igwn-auth-utils-0.3.1/docs/requests.rst --- old/igwn-auth-utils-0.2.3/docs/requests.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/igwn-auth-utils-0.3.1/docs/requests.rst 2022-09-17 14:52:32.000000000 +0200 @@ -0,0 +1,44 @@ +.. sectionauthor:: Duncan Macleod <duncan.macl...@ligo.org> + +.. _igwn-auth-utils-requests: + +############################################ +Making HTTP(S) requests with IGWN Auth Utils +############################################ + +``igwn_auth_utils`` provides a `requests` interface to support +HTTP/HTTPS requests with the IGWN Auth flow. + +=========== +Basic usage +=========== + +To use this interface, open a :class:`~igwn_auth_utils.Session` +and make some requests: + +.. code-block:: python + + >>> from igwn_auth_utils import Session + >>> with Session() as sess: + ... sess.get("https://myservice.example.com/api/important/data") + +The :class:`igwn_auth_utils.Session` class will automatically discover +available SciTokens and X.509 credentials and will send them with the +request to maximise chances of a successfull authorisation. + +See the :class:`igwn_auth_utils.Session` documentation for details on +keywords that enable configuring the discovery of each of the credential +types, including disabling/enabling individual credential types, or +disabling all credentials completely. + +=== +API +=== + +.. autosummary:: + :toctree: api + :nosignatures: + + ~igwn_auth_utils.SessionAuthMixin + ~igwn_auth_utils.Session + ~igwn_auth_utils.get diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/igwn-auth-utils-0.2.3/docs/scitokens.rst new/igwn-auth-utils-0.3.1/docs/scitokens.rst --- old/igwn-auth-utils-0.2.3/docs/scitokens.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/igwn-auth-utils-0.3.1/docs/scitokens.rst 2022-09-17 14:52:32.000000000 +0200 @@ -0,0 +1,18 @@ +.. sectionauthor:: Duncan Macleod <duncan.macl...@ligo.org> + +.. _igwn-auth-utils-scitokens: + +###################### +Working with SciTokens +###################### + +=== +API +=== + +.. autosummary:: + :toctree: api + :nosignatures: + + ~igwn_auth_utils.find_scitoken + ~igwn_auth_utils.scitoken_authorization_header diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/igwn-auth-utils-0.2.3/docs/x509.rst new/igwn-auth-utils-0.3.1/docs/x509.rst --- old/igwn-auth-utils-0.2.3/docs/x509.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/igwn-auth-utils-0.3.1/docs/x509.rst 2022-09-17 14:52:32.000000000 +0200 @@ -0,0 +1,17 @@ +.. sectionauthor:: Duncan Macleod <duncan.macl...@ligo.org> + +.. _igwn-auth-utils-x509: + +############################## +Working with X.509 credentials +############################## + +=== +API +=== + +.. autosummary:: + :toctree: api + :nosignatures: + + ~igwn_auth_utils.find_x509_credentials diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/igwn-auth-utils-0.2.3/igwn-auth-utils.spec new/igwn-auth-utils-0.3.1/igwn-auth-utils.spec --- old/igwn-auth-utils-0.2.3/igwn-auth-utils.spec 2022-06-21 16:54:16.000000000 +0200 +++ new/igwn-auth-utils-0.3.1/igwn-auth-utils.spec 2022-09-18 16:07:49.000000000 +0200 @@ -1,5 +1,5 @@ %define srcname igwn-auth-utils -%define version 0.2.3 +%define version 0.3.1 %define release 1 Name: python-%{srcname} @@ -36,11 +36,9 @@ %package -n python%{python3_pkgversion}-%{srcname} Requires: python%{python3_pkgversion}-cryptography >= 2.3 +Requires: python%{python3_pkgversion}-requests >= 2.14 +Requires: python%{python3_pkgversion}-safe-netrc >= 1.0.0 Requires: python%{python3_pkgversion}-scitokens >= 1.7.0 -%if 0%{?rhel} == 0 || 0%{?rhel} >= 8 -Recommends: python%{python3_pkgversion}-requests >= 2.14 -Recommends: python%{python3_pkgversion}-safe-netrc >= 1.0.0 -%endif Summary: %{summary} %{?python_provide:%python_provide python%{python3_pkgversion}-%{srcname}} %description -n python%{python3_pkgversion}-%{srcname} @@ -75,6 +73,10 @@ # -- changelog %changelog +* Sun Sep 18 2022 Duncan Macleod <duncan.macl...@ligo.org> - 0.3.1-1 +- update to 0.3.1, 0.3.0 was forgotten in RPM +- promote requests interface requirements from suggested to requires + * Thu Jun 16 2022 Duncan Macleod <duncan.macl...@ligo.org> - 0.2.3-1 - update to 0.2.3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/igwn-auth-utils-0.2.3/igwn_auth_utils/__init__.py new/igwn-auth-utils-0.3.1/igwn_auth_utils/__init__.py --- old/igwn-auth-utils-0.2.3/igwn_auth_utils/__init__.py 2021-12-20 17:24:36.000000000 +0100 +++ new/igwn-auth-utils-0.3.1/igwn_auth_utils/__init__.py 2022-09-17 14:52:32.000000000 +0200 @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2021 Cardiff University +# Copyright 2021-2022 Cardiff University # Distributed under the terms of the BSD-3-Clause license __author__ = "Duncan Macleod <duncan.macl...@ligo.org>" @@ -7,6 +7,12 @@ __license__ = "BSD-3-Clause" from .error import IgwnAuthError +from .requests import ( + get, + Session, + SessionAuthMixin, + SessionErrorMixin, +) from .scitokens import ( find_token as find_scitoken, token_authorization_header as scitoken_authorization_header, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/igwn-auth-utils-0.2.3/igwn_auth_utils/_version.py new/igwn-auth-utils-0.3.1/igwn_auth_utils/_version.py --- old/igwn-auth-utils-0.2.3/igwn_auth_utils/_version.py 2022-06-21 17:02:03.000000000 +0200 +++ new/igwn-auth-utils-0.3.1/igwn_auth_utils/_version.py 2022-09-18 16:09:55.000000000 +0200 @@ -1,5 +1,5 @@ # coding: utf-8 # file generated by setuptools_scm # don't change, don't track in version control -version = '0.2.3' -version_tuple = (0, 2, 3) +__version__ = version = '0.3.1' +__version_tuple__ = version_tuple = (0, 3, 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/igwn-auth-utils-0.2.3/igwn_auth_utils/requests.py new/igwn-auth-utils-0.3.1/igwn_auth_utils/requests.py --- old/igwn-auth-utils-0.2.3/igwn_auth_utils/requests.py 2022-04-25 23:01:09.000000000 +0200 +++ new/igwn-auth-utils-0.3.1/igwn_auth_utils/requests.py 2022-09-17 14:52:32.000000000 +0200 @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2021 Cardiff University +# Copyright 2021-2022 Cardiff University # Distributed under the terms of the BSD-3-Clause license """Python Requests interface with IGWN authentication @@ -17,11 +17,15 @@ import requests -from . import ( - IgwnAuthError, - find_scitoken, - find_x509_credentials, - scitoken_authorization_header, +from scitokens import SciToken + +from .error import IgwnAuthError +from .scitokens import ( + find_token as find_scitoken, + token_authorization_header as scitoken_authorization_header, +) +from .x509 import ( + find_credentials as find_x509_credentials, ) _auth_session_parameters = """ @@ -30,29 +34,40 @@ 1. if ``force_noauth=True`` is given, no auth is configured; - 2. if a bearer token is provided via the ``token`` keyword argument, - then use that; + 2. for SciTokens: + + 1. if a bearer token is provided via the ``token`` keyword argument, + then use that, or + + 2. look for a bearer token by passing the ``token_audience`` + and ``token_scope`` keyword parameters to + :func:`igwn_auth_utils.find_scitokens`; + + 3. for X.509 credentials: - 3. if an X.509 credential path is provided via the ``cert`` keyword - argument, then use that; + 1. if an X.509 credential path is provided via the ``cert`` keyword + argument, then use that, or - 4. if ``auth`` keyword is provided, then use that; + 2. look for an X.509 credential using + :func:`igwn_auth_utils.find_x509_credential` - 5. look for a bearer token by passing the ``token_audience`` - and ``token_scope`` keyword parameters to - :func:`igwn_auth_utils.find_scitokens`; + 4. for basic auth (username/password): - 6. look for an X.509 credential using - :func:`igwn_auth_utils.find_x509_credential` + 1. if ``auth`` keyword is provided, then use that, or - 7. read the netrc file located at :file:`~/.netrc`, or at the path - stored in the :envvar:`NETRC` environment variable, and look - for a username and password matching the hostname given in the - ``url`` keyword argument; + 2. read the netrc file located at :file:`~/.netrc`, or at the path + stored in the :envvar:`$NETRC` environment variable, and look + for a username and password matching the hostname given in the + ``url`` keyword argument; - 8. if none of the above yield a credential, and ``fail_if_noauth=True`` + 5. if none of the above yield a credential, and ``fail_if_noauth=True`` was provided, raise a `ValueError`. + Steps 2-4 are all tried independently, with all valid credentials + (one per type) configured for the session. + It is up to the request receiver to handle the multiple credential + types and prioritise between them. + Parameters ---------- token : `scitokens.SciToken`, `str`, `bool`, optional @@ -101,20 +116,22 @@ Raises ------ - IgwnAuthError + ~igwn_auth_utils.IgwnAuthError If ``cert=True`` or ``token=True`` is given and the relevant credential was not actually discovered, or if ``fail_if_noauth=True`` is given and no authorisation token/credentials of any valid type are presented or discovered. - Note - ---- - This class requires `Requests <https://requests.readthedocs.io/>`__. - See also -------- requests.Session for details of the standard options + + igwn_auth_utils.find_scitoken + for details of the SciToken discovery + + igwn_auth_utils.find_x509_credentials + for details of the X.509 credential discovery """.strip() @@ -178,9 +195,15 @@ fail_if_noauth=False, **kwargs, ): - # initialise session + # initialise session and new attributes super().__init__(**kwargs) + #: The SciToken object to be serialised and sent with all requests, + #: this is only populated if a `~scitokens.SciToken` object is + #: passed directly, or discovered automatically (i.e. a serialised + #: token will not be deserialized and stored). + self.token = None + # handle options if force_noauth and fail_if_noauth: raise ValueError( @@ -220,6 +243,8 @@ url=url, error=bool(token), ) + if isinstance(token, SciToken): + self.token = token if token: token = self._set_token_header(token) @@ -305,10 +330,37 @@ Examples -------- + To use the default authorisation discovery: + >>> from igwn_auth_utils.requests import Session + >>> with Session() as sess: + ... sess.get("https://science.example.com/api/important/data") + + To explicitly pass a specific :class:`~scitokens.SciToken` as the token: + >>> with Session(token=mytoken) as sess: - ... sess.get("https://my.science.stuff/data") + ... sess.get("https://science.example.com/api/important/data") + + To explicitly *require* that a token is discovered, and *disable* + any X.509 discovery: + + >>> with Session(token=True, x509=False) as sess: + ... sess.get("https://science.example.com/api/important/data") + + To use default authorisation discovery, but fail if no credentials + are discovered: + + >>> with Session(fail_if_noauth=True) as sess: + ... sess.get("https://science.example.com/api/important/data") + + To disable all authorisation discovery: + + >>> with Session(force_noauth=True) as sess: + ... sess.get("https://science.example.com/api/important/data") """ + __attrs__ = requests.Session.__attrs__ = [ + "token", + ] # update the docstrings to include the same parameter info @@ -328,13 +380,13 @@ the connection session to use, if not given one will be created on-the-fly - *args, **kwargs + args, kwargs all other keyword arguments are passed directly to `requests.Session.get` Returns ------- - resp : `requets.Response` + resp : `requests.Response` the response object See also diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/igwn-auth-utils-0.2.3/igwn_auth_utils/scitokens.py new/igwn-auth-utils-0.3.1/igwn_auth_utils/scitokens.py --- old/igwn-auth-utils-0.2.3/igwn_auth_utils/scitokens.py 2022-04-04 16:27:29.000000000 +0200 +++ new/igwn-auth-utils-0.3.1/igwn_auth_utils/scitokens.py 2022-09-17 14:52:32.000000000 +0200 @@ -10,7 +10,10 @@ import os from pathlib import Path -from jwt import InvalidTokenError +from jwt import ( + InvalidAudienceError, + InvalidTokenError, +) from scitokens import ( Enforcer, SciToken, @@ -20,6 +23,7 @@ from .error import IgwnAuthError TOKEN_ERROR = ( + InvalidAudienceError, InvalidTokenError, SciTokensException, ) @@ -64,7 +68,7 @@ raw : `str` the raw serialised token content to deserialise - **kwargs + kwargs all keyword arguments are passed on to :meth:`scitokens.SciToken.deserialize` @@ -89,7 +93,7 @@ path : `str` the path to the scitokens file - **kwargs + kwargs all keyword arguments are passed on to :func:`deserialize_token` Returns @@ -114,7 +118,7 @@ # -- discovery -------------- -def find_token(audience, scope, timeleft=600, skip_errors=False, **kwargs): +def find_token(audience, scope, timeleft=600, skip_errors=True, **kwargs): """Find and load a `SciToken` for the given ``audience`` and ``scope``. Parameters @@ -132,9 +136,10 @@ skip_errors : `bool`, optional skip over errors encoutered when attempting to deserialise discovered tokens; this may be useful to skip over invalid - or expired tokens that exist, for example. + or expired tokens that exist, for example, which is why it + is the default behaviour. - **kwargs + kwargs all keyword arguments are passed on to :meth:`scitokens.SciToken.deserialize` @@ -202,23 +207,22 @@ **deserialize_kwargs, ) + # try and find a token from HTCondor + for tokenfile in _find_condor_creds_token_paths(): + yield _token_or_exception( + load_token_file, + tokenfile, + **deserialize_kwargs, + ) + try: yield _token_or_exception(SciToken.discover, **deserialize_kwargs) - except ( - OSError, # no token - AttributeError, # windows doesn't have geteuid - ) as exc: - if isinstance(exc, AttributeError) and not ( - WINDOWS - and "geteuid" in str(exc) - ): + except OSError: # no token + pass # try something else + except AttributeError as exc: + # windows doesn't have geteuid, that's ok, otherwise panic + if not WINDOWS or "geteuid" not in str(exc): raise - for tokenfile in _find_condor_creds_token_paths(): - yield _token_or_exception( - load_token_file, - tokenfile, - **deserialize_kwargs, - ) def _find_condor_creds_token_paths(): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/igwn-auth-utils-0.2.3/igwn_auth_utils/tests/test_requests.py new/igwn-auth-utils-0.3.1/igwn_auth_utils/tests/test_requests.py --- old/igwn-auth-utils-0.2.3/igwn_auth_utils/tests/test_requests.py 2022-04-25 23:01:09.000000000 +0200 +++ new/igwn-auth-utils-0.3.1/igwn_auth_utils/tests/test_requests.py 2022-09-17 14:52:32.000000000 +0200 @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2021 Cardiff University +# Copyright 2021-2022 Cardiff University # Distributed under the terms of the BSD-3-Clause license """Tests for :mod:`igwn_auth_utils.requests`. @@ -14,12 +14,9 @@ import pytest -try: - from .. import requests as igwn_requests -except ModuleNotFoundError as exc: # pragma: no cover - pytest.skip(str(exc), allow_module_level=True) -else: - from requests import RequestException +from requests import RequestException + +from .. import requests as igwn_requests from ..error import IgwnAuthError from .test_scitokens import rtoken # noqa: F401 @@ -87,7 +84,8 @@ # -- SessionAuthMixin def test_noauth_args(self): - """Test that `Session(force_noauth=True, fail_if_noauth=True)` is invalid + """Test that `Session(force_noauth=True, fail_if_noauth=True)` + is invalid. """ with pytest.raises(ValueError): self.Session(force_noauth=True, fail_if_noauth=True) @@ -123,6 +121,7 @@ """Test that tokens are handled properly """ sess = self.Session(token=rtoken) + assert sess.token is rtoken assert sess.headers["Authorization"] == ( igwn_requests.scitoken_authorization_header(rtoken) ) @@ -133,11 +132,14 @@ serialized = rtoken.serialize() sess = self.Session(token=serialized) assert sess.headers["Authorization"] == f"Bearer {serialized}" + # will not deserialise a token for storage + assert sess.token is None @mock.patch("igwn_auth_utils.requests.find_scitoken") def test_token_discovery(self, find_token, rtoken): # noqa: F811 find_token.return_value = rtoken sess = self.Session() + assert sess.token is rtoken assert sess.headers["Authorization"] == ( igwn_requests.scitoken_authorization_header(rtoken) ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/igwn-auth-utils-0.2.3/igwn_auth_utils/tests/test_scitokens.py new/igwn-auth-utils-0.3.1/igwn_auth_utils/tests/test_scitokens.py --- old/igwn-auth-utils-0.2.3/igwn_auth_utils/tests/test_scitokens.py 2022-04-04 16:27:29.000000000 +0200 +++ new/igwn-auth-utils-0.3.1/igwn_auth_utils/tests/test_scitokens.py 2022-09-17 14:52:32.000000000 +0200 @@ -20,9 +20,10 @@ from ..error import IgwnAuthError ISSUER = "local" -AUDIENCE = "igwn_auth_utils" _SCOPE_PATH = "/igwn_auth_utils" +READ_AUDIENCE = "igwn_auth_utils" READ_SCOPE = "read:{}".format(_SCOPE_PATH) +WRITE_AUDIENCE = "igwn_auth_utils2" WRITE_SCOPE = "write:{}".format(_SCOPE_PATH) @@ -33,7 +34,7 @@ def _create_token( key=None, iss=ISSUER, - aud=AUDIENCE, + aud=READ_AUDIENCE, scope=READ_SCOPE, **kwargs ): @@ -74,6 +75,7 @@ def wtoken(private_key): return _create_token( key=private_key, + aud=WRITE_AUDIENCE, scope=WRITE_SCOPE, ) @@ -124,19 +126,23 @@ (None, True), # accept any scope )) def test_is_valid_token(rtoken, scope, validity): - assert igwn_scitokens.is_valid_token(rtoken, AUDIENCE, scope) is validity + assert igwn_scitokens.is_valid_token( + rtoken, + READ_AUDIENCE, + scope, + ) is validity def test_is_valid_token_invalid_path(rtoken): with pytest.raises(InvalidPathError): - igwn_scitokens.is_valid_token(rtoken, AUDIENCE, "read") + igwn_scitokens.is_valid_token(rtoken, READ_AUDIENCE, "read") def test_load_token_file(rtoken_path, rtoken, public_pem): assert_tokens_equal( igwn_scitokens.load_token_file( rtoken_path, - audience=AUDIENCE, + audience=READ_AUDIENCE, insecure=True, public_key=public_pem, ), @@ -153,7 +159,7 @@ os.environ[envname] = rtoken.serialize(lifetime=86400).decode("utf-8") assert_tokens_equal( igwn_scitokens.find_token( - audience=AUDIENCE, + audience=READ_AUDIENCE, scope=READ_SCOPE, insecure=True, public_key=public_pem, @@ -181,18 +187,17 @@ # and make sure we get the correct token back assert_tokens_equal( igwn_scitokens.find_token( - audience=AUDIENCE, + audience=READ_AUDIENCE, scope=READ_SCOPE, insecure=True, public_key=public_pem, + skip_errors=True, ), rtoken, ) @mock.patch.dict("os.environ") -# make sure a real token doesn't get in the way -@mock.patch("igwn_auth_utils.scitokens.SciToken.discover", _os_error) def test_find_token_condor_creds( rtoken, wtoken, @@ -200,38 +205,43 @@ condor_creds_path, ): os.environ["_CONDOR_CREDS"] = str(condor_creds_path) - for token, scope in ( - (rtoken, READ_SCOPE), - (wtoken, WRITE_SCOPE), + for token, aud, scope in ( + (rtoken, READ_AUDIENCE, READ_SCOPE), + (wtoken, WRITE_AUDIENCE, WRITE_SCOPE), ): + print("TEST", token, aud, scope) assert_tokens_equal( igwn_scitokens.find_token( - audience=AUDIENCE, + audience=aud, scope=scope, insecure=True, public_key=public_pem, + skip_errors=True, ), token, ) +@pytest.mark.parametrize(("audience", "msg"), [ + (READ_AUDIENCE, "could not find a valid SciToken"), + (WRITE_AUDIENCE, "Invalid audience"), +]) @mock.patch.dict("os.environ") # make sure a real token doesn't get in the way @mock.patch("igwn_auth_utils.scitokens.SciToken.discover", _os_error) -def test_find_token_error(rtoken, public_pem): +def test_find_token_error(rtoken, public_pem, audience, msg): # token with the wrong claims os.environ["SCITOKEN"] = rtoken.serialize().decode("utf-8") # check that we get an error with pytest.raises(IgwnAuthError) as exc: igwn_scitokens.find_token( - AUDIENCE, + audience, WRITE_SCOPE, insecure=True, public_key=public_pem, + skip_errors=False, ) - assert str(exc.value).startswith( - "could not find a valid SciToken", - ) + assert str(exc.value).startswith(msg) @mock.patch.dict("os.environ") @@ -251,7 +261,7 @@ # check that we get the normal error with pytest.raises(IgwnAuthError) as exc: igwn_scitokens.find_token( - AUDIENCE, + READ_AUDIENCE, READ_SCOPE, skip_errors=skip_errors, ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/igwn-auth-utils-0.2.3/igwn_auth_utils.egg-info/PKG-INFO new/igwn-auth-utils-0.3.1/igwn_auth_utils.egg-info/PKG-INFO --- old/igwn-auth-utils-0.2.3/igwn_auth_utils.egg-info/PKG-INFO 2022-06-21 17:02:04.000000000 +0200 +++ new/igwn-auth-utils-0.3.1/igwn_auth_utils.egg-info/PKG-INFO 2022-09-18 16:09:55.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: igwn-auth-utils -Version: 0.2.3 +Version: 0.3.1 Summary: Authorisation utilities for IGWN Home-page: https://git.ligo.org/computing/igwn-auth-utils Author: Duncan Macleod @@ -30,7 +30,6 @@ Requires-Python: >=3.6 Description-Content-Type: text/markdown Provides-Extra: docs -Provides-Extra: requests Provides-Extra: test Provides-Extra: lint License-File: LICENSE diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/igwn-auth-utils-0.2.3/igwn_auth_utils.egg-info/SOURCES.txt new/igwn-auth-utils-0.3.1/igwn_auth_utils.egg-info/SOURCES.txt --- old/igwn-auth-utils-0.2.3/igwn_auth_utils.egg-info/SOURCES.txt 2022-06-21 17:02:06.000000000 +0200 +++ new/igwn-auth-utils-0.3.1/igwn_auth_utils.egg-info/SOURCES.txt 2022-09-18 16:09:55.000000000 +0200 @@ -5,6 +5,7 @@ .readthedocs.yml LICENSE README.md +RELEASE.md igwn-auth-utils.spec pyproject.toml setup.cfg @@ -27,6 +28,9 @@ debian/source/format docs/conf.py docs/index.rst +docs/requests.rst +docs/scitokens.rst +docs/x509.rst docs/_static/css/igwnauthutils.css docs/_templates/autosummary/class.rst docs/_templates/autosummary/function.rst diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/igwn-auth-utils-0.2.3/igwn_auth_utils.egg-info/requires.txt new/igwn-auth-utils-0.3.1/igwn_auth_utils.egg-info/requires.txt --- old/igwn-auth-utils-0.2.3/igwn_auth_utils.egg-info/requires.txt 2022-06-21 17:02:05.000000000 +0200 +++ new/igwn-auth-utils-0.3.1/igwn_auth_utils.egg-info/requires.txt 2022-09-18 16:09:55.000000000 +0200 @@ -1,4 +1,6 @@ cryptography>=2.3 +requests>=2.14 +safe-netrc>=1.0.0 scitokens>=1.7.0 [docs] @@ -9,10 +11,6 @@ flake8>=3.7.0 flake8-bandit -[requests] -requests>=2.14 -safe-netrc>=1.0.0 - [test] pytest>=3.9.1 pytest-cov diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/igwn-auth-utils-0.2.3/setup.cfg new/igwn-auth-utils-0.3.1/setup.cfg --- old/igwn-auth-utils-0.2.3/setup.cfg 2022-06-21 17:02:06.152180000 +0200 +++ new/igwn-auth-utils-0.3.1/setup.cfg 2022-09-18 16:09:55.533328300 +0200 @@ -37,15 +37,14 @@ python_requires = >=3.6 install_requires = cryptography >=2.3 + requests >=2.14 + safe-netrc >=1.0.0 scitokens >=1.7.0 [options.extras_require] docs = sphinx >=4.0.0 sphinx-immaterial-igwn -requests = - requests >=2.14 - safe-netrc >=1.0.0 test = pytest >=3.9.1 pytest-cov