Skip to content

Commit 053aa70

Browse files
Rename the library, support for DI, v1 🚀
1 parent 617840f commit 053aa70

54 files changed

Lines changed: 1484 additions & 878 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/build.yml

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ on:
1212
- "*"
1313

1414
env:
15-
PROJECT_NAME: guardpost
15+
PROJECT_NAME: neoteroi
1616

1717
jobs:
1818
build:
@@ -29,7 +29,7 @@ jobs:
2929
submodules: false
3030

3131
- name: Use Python ${{ matrix.python-version }}
32-
uses: actions/setup-python@v1
32+
uses: actions/setup-python@v3
3333
with:
3434
python-version: ${{ matrix.python-version }}
3535

@@ -61,8 +61,13 @@ jobs:
6161
6262
- name: Run tests
6363
run: |
64+
pip install -e .
6465
pytest --doctest-modules --junitxml=junit/pytest-results-${{ matrix.python-version }}.xml --cov=$PROJECT_NAME --cov-report=xml tests/
6566
67+
- name: Test examples
68+
run: |
69+
for f in ./examples/*.py; do echo "Processing $f file..." && python $f; done
70+
6671
- name: Upload pytest test results
6772
uses: actions/upload-artifact@master
6873
with:
@@ -75,19 +80,19 @@ jobs:
7580
bash <(curl -s https://codecov.io/bash)
7681
7782
- name: Install distribution dependencies
78-
run: pip install --upgrade twine setuptools wheel
79-
if: matrix.python-version == 3.8 || matrix.python-version == 3.9
83+
run: pip install --upgrade build
84+
if: matrix.python-version == 3.10
8085

8186
- name: Create distribution package
82-
run: python setup.py sdist bdist_wheel
83-
if: matrix.python-version == 3.8 || matrix.python-version == 3.9
87+
run: python -m build
88+
if: matrix.python-version == 3.10
8489

8590
- name: Upload distribution package
8691
uses: actions/upload-artifact@master
8792
with:
88-
name: dist-package-${{ matrix.python-version }}
93+
name: dist
8994
path: dist
90-
if: matrix.python-version == 3.8 || matrix.python-version == 3.9
95+
if: matrix.python-version == 3.10
9196

9297
publish:
9398
runs-on: ubuntu-latest
@@ -97,17 +102,28 @@ jobs:
97102
- name: Download a distribution artifact
98103
uses: actions/download-artifact@v2
99104
with:
100-
name: dist-package-3.9
105+
name: dist
101106
path: dist
102-
- name: Publish distribution 📦 to Test PyPI
103-
uses: pypa/gh-action-pypi-publish@master
107+
108+
- name: Use Python 3.11
109+
uses: actions/setup-python@v1
104110
with:
105-
skip_existing: true
106-
user: __token__
107-
password: ${{ secrets.test_pypi_password }}
108-
repository_url: https://test.pypi.org/legacy/
111+
python-version: '3.11'
112+
113+
- name: Install dependencies
114+
run: |
115+
pip install twine
116+
117+
- name: Publish distribution 📦 to Test PyPI
118+
run: |
119+
twine upload -r testpypi dist/*
120+
env:
121+
TWINE_USERNAME: __token__
122+
TWINE_PASSWORD: ${{ secrets.test_pypi_password2 }}
123+
109124
- name: Publish distribution 📦 to PyPI
110-
uses: pypa/gh-action-pypi-publish@master
111-
with:
112-
user: __token__
113-
password: ${{ secrets.pypi_password }}
125+
run: |
126+
twine upload -r pypi dist/*
127+
env:
128+
TWINE_USERNAME: __token__
129+
TWINE_PASSWORD: ${{ secrets.pypi_password2 }}

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@ __pycache__
66
*.egg-info
77
*.tar.gz
88
.mypy_cache
9+
junit
10+
coverage.xml

CHANGELOG.md

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,39 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.0.0] - 2022-12-xx :star:
9+
- Renames the library to `neoteroi-auth`.
10+
- Adopts PEP 420 and renames the main namespace from `guardpost` to `neoteroi.auth`
11+
- Adds built-in support for dependency injection, using the new `ContainerProtocol`
12+
in `neoteroi-di` (new version of `rodi`).
13+
- Removes the synchronous code API, maintaining only the asynchronous code API
14+
for `AuthenticationStrategy.authenticate` and `AuthorizationStrategy.authorize`.
15+
- Replaces `setup.py` with `pyproject.toml`.
16+
- Reduces imports verbosity.
17+
- Improves the `identity_getter` code API.
18+
- Corrects `Identity.__getitem__` to raise `KeyError` if a claim is missing.
19+
820
## [0.1.0] - 2022-11-06 :snake:
9-
- Workflow maintenance
21+
- Workflow maintenance.
1022

1123
## [0.0.9] - 2021-11-14 :swan:
12-
- Adds `sub`, `access_token`, and `refresh_token` properties to the `Identity`
24+
- Adds `sub`, `access_token`, and `refresh_token` properties to the `Identity`.
1325
class
14-
- Adds `py.typed` file
26+
- Adds `py.typed` file.
1527

1628
## [0.0.8] - 2021-10-31 :shield:
17-
- Adds classes to handle `JWT`s validation, but only for `RSA` keys
18-
- Fixes issue (wrong arrangement in test) #5
19-
- Includes `Python 3.10` in the CI/CD matrix
20-
- Enforces `black` and `isort` in the CI pipeline
29+
- Adds classes to handle `JWT`s validation, but only for `RSA` keys.
30+
- Fixes issue (wrong arrangement in test) #5.
31+
- Includes `Python 3.10` in the CI/CD matrix.
32+
- Enforces `black` and `isort` in the CI pipeline.
2133

2234
## [0.0.7] - 2021-01-31 :grapes:
23-
- Corrects a bug in the `Policy` class (#2)
24-
- Changes the type annotation of `Identity` claims (#3)
35+
- Corrects a bug in the `Policy` class (#2).
36+
- Changes the type annotation of `Identity` claims (#3).
2537

2638
## [0.0.6] - 2020-12-12 :octocat:
27-
- Completely migrates to GitHub Workflows
28-
- Improves build to test Python 3.6 and 3.9
29-
- Adds a changelog
30-
- Improves badges
31-
- Improves code quality using `flake8` and `black`
39+
- Completely migrates to GitHub Workflows.
40+
- Improves build to test Python 3.6 and 3.9.
41+
- Adds a changelog.
42+
- Improves badges.
43+
- Improves code quality using `flake8` and `black`.

MANIFEST.in

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

Makefile

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,63 @@
11
.PHONY: release test
22

33

4+
lint-types:
5+
mypy neoteroi --explicit-package-bases
6+
7+
48
artifacts: test
5-
python setup.py sdist bdist_wheel
9+
python -m build
610

711

812
clean:
913
rm -rf dist/
1014

1115

1216
prepforbuild:
13-
pip install --upgrade twine setuptools wheel
17+
pip install build
18+
1419

20+
build:
21+
python -m build
1522

16-
uploadtest:
17-
twine upload --repository-url https://test.pypi.org/legacy/ dist/*
1823

24+
test-release:
25+
twine upload --repository testpypi dist/*
1926

20-
release: clean artifacts
21-
twine upload --repository-url https://upload.pypi.org/legacy/ dist/*
27+
28+
release:
29+
twine upload --repository pypi dist/*
2230

2331

2432
test:
2533
python -m pytest
2634

2735

28-
testcov:
29-
python -m pytest --cov-report html --cov=guardpost tests/
36+
test-cov:
37+
python -m pytest --cov-report html --cov=neoteroi tests/
38+
39+
40+
lint: check-flake8 check-isort check-black
41+
42+
format:
43+
@isort neoteroi 2>&1
44+
@isort tests 2>&1
45+
@black neoteroi 2>&1
46+
@black tests 2>&1
47+
48+
check-flake8:
49+
@echo "$(BOLD)Checking flake8$(RESET)"
50+
@flake8 neoteroi 2>&1
51+
@flake8 tests 2>&1
52+
53+
54+
check-isort:
55+
@echo "$(BOLD)Checking isort$(RESET)"
56+
@isort --check-only neoteroi 2>&1
57+
@isort --check-only tests 2>&1
58+
59+
60+
check-black: ## Run the black tool in check mode only (won't modify files)
61+
@echo "$(BOLD)Checking black$(RESET)"
62+
@black --check neoteroi 2>&1
63+
@black --check tests 2>&1

README.md

Lines changed: 40 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,64 @@
11
[![Build](https://github.com/Neoteroi/guardpost/workflows/Build/badge.svg)](https://github.com/Neoteroi/guardpost/actions?query=workflow%3ABuild)
2-
[![pypi](https://img.shields.io/pypi/v/guardpost.svg?color=blue)](https://pypi.org/project/guardpost/)
3-
[![versions](https://img.shields.io/pypi/pyversions/guardpost.svg)](https://github.com/Neoteroi/guardpost)
4-
[![license](https://img.shields.io/github/license/Neoteroi/guardpost.svg)](https://github.com/Neoteroi/guardpost/blob/master/LICENSE)
5-
[![codecov](https://codecov.io/gh/Neoteroi/guardpost/branch/master/graph/badge.svg?token=sBKZG2D1bZ)](https://codecov.io/gh/Neoteroi/guardpost)
2+
[![pypi](https://img.shields.io/pypi/v/neoteroi-auth.svg?color=blue)](https://pypi.org/project/neoteroi-auth/)
3+
[![versions](https://img.shields.io/pypi/pyversions/neoteroi-auth.svg)](https://github.com/Neoteroi/guardpost)
4+
[![license](https://img.shields.io/github/license/Neoteroi/guardpost.svg)](https://github.com/Neoteroi/guardpost/blob/main/LICENSE)
5+
[![codecov](https://codecov.io/gh/Neoteroi/guardpost/branch/main/graph/badge.svg?token=sBKZG2D1bZ)](https://codecov.io/gh/Neoteroi/guardpost)
66

7-
# GuardPost
8-
GuardPost provides a basic framework to handle authentication and authorization
9-
in any kind of Python application.
7+
# Authentication and authorization framework for Python apps
8+
Basic framework to handle authentication and authorization in asynchronous
9+
Python applications.
10+
11+
**Features:**
12+
13+
- strategy to implement authentication (who or what is using a service?)
14+
- strategy to implement authorization (is the acting identity authorized to do a certain action?)
15+
- support for dependency injection for classes handling authentication and
16+
authorization requirements
17+
- built-in support for JSON Web Tokens (JWTs) authentication
18+
19+
This library is freely inspired by [authorization in ASP.NET
20+
Core](https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-2.2);
21+
although its implementation is extremely different.
22+
23+
## Installation
1024

1125
```bash
12-
pip install guardpost
26+
pip install neoteroi-auth
1327
```
1428

1529
To install with support for `JSON Web Tokens (JWTs)` validation:
1630

1731
```
18-
pip install guardpost[jwt]
32+
pip install neoteroi-auth[jwt]
1933
```
2034

21-
This library is freely inspired by [authorization in ASP.NET
22-
Core](https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-2.2);
23-
although its implementation is extremely different.
24-
25-
Notable differences are:
26-
1. GuardPost is abstracted from the code that executes it, so it's not bound to
27-
the context of a web framework.
28-
1. GuardPost implements both classes for use with synchronous code (not
29-
necessarily I/O bound), and classes using `async/await` syntax (optimized
30-
for authentication and authorization rules that involve I/O bound operations
31-
such as web requests and communications with databases).
32-
1. GuardPost leverages Python function decorators for the authorization part,
33-
so any function can be wrapped to be executed after handling authorization.
34-
1. The code API is simpler.
35-
36-
## More documentation and examples
37-
For documentation and
38-
[examples](https://github.com/RobertoPrevato/GuardPost/wiki/Examples), refer to
39-
the project [Wiki](https://github.com/RobertoPrevato/GuardPost/wiki).
40-
41-
To see how `guardpost` is used in `blacksheep` web framework, read the
42-
documentation here:
35+
### Examples
4336

44-
* [Authentication](https://www.neoteroi.dev/blacksheep/authentication/)
45-
* [Authorization](https://www.neoteroi.dev/blacksheep/authorization/)
46-
47-
## Both for async/await and synchronous code
48-
GuardPost can be used both with async/await code and with synchronous code,
49-
according to use cases and users' preference.
37+
For examples, refer to the [examples folder](./examples).
5038

5139
## If you have doubts about authentication vs authorization...
52-
`Authentication` answers the question: _Who is the user who is executing the
40+
`Authentication` answers the question: _Who is the user who is initiating the
5341
action?_, or more in general: _Who is the user, or what is the service, that is
54-
executing the action?_.
42+
initiating the action?_.
5543

5644
`Authorization` answers the question: _Is the user, or service, authorized to
5745
do something?_.
5846

5947
Usually, to implement authorization, is necessary to have the context of the
60-
entity that is executing the action. Anyway, the two things are logically
61-
separated and GuardPost is designed to keep them separate.
48+
entity that is executing the action.
6249

6350
## Usage in BlackSheep
64-
`guardpost` is used in the [BlackSheep](https://www.neoteroi.dev/blacksheep/)
65-
web framework to implement [authentication and authorization
51+
`neoteroi-auth` is used in the second version of the
52+
[BlackSheep](https://www.neoteroi.dev/blacksheep/) web framework, to implement
53+
[authentication and authorization
6654
strategies](https://www.neoteroi.dev/blacksheep/authentication/) for request
6755
handlers.
56+
57+
To see how `neoteroi-auth` is used in `blacksheep` web framework, read:
58+
59+
* [Authentication](https://www.neoteroi.dev/blacksheep/authentication/)
60+
* [Authorization](https://www.neoteroi.dev/blacksheep/authorization/)
61+
62+
# Documentation
63+
64+
Under construction. 🚧

examples-summary.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""
2+
Generates a README.md file for the examples folder.
3+
"""
4+
5+
import glob
6+
import importlib
7+
import sys
8+
9+
examples = [file for file in glob.glob("./examples/*.py")]
10+
examples.sort()
11+
sys.path.append("./examples")
12+
13+
with open("./examples/README.md", mode="wt", encoding="utf8 ") as examples_readme:
14+
examples_readme.write(
15+
"<!-- generated file, to update use: python examples-summary.py -->\n\n"
16+
)
17+
examples_readme.write("""# Examples""")
18+
19+
for file_path in examples:
20+
if "__init__" in file_path:
21+
continue
22+
23+
module_name = file_path.replace("./examples/", "").replace(".py", "")
24+
25+
module = importlib.import_module(module_name)
26+
27+
if not module.__doc__:
28+
continue
29+
30+
examples_readme.write(f"\n\n## {module_name}.py\n")
31+
examples_readme.write(str(module.__doc__))

0 commit comments

Comments
 (0)