Skip to content

Commit 86bcd9f

Browse files
committed
Update package to follow the latest draft
1 parent 8d615ea commit 86bcd9f

File tree

12 files changed

+272
-525
lines changed

12 files changed

+272
-525
lines changed

.github/FUNDING.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
github: [kislyuk]

.github/workflows/ci.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: Test
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
CI:
7+
name: Python ${{ matrix.python-version }}
8+
runs-on: ubuntu-20.04
9+
strategy:
10+
fail-fast: false
11+
max-parallel: 8
12+
matrix:
13+
python-version: ["3.7", "3.8", "3.9", "3.10"]
14+
15+
steps:
16+
- uses: actions/checkout@v2
17+
- name: Set up Python ${{ matrix.python-version }}
18+
uses: actions/setup-python@v2
19+
with:
20+
python-version: ${{ matrix.python-version }}
21+
- name: Install build dependencies
22+
run: pip install build wheel
23+
- name: Install package
24+
run: pip install .[tests]
25+
- name: Test
26+
run: make test

.github/workflows/pythonpackage.yml

Lines changed: 0 additions & 27 deletions
This file was deleted.

Makefile

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,22 @@
1-
test_deps:
2-
pip install coverage flake8 wheel
1+
SHELL=/bin/bash
32

4-
lint: test_deps
5-
flake8 $$(python setup.py --name | sed 's/-/_/g')
3+
lint:
4+
flake8
65

7-
test: test_deps lint
8-
coverage run --source=$$(python setup.py --name | sed 's/-/_/g') ./test/test.py
6+
test: lint
7+
python ./test/test.py -v
98

109
init_docs:
1110
cd docs; sphinx-quickstart
1211

1312
docs:
14-
$(MAKE) -C docs html
13+
sphinx-build docs docs/html
1514

16-
install: clean
17-
pip install wheel
18-
python setup.py bdist_wheel
15+
install:
16+
-rm -rf dist
17+
python -m build
1918
pip install --upgrade dist/*.whl
2019

21-
clean:
22-
-rm -rf build dist
23-
-rm -rf *.egg-info
24-
25-
.PHONY: lint test test_deps docs install clean
20+
.PHONY: test lint release docs
2621

2722
include common.mk

README.rst

Lines changed: 44 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@ requests-http-signature: A Requests auth module for HTTP Signature
22
==================================================================
33
**requests-http-signature** is a `Requests <https://github.com/requests/requests>`_ `authentication plugin
44
<http://docs.python-requests.org/en/master/user/authentication/>`_ (``requests.auth.AuthBase`` subclass) implementing
5-
the `IETF HTTP Signatures draft RFC <https://tools.ietf.org/html/draft-richanna-http-message-signatures>`_. It has no
6-
required dependencies outside the standard library. If you wish to use algorithms other than HMAC (namely, RSA and
7-
ECDSA algorithms specified in the RFC), there is an optional dependency on
8-
`cryptography <https://pypi.python.org/pypi/cryptography>`_.
5+
the `IETF HTTP Message Signatures draft RFC <https://datatracker.ietf.org/doc/draft-ietf-httpbis-message-signatures/>`_.
96

107
Installation
118
------------
@@ -19,65 +16,74 @@ Usage
1916
.. code-block:: python
2017
2118
import requests
22-
from requests_http_signature import HTTPSignatureAuth
19+
from requests_http_signature import HTTPSignatureAuth, algorithms
2320
2421
preshared_key_id = 'squirrel'
25-
preshared_secret = 'monorail_cat'
22+
preshared_secret = b'monorail_cat'
2623
url = 'http://example.com/path'
27-
28-
requests.get(url, auth=HTTPSignatureAuth(key=preshared_secret, key_id=preshared_key_id))
2924
30-
By default, only the ``Date`` header is signed (as per the RFC) for body-less requests such as GET. The ``Date`` header
31-
is set if it is absent. In addition, for requests with bodies (such as POST), the ``Digest`` header is set to the SHA256
32-
of the request body and signed (an example of this appears in the RFC). To add other headers to the signature, pass an
33-
array of header names in the ``headers`` keyword argument.
25+
auth = HTTPSignatureAuth(key=preshared_secret, key_id=preshared_key_id, signature_algorithm=algorithms.HMAC_SHA256)
26+
requests.get(url, auth=auth)
27+
28+
By default, only the ``Date`` header and the ``@method``, ``@authority``, and ``@target-uri`` derived component
29+
identifiers are signed for body-less requests such as GET. The ``Date`` header is set if it is absent. In addition, for
30+
requests with bodies (such as POST), the ``Content-Digest`` header is set to the SHA256 of the request body using the
31+
format described in the
32+
`IETF Digest Fields draft RFC <https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-digest-headers>`_ and signed.
33+
To add other headers to the signature, pass an array of header names in the ``covered_component_ids`` keyword argument.
3434

3535
In addition to signing messages in the client, the class method ``HTTPSignatureAuth.verify()`` can be used to verify
3636
incoming requests:
3737

3838
.. code-block:: python
3939
40-
def key_resolver(key_id, algorithm):
41-
return 'monorail_cat'
40+
class key_resolver:
41+
def resolve_public_key(self, key_id):
42+
assert key_id == 'squirrel'
43+
return 'monorail_cat'
44+
45+
HTTPSignatureAuth.verify(request, signature_algorithm=algorithms.HMAC_SHA256, key_resolver=key_resolver)
46+
4247
43-
HTTPSignatureAuth.verify(request, key_resolver=key_resolver)
48+
Asymmetric key algorithms
49+
~~~~~~~~~~~~~~~~~~~~~~~~~
50+
To sign or verify messages with an asymmetric key algorithm, set the ``signature_algorithm`` keyword argument to
51+
``algorithms.ED25519``, ``algorithms.ECDSA_P256_SHA256``, ``algorithms.RSA_V1_5_SHA256``, or
52+
``algorithms.RSA_PSS_SHA512``. Note that signing with rsa-pss-sha512 is not currently supported due to a limitation of
53+
the cryptography library.
4454

45-
Asymmetric key algorithms (RSA and ECDSA)
46-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
47-
For asymmetric key algorithms, you should supply the private key as the ``key`` parameter to the ``HTTPSignatureAuth()``
48-
constructor as bytes in the PEM format:
55+
For asymmetric key algorithms, you can supply the private key as the ``key`` parameter to the ``HTTPSignatureAuth()``
56+
constructor as bytes in the PEM format, or configure the key resolver as follows:
4957

5058
.. code-block:: python
5159
5260
with open('key.pem', 'rb') as fh:
53-
requests.get(url, auth=HTTPSignatureAuth(algorithm="rsa-sha256", key=fh.read(), key_id=preshared_key_id))
61+
auth = HTTPSignatureAuth(algorithm=algorithms.RSA_V1_5_SHA256, key=fh.read(), key_id=preshared_key_id)
62+
requests.get(url, auth=auth)
5463
55-
When verifying, the ``key_resolver()`` callback should provide the public key as bytes in the PEM format as well.
64+
class MyKeyResolver:
65+
def resolve_public_key(self, key_id: str):
66+
return public_key_pem_bytes[key_id]
67+
68+
def resolve_private_key(self, key_id: str):
69+
return private_key_pem_bytes[key_id]
70+
71+
auth = HTTPSignatureAuth(algorithm=algorithms.RSA_V1_5_SHA256, key=fh.read(), key_resolver=MyKeyResolver())
72+
requests.get(url, auth=auth)
5673
5774
Links
5875
-----
59-
* `IETF HTTP Signatures draft <https://tools.ietf.org/html/draft-richanna-http-message-signatures>`_
60-
* https://github.com/joyent/node-http-signature
61-
* `Project home page (GitHub) <https://github.com/kislyuk/requests-http-signature>`_
62-
* `Documentation (Read the Docs) <https://requests-http-signature.readthedocs.io/en/latest/>`_
76+
* `IETF HTTP Signatures draft <https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-message-signatures>`_
77+
* `http-message-signatures <https://github.com/pyauth/http-message-signatures>`_ - a dependency of this library that
78+
handles much of the implementation
79+
* `Project home page (GitHub) <https://github.com/pyauth/requests-http-signature>`_
6380
* `Package distribution (PyPI) <https://pypi.python.org/pypi/requests-http-signature>`_
64-
* `Change log <https://github.com/kislyuk/requests-http-signature/blob/master/Changes.rst>`_
81+
* `Change log <https://github.com/pyauth/requests-http-signature/blob/master/Changes.rst>`_
6582

6683
Bugs
6784
~~~~
68-
Please report bugs, issues, feature requests, etc. on `GitHub <https://github.com/kislyuk/requests-http-signature/issues>`_.
85+
Please report bugs, issues, feature requests, etc. on `GitHub <https://github.com/pyauth/requests-http-signature/issues>`_.
6986

7087
License
7188
-------
7289
Licensed under the terms of the `Apache License, Version 2.0 <http://www.apache.org/licenses/LICENSE-2.0>`_.
73-
74-
.. image:: https://github.com/pyauth/requests-http-signature/workflows/Python%20package/badge.svg
75-
:target: https://github.com/pyauth/requests-http-signature/actions
76-
.. image:: https://codecov.io/github/kislyuk/requests-http-signature/coverage.svg?branch=master
77-
:target: https://codecov.io/github/kislyuk/requests-http-signature?branch=master
78-
.. image:: https://img.shields.io/pypi/v/requests-http-signature.svg
79-
:target: https://pypi.python.org/pypi/requests-http-signature
80-
.. image:: https://img.shields.io/pypi/l/requests-http-signature.svg
81-
:target: https://pypi.python.org/pypi/requests-http-signature
82-
.. image:: https://readthedocs.org/projects/requests-http-signature/badge/?version=latest
83-
:target: https://requests-http-signature.readthedocs.org/

common.mk

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,31 @@
11
SHELL=/bin/bash -eo pipefail
22

3-
release_major:
3+
release-major:
44
$(eval export TAG=$(shell git describe --tags --match 'v*.*.*' | perl -ne '/^v(\d+)\.(\d+)\.(\d+)/; print "v@{[$$1+1]}.0.0"'))
55
$(MAKE) release
66

7-
release_minor:
7+
release-minor:
88
$(eval export TAG=$(shell git describe --tags --match 'v*.*.*' | perl -ne '/^v(\d+)\.(\d+)\.(\d+)/; print "v$$1.@{[$$2+1]}.0"'))
99
$(MAKE) release
1010

11-
release_patch:
11+
release-patch:
1212
$(eval export TAG=$(shell git describe --tags --match 'v*.*.*' | perl -ne '/^v(\d+)\.(\d+)\.(\d+)/; print "v$$1.$$2.@{[$$3+1]}"'))
1313
$(MAKE) release
1414

1515
release:
16-
@if [[ -z $$TAG ]]; then echo "Use release_{major,minor,patch}"; exit 1; fi
17-
$(eval REMOTE=$(shell git remote get-url origin | perl -ne '/([^\/\:]+\/.+?)(\.git)?$$/; print $$1'))
16+
@if ! git diff --cached --exit-code; then echo "Commit staged files before proceeding"; exit 1; fi
17+
@if [[ -z $$TAG ]]; then echo "Use release-{major,minor,patch}"; exit 1; fi
18+
@if ! type -P pandoc; then echo "Please install pandoc"; exit 1; fi
19+
@if ! type -P sponge; then echo "Please install moreutils"; exit 1; fi
20+
@if ! type -P http; then echo "Please install httpie"; exit 1; fi
21+
@if ! type -P twine; then echo "Please install twine"; exit 1; fi
22+
$(eval REMOTE=$(shell git remote get-url origin | perl -ne '/([^\/\:]+\/[^\/\:]+?)(\.git)?$$/; print $$1'))
1823
$(eval GIT_USER=$(shell git config --get user.email))
1924
$(eval GH_AUTH=$(shell if grep -q '@github.com' ~/.git-credentials; then echo $$(grep '@github.com' ~/.git-credentials | python3 -c 'import sys, urllib.parse as p; print(p.urlparse(sys.stdin.read()).netloc.split("@")[0])'); else echo $(GIT_USER); fi))
2025
$(eval RELEASES_API=https://api.github.com/repos/${REMOTE}/releases)
2126
$(eval UPLOADS_API=https://uploads.github.com/repos/${REMOTE}/releases)
2227
git pull
2328
git clean -x --force $$(python setup.py --name)
24-
sed -i -e "s/version=\([\'\"]\)[0-9]*\.[0-9]*\.[0-9]*/version=\1$${TAG:1}/" setup.py
25-
git add setup.py
2629
TAG_MSG=$$(mktemp); \
2730
echo "# Changes for ${TAG} ($$(date +%Y-%m-%d))" > $$TAG_MSG; \
2831
git log --pretty=format:%s $$(git describe --abbrev=0)..HEAD >> $$TAG_MSG; \
@@ -32,15 +35,15 @@ release:
3235
git commit -m ${TAG}; \
3336
git tag --sign --annotate --file $$TAG_MSG ${TAG}
3437
git push --follow-tags
35-
http --auth ${GH_AUTH} ${RELEASES_API} tag_name=${TAG} name=${TAG} \
38+
http --check-status --auth ${GH_AUTH} ${RELEASES_API} tag_name=${TAG} name=${TAG} \
3639
body="$$(git tag --list ${TAG} -n99 | perl -pe 's/^\S+\s*// if $$. == 1' | sed 's/^\s\s\s\s//')"
3740
$(MAKE) install
38-
http --auth ${GH_AUTH} POST ${UPLOADS_API}/$$(http --auth ${GH_AUTH} ${RELEASES_API}/latest | jq .id)/assets \
41+
http --check-status --auth ${GH_AUTH} POST ${UPLOADS_API}/$$(http --auth ${GH_AUTH} ${RELEASES_API}/latest | jq .id)/assets \
3942
name==$$(basename dist/*.whl) label=="Python Wheel" < dist/*.whl
40-
$(MAKE) pypi_release
43+
$(MAKE) release-pypi
4144

42-
pypi_release:
43-
python setup.py sdist bdist_wheel
45+
release-pypi:
46+
python -m build
4447
twine upload dist/*.tar.gz dist/*.whl --sign --verbose
4548

4649
.PHONY: release

docs/Makefile

Lines changed: 0 additions & 20 deletions
This file was deleted.

0 commit comments

Comments
 (0)