Skip to content

Commit

Permalink
Merge pull request #1 from feteu/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
feteu authored Jan 12, 2025
2 parents c7c8ea5 + 261744e commit 8dd7591
Show file tree
Hide file tree
Showing 26 changed files with 2,900 additions and 0 deletions.
29 changes: 29 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Build Python 🐍 distribution 📦

on: workflow_call

jobs:

build:
name: Build the Magic Python 🧙‍♂️ Distribution 📦
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Set up the Python Wizardry 🧙‍♂️
uses: actions/setup-python@v5
with:
python-version: "3.13"
- name: Install the Build Potion 🧪
run: |
pip install build
- name: Concoct the Binary Wheel and Source Tarball 🧙‍♀️
run: |
python -m build
- name: Store the Magical Packages 🧳
uses: actions/upload-artifact@v4
with:
name: python-package-distributions
path: dist/
59 changes: 59 additions & 0 deletions .github/workflows/publish-pypi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: Publish Python 🐍 distribution 📦 to PyPI

on:
workflow_dispatch:

jobs:
build:
uses: ./.github/workflows/build.yaml

publish-to-pypi:
name: Teleport Python 🐍 Distribution 📦 to PyPI
needs: build
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/p/asgi-claim-validator
permissions:
id-token: write

steps:
- name: Summon the Distribution Artifacts 🧙‍♂️
uses: actions/download-artifact@v4
with:
name: python-package-distributions
path: dist/
- name: Cast the Publish Spell 📦 to PyPI
uses: pypa/gh-action-pypi-publish@67339c736fd9354cd4f8cb0b744f2b82a74b5c70

github-release:
name: Enchant the Python 🐍 Distribution 📦 with Sigstore and Upload to GitHub Release
needs: publish-to-pypi
runs-on: ubuntu-latest

permissions:
contents: write
id-token: write

steps:
- name: Summon the Distribution Artifacts 🧙‍♂️
uses: actions/download-artifact@v4
with:
name: python-package-distributions
path: dist/
- name: Enchant the Artifacts with Sigstore ✨
uses: sigstore/gh-action-sigstore-python@f514d46b907ebcd5bedc05145c03b69c1edd8b46
with:
inputs: >-
./dist/*.tar.gz
./dist/*.whl
- name: Create the GitHub Release 🎉
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
gh release create "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" --notes ""
- name: Upload the Enchanted Artifacts to GitHub Release 🧳
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
gh release upload "$GITHUB_REF_NAME" dist/** --repo "$GITHUB_REPOSITORY"
31 changes: 31 additions & 0 deletions .github/workflows/publish-testpypi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Publish Python 🐍 distribution 📦 to TestPyPI

on:
push:
branches:
- main

jobs:
build:
uses: ./.github/workflows/build.yaml

publish-to-testpypi:
name: Teleport Python 🐍 Distribution 📦 to TestPyPI
needs: build
runs-on: ubuntu-latest
environment:
name: testpypi
url: https://test.pypi.org/p/asgi-claim-validator
permissions:
id-token: write

steps:
- name: Summon the Distribution Artifacts 🧙‍♂️
uses: actions/download-artifact@v4
with:
name: python-package-distributions
path: dist/
- name: Cast the Publish Spell 📦 to TestPyPI
uses: pypa/gh-action-pypi-publish@67339c736fd9354cd4f8cb0b744f2b82a74b5c70
with:
repository-url: https://test.pypi.org/legacy/
43 changes: 43 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
on:
pull_request:
push:
branches:
- main

jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version:
- 3.11
- 3.12
- 3.13
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v5
with:
python-version: "${{ matrix.python-version }}"
- name: Create a Python Wonderland 🐍✨
run: |
python -m venv .venv
source .venv/bin/activate
- name: Pimp My Pip 🚀🎩
run: |
source .venv/bin/activate
pip install --upgrade pip
- name: Dependency Party 🎉📦
run: |
source .venv/bin/activate
pip install poetry
rm poetry.lock
poetry install --no-interaction --no-root
- name: Install the app 📲🚀
run: |
source .venv/bin/activate
poetry install --no-interaction
- name: Test Fest 🎈✅
run: |
source .venv/bin/activate
poetry run pytest -c pytest.ini
74 changes: 74 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Contributing to ASGI Claim Validator

Thanks for thinking about contributing to ASGI Request Duration! I welcome your help and can't wait to see what you'll bring to the table.

## How to Contribute

### Reporting Bugs

Found a bug? Report it by opening an issue on my [GitHub Issues](https://github.com/feteu/asgi-claim-validator/issues) page. The more details, the better!

### Feature Requests

Got a brilliant idea for a new feature? Open an issue on the [GitHub Issues](https://github.com/feteu/asgi-claim-validator/issues) page. Let's collaborate to enhance this project together.

### Submitting Changes

1. **Fork it**: Click the "Fork" button.
2. **Clone it**: Clone your fork.
```sh
git clone https://github.com/your-username/asgi-claim-validator.git
```
3. **Branch it**: Create a new branch.
```sh
git checkout -b my-awesome-feature
```
4. **Change it**: Make your magic happen.
5. **Commit it**: Commit with style.
```sh
git commit -m "My awesome changes"
```
6. **Push it**: Push to your fork.
```sh
git push origin my-awesome-feature
```
7. **Pull it**: Open a pull request. Describe your awesomeness.

### Setting Up the Development Environment

1. **Clone the repository**:
```sh
git clone https://github.com/feteu/asgi-claim-validator.git
cd asgi-claim-validator
```
2. **Install dependencies using Poetry**:
```sh
poetry install
```

### Running Tests

Run the tests using `pytest`:
```sh
poetry run pytest
```

### Code Style

Maintain a clean and consistent code style. Adhere to the existing conventions. If you notice any errors or areas for improvement, please correct them or let me know. I'm always eager to learn and improve.
### Documentation
Update the docs if you change or add something. Keep everyone in the loop.
## Need Help?
Open an issue on the [GitHub Issues](https://github.com/feteu/asgi-claim-validator/issues) page. I'll do my best to help.

## Reviewing Pull Requests

I'll review your pull request ASAP. Thanks for your patience!
## Acknowledgements
Thanks for contributing! Your support makes this project rock.
15 changes: 15 additions & 0 deletions COPYRIGHT
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
asgi-claim-validator
Copyright (C) 2024 Fabio Greco

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
121 changes: 121 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,123 @@
[![PyPI - License](https://img.shields.io/pypi/l/asgi-claim-validator)](https://www.gnu.org/licenses/gpl-3.0)
[![PyPI - Version](https://img.shields.io/pypi/v/asgi-claim-validator.svg)](https://pypi.org/project/asgi-claim-validator/)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/asgi-claim-validator)](https://pypi.org/project/asgi-claim-validator/)
[![PyPI - Status](https://img.shields.io/pypi/status/asgi-claim-validator)](https://pypi.org/project/asgi-claim-validator/)
[![Dependencies](https://img.shields.io/librariesio/release/pypi/asgi-claim-validator)](https://libraries.io/pypi/asgi-claim-validator)
[![Last Commit](https://img.shields.io/github/last-commit/feteu/asgi-claim-validator)](https://github.com/feteu/asgi-claim-validator/commits/main)
[![Build Status build/testpypi](https://img.shields.io/github/actions/workflow/status/feteu/asgi-claim-validator/publish-testpypi.yaml?label=publish-testpypi)](https://github.com/feteu/asgi-claim-validator/actions/workflows/publish-testpypi.yaml)
[![Build Status build/pypi](https://img.shields.io/github/actions/workflow/status/feteu/asgi-claim-validator/publish-pypi.yaml?label=publish-pypi)](https://github.com/feteu/asgi-claim-validator/actions/workflows/publish-pypi.yaml)
[![Build Status test](https://img.shields.io/github/actions/workflow/status/feteu/asgi-claim-validator/test.yaml?label=test)](https://github.com/feteu/asgi-claim-validator/actions/workflows/test.yaml)

# asgi-claim-validator

A focused ASGI middleware for validating additional claims within JWT tokens to enhance token-based workflows.

## Overview

`asgi-claim-validator` is an ASGI middleware designed to validate additional claims within JWT tokens. Built in addition to the default JWT verification implementation of Connexion, it enhances token-based workflows by ensuring that specific claims are present and meet certain criteria before allowing access to protected endpoints. This middleware allows consumers to validate claims on an endpoint/method level and is compatible with popular ASGI frameworks such as Starlette, FastAPI, and Connexion.

## Features

- **Claim Validation**: Validate specific claims within JWT tokens, such as `sub`, `iss`, `aud`, `exp`, `iat`, and `nbf`.
- **Customizable Claims**: Define essential claims, allowed values, and whether blank values are permitted.
- **Path and Method Filtering**: Apply claim validation to specific paths and HTTP methods.
- **Exception Handling**: Integrate with custom exception handlers to provide meaningful error responses.
- **Logging**: Log validation errors for debugging and monitoring purposes.

## Installation

Install the package using pip:

```sh
pip install asgi-claim-validator
```

## Usage

### Basic Usage

Here's an example of how to use `asgi-claim-validator` with Starlette:

```python
from starlette.applications import Starlette
from starlette.requests import Request
from starlette.responses import JSONResponse
from starlette.routing import Route
from asgi_claim_validator import ClaimValidatorMiddleware

async def secured_endpoint(request: Request) -> JSONResponse:
return JSONResponse({"message": "secured"})

app = Starlette(routes=[
Route("/secured", secured_endpoint, methods=["GET"]),
])

app.add_middleware(
ClaimValidatorMiddleware,
claims_callable=lambda: {
"sub": "admin",
"iss": "https://example.com",
},
secured={
"^/secured$": {
"GET": {
"sub": {
"essential": True,
"allow_blank": False,
"values": ["admin"],
},
"iss": {
"essential": True,
"allow_blank": False,
"values": ["https://example.com"],
},
},
}
},
)
```

## Advanced Usage

### Custom Exception Handlers

Integrate `asgi-claim-validator` with custom exception handlers to provide meaningful error responses. Below are examples for Starlette and Connexion. Refer to the specific framework examples in the [examples](examples) directory for detailed implementation.

### Middleware Configuration

Configure the middleware with the following options:

- **claims_callable**: A callable that returns the JWT claims to be validated.
- **secured**: A dictionary defining the paths and methods that require claim validation.
- **skipped**: A dictionary defining the paths and methods to be excluded from claim validation.
- **raise_on_unspecified_path**: Raise an exception if the path is not specified in the `secured` or `skipped` dictionaries.
- **raise_on_unspecified_method**: Raise an exception if the method is not specified for a secured path.

### Claim Validation Options

Configure claims with the following options:

- **essential**: Indicates if the claim is essential (default: `False`).
- **allow_blank**: Indicates if blank values are allowed (default: `True`).
- **values**: A list of allowed values for the claim.

## Examples

### Starlette Example
Refer to the [app.py](examples/starlette/simple/app.py) file for a complete example using Starlette.

### Connexion Example
Refer to the [app.py](examples/connexion/simple/app.py) file for a complete example using Connexion.

## Testing
Run the tests using `pytest`:

```sh
poetry run pytest
```

## Contributing
Contributions are welcome! Please refer to the [CONTRIBUTING.md](CONTRIBUTING.md) file for guidelines on how to contribute to this project.

## License
This project is licensed under the GNU GPLv3 License. See the [LICENSE](LICENSE) file for more details.
Loading

0 comments on commit 8dd7591

Please sign in to comment.