SessionArmor 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,41 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ pypi-publish:
13
+ name: Upload release to PyPI
14
+ runs-on: ubuntu-latest
15
+ environment:
16
+ name: pypi
17
+ url: https://pypi.org/p/SessionArmor
18
+ permissions:
19
+ id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
20
+ contents: read
21
+ steps:
22
+ - name: Checkout code
23
+ uses: actions/checkout@v4
24
+
25
+ - name: Set up Python
26
+ uses: actions/setup-python@v5
27
+ with:
28
+ python-version: "3.12"
29
+
30
+ - name: Install build dependencies
31
+ run: |
32
+ python -m pip install --upgrade pip
33
+ pip install build
34
+
35
+ - name: Build package
36
+ run: python -m build
37
+
38
+ - name: Publish distribution 📦 to PyPI
39
+ uses: pypa/gh-action-pypi-publish@release/v1
40
+ with:
41
+ print_hash: true
@@ -0,0 +1,49 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [ "main" ]
6
+ pull_request:
7
+ branches: [ "main" ]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+
19
+ - name: Set up Python ${{ matrix.python-version }}
20
+ uses: actions/setup-python@v5
21
+ with:
22
+ python-version: ${{ matrix.python-version }}
23
+
24
+ - name: Install dependencies
25
+ run: |
26
+ python -m pip install --upgrade pip
27
+ pip install .[dev]
28
+
29
+ - name: Lint with ruff
30
+ run: |
31
+ ruff check src/session_armor tests
32
+
33
+ - name: Type check with mypy
34
+ run: |
35
+ mypy src/session_armor --ignore-missing-imports
36
+ continue-on-error: true
37
+
38
+ - name: Run tests with coverage
39
+ run: |
40
+ export PYTHONPATH=$PYTHONPATH:$(pwd)/src
41
+ pytest tests/ --cov=session_armor --cov-report=xml --cov-report=term-missing
42
+
43
+ - name: Upload coverage to Codecov
44
+ uses: codecov/codecov-action@v4
45
+ if: matrix.python-version == '3.12'
46
+ with:
47
+ files: ./coverage.xml
48
+ fail_ci_if_error: false
49
+ verbose: true
@@ -0,0 +1,94 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ *.manifest
31
+ *.spec
32
+
33
+ # Installer logs
34
+ pip-log.txt
35
+ pip-delete-this-directory.txt
36
+
37
+ # Unit test / coverage reports
38
+ htmlcov/
39
+ .tox/
40
+ .nox/
41
+ .coverage
42
+ .coverage.*
43
+ .cache
44
+ nosetests.xml
45
+ coverage.xml
46
+ *.cover
47
+ *.py,cover
48
+ .hypothesis/
49
+ .pytest_cache/
50
+ cover/
51
+
52
+ # Translations
53
+ *.mo
54
+ *.pot
55
+
56
+ # Django stuff:
57
+ *.log
58
+ local_settings.py
59
+ db.sqlite3
60
+ db.sqlite3-journal
61
+
62
+ # Environments
63
+ .env
64
+ .envrc
65
+ .venv
66
+ env/
67
+ venv/
68
+ ENV/
69
+ env.bak/
70
+ venv.bak/
71
+
72
+ # IDE
73
+ .idea/
74
+ .vscode/
75
+ *.swp
76
+ *.swo
77
+ *~
78
+
79
+ # mypy
80
+ .mypy_cache/
81
+ .dmypy.json
82
+ dmypy.json
83
+
84
+ # ruff
85
+ .ruff_cache/
86
+
87
+ # Pyre type checker
88
+ .pyre/
89
+
90
+ # pytype static type analyzer
91
+ .pytype/
92
+
93
+ # Cython debug symbols
94
+ cython_debug/
@@ -0,0 +1,20 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - 2026-05-22
11
+
12
+ ### Added
13
+ - **SessionSecurityMiddleware** — Client fingerprint binding (IP + User-Agent hash), absolute/idle session timeouts, JWT claim drift detection, session fixation prevention via `cycle_key()`.
14
+ - **AuditMiddleware** — Privacy-preserving audit trail for authenticated requests with request ID correlation, hashed IPs, sanitized log entries.
15
+ - **GateMiddleware** — Base class for building cacheable, hookable conditional gates (compliance, onboarding, feature flags, maintenance).
16
+ - **Utilities** — `get_client_ip()` with proxy-depth awareness, `hash_value()`, `sanitize_for_log()` with control character stripping, `is_authenticated()`.
17
+ - Full hook system on all three middleware classes for zero-subclass-needed customization.
18
+ - `SESSION_ARMOR_TRUSTED_PROXY_DEPTH` setting to prevent X-Forwarded-For spoofing.
19
+ - `fail_open=False` as defense-grade default on GateMiddleware.
20
+ - CI/CD with GitHub Actions (tests on Python 3.10–3.13, PyPI publishing via trusted publishing).
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024-2026 Alex C
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,174 @@
1
+ Metadata-Version: 2.4
2
+ Name: SessionArmor
3
+ Version: 0.1.0
4
+ Summary: Defense-grade Django middleware: session security, audit logging, and configurable request gates with hooks.
5
+ Project-URL: Homepage, https://github.com/Tunet-xyz/session_armor
6
+ Project-URL: Documentation, https://github.com/Tunet-xyz/session_armor#readme
7
+ Project-URL: Repository, https://github.com/Tunet-xyz/session_armor
8
+ Project-URL: Issues, https://github.com/Tunet-xyz/session_armor/issues
9
+ Project-URL: Changelog, https://github.com/Tunet-xyz/session_armor/blob/main/CHANGELOG.md
10
+ Author-email: Alex C <alex@coded.uk>
11
+ License-Expression: MIT
12
+ License-File: LICENSE
13
+ Keywords: audit,django,gates,middleware,nist,owasp,security,session
14
+ Classifier: Framework :: Django
15
+ Classifier: Framework :: Django :: 4.2
16
+ Classifier: Framework :: Django :: 5.0
17
+ Classifier: Intended Audience :: Developers
18
+ Classifier: License :: OSI Approved :: MIT License
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Topic :: Security
25
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
26
+ Requires-Python: >=3.10
27
+ Requires-Dist: django>=4.2
28
+ Provides-Extra: dev
29
+ Requires-Dist: django-stubs>=4.2.0; extra == 'dev'
30
+ Requires-Dist: mypy>=1.0.0; extra == 'dev'
31
+ Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
32
+ Requires-Dist: pytest-django>=4.5; extra == 'dev'
33
+ Requires-Dist: pytest>=8.0; extra == 'dev'
34
+ Requires-Dist: ruff>=0.4; extra == 'dev'
35
+ Description-Content-Type: text/markdown
36
+
37
+ # SessionArmor
38
+
39
+ [![Tests](https://github.com/Tunet-xyz/session_armor/actions/workflows/tests.yaml/badge.svg)](https://github.com/Tunet-xyz/session_armor/actions/workflows/tests.yaml)
40
+ [![PyPI version](https://badge.fury.io/py/SessionArmor.svg)](https://pypi.org/project/SessionArmor/)
41
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
42
+ [![Django 4.2+](https://img.shields.io/badge/django-4.2+-green.svg)](https://www.djangoproject.com/)
43
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
44
+
45
+ **Defense-grade Django middleware: session security, audit logging, and configurable request gates with hooks.**
46
+
47
+ Part of the [Tunet](https://github.com/Tunet-xyz) ecosystem — alongside [SwapLayer](https://github.com/Tunet-xyz/swap_layer) and [InfraGlyph](https://github.com/Tunet-xyz/infra_glyph).
48
+
49
+ ---
50
+
51
+ ## What It Does
52
+
53
+ SessionArmor provides three drop-in Django middleware classes that harden your application's session layer:
54
+
55
+ | Middleware | Purpose |
56
+ |-----------|---------|
57
+ | `SessionSecurityMiddleware` | Fingerprint binding, absolute/idle timeouts, claim drift detection |
58
+ | `AuditMiddleware` | Privacy-preserving security audit trail for every authenticated request |
59
+ | `GateMiddleware` | Base class for building cacheable conditional gates (compliance, onboarding, feature flags) |
60
+
61
+ All three are **hookable** — override methods to customize behavior without touching internals.
62
+
63
+ ## References
64
+
65
+ - [NIST SP 800-53 AC-12](https://csrc.nist.gov/publications/detail/sp/800-53/rev-5/final) (Session Termination)
66
+ - [NIST SP 800-53 SC-23](https://csrc.nist.gov/publications/detail/sp/800-53/rev-5/final) (Session Authenticity)
67
+ - [NIST SP 800-53 AU-3/AU-12](https://csrc.nist.gov/publications/detail/sp/800-53/rev-5/final) (Audit Content/Generation)
68
+ - [OWASP Session Management Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html)
69
+
70
+ ---
71
+
72
+ ## Installation
73
+
74
+ ```bash
75
+ pip install SessionArmor
76
+ ```
77
+
78
+ ## Quick Start
79
+
80
+ ```python
81
+ # settings.py
82
+ MIDDLEWARE = [
83
+ 'django.middleware.security.SecurityMiddleware',
84
+ 'django.contrib.sessions.middleware.SessionMiddleware',
85
+ # ... your auth middleware ...
86
+ 'session_armor.session.SessionSecurityMiddleware',
87
+ 'session_armor.audit.AuditMiddleware',
88
+ # ... rest of your middleware ...
89
+ ]
90
+
91
+ # Optional settings (shown with defaults)
92
+ SESSION_ABSOLUTE_TIMEOUT = 28800 # 8 hours
93
+ SESSION_IDLE_TIMEOUT = 1800 # 30 minutes
94
+ SESSION_BIND_IP = True
95
+ SESSION_BIND_USER_AGENT = True
96
+ SESSION_DETECT_CLAIM_DRIFT = True
97
+ SESSION_ARMOR_TRUSTED_PROXY_DEPTH = 1 # Number of trusted reverse proxies
98
+ ```
99
+
100
+ ## Building a Gate
101
+
102
+ ```python
103
+ from session_armor import GateMiddleware
104
+ from django.shortcuts import redirect
105
+
106
+ class ComplianceGate(GateMiddleware):
107
+ gate_id = 'compliance'
108
+ cache_ttl_setting = 'COMPLIANCE_CACHE_TTL'
109
+ default_cache_ttl = 3600
110
+ fail_open = False # Block access if check fails
111
+
112
+ def check(self, request) -> bool:
113
+ return user_accepted_current_terms(request)
114
+
115
+ def on_reject(self, request):
116
+ return redirect('/accept-terms/')
117
+ ```
118
+
119
+ ## Customizing Session Security
120
+
121
+ ```python
122
+ from session_armor import SessionSecurityMiddleware
123
+
124
+ class MySessionSecurity(SessionSecurityMiddleware):
125
+ exempt_paths = ('/health/', '/static/')
126
+
127
+ def get_critical_claims(self, user):
128
+ # Auth0 / OIDC claims that must not change mid-session
129
+ return [user.sub, user.organization_uuid, user.platform]
130
+
131
+ def get_login_url(self, request):
132
+ platform = getattr(request.user, 'platform', '')
133
+ return f'/{platform}/login/' if platform else '/login/'
134
+ ```
135
+
136
+ ## Customizing Audit Logging
137
+
138
+ ```python
139
+ from session_armor import AuditMiddleware
140
+
141
+ class MyAudit(AuditMiddleware):
142
+ exempt_paths = ('/health/', '/static/', '/favicon.ico')
143
+
144
+ def get_user_identity(self, request):
145
+ return {
146
+ 'uid': request.user.sub,
147
+ 'platform': request.user.platform,
148
+ 'org': request.user.organization_uuid,
149
+ }
150
+ ```
151
+
152
+ ---
153
+
154
+ ## Development
155
+
156
+ ```bash
157
+ # Clone and install
158
+ git clone https://github.com/Tunet-xyz/session_armor.git
159
+ cd session_armor
160
+ pip install -e ".[dev]"
161
+
162
+ # Run tests
163
+ pytest
164
+
165
+ # Lint
166
+ ruff check src/session_armor tests
167
+
168
+ # Type check
169
+ mypy src/session_armor
170
+ ```
171
+
172
+ ## License
173
+
174
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,138 @@
1
+ # SessionArmor
2
+
3
+ [![Tests](https://github.com/Tunet-xyz/session_armor/actions/workflows/tests.yaml/badge.svg)](https://github.com/Tunet-xyz/session_armor/actions/workflows/tests.yaml)
4
+ [![PyPI version](https://badge.fury.io/py/SessionArmor.svg)](https://pypi.org/project/SessionArmor/)
5
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
6
+ [![Django 4.2+](https://img.shields.io/badge/django-4.2+-green.svg)](https://www.djangoproject.com/)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+
9
+ **Defense-grade Django middleware: session security, audit logging, and configurable request gates with hooks.**
10
+
11
+ Part of the [Tunet](https://github.com/Tunet-xyz) ecosystem — alongside [SwapLayer](https://github.com/Tunet-xyz/swap_layer) and [InfraGlyph](https://github.com/Tunet-xyz/infra_glyph).
12
+
13
+ ---
14
+
15
+ ## What It Does
16
+
17
+ SessionArmor provides three drop-in Django middleware classes that harden your application's session layer:
18
+
19
+ | Middleware | Purpose |
20
+ |-----------|---------|
21
+ | `SessionSecurityMiddleware` | Fingerprint binding, absolute/idle timeouts, claim drift detection |
22
+ | `AuditMiddleware` | Privacy-preserving security audit trail for every authenticated request |
23
+ | `GateMiddleware` | Base class for building cacheable conditional gates (compliance, onboarding, feature flags) |
24
+
25
+ All three are **hookable** — override methods to customize behavior without touching internals.
26
+
27
+ ## References
28
+
29
+ - [NIST SP 800-53 AC-12](https://csrc.nist.gov/publications/detail/sp/800-53/rev-5/final) (Session Termination)
30
+ - [NIST SP 800-53 SC-23](https://csrc.nist.gov/publications/detail/sp/800-53/rev-5/final) (Session Authenticity)
31
+ - [NIST SP 800-53 AU-3/AU-12](https://csrc.nist.gov/publications/detail/sp/800-53/rev-5/final) (Audit Content/Generation)
32
+ - [OWASP Session Management Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html)
33
+
34
+ ---
35
+
36
+ ## Installation
37
+
38
+ ```bash
39
+ pip install SessionArmor
40
+ ```
41
+
42
+ ## Quick Start
43
+
44
+ ```python
45
+ # settings.py
46
+ MIDDLEWARE = [
47
+ 'django.middleware.security.SecurityMiddleware',
48
+ 'django.contrib.sessions.middleware.SessionMiddleware',
49
+ # ... your auth middleware ...
50
+ 'session_armor.session.SessionSecurityMiddleware',
51
+ 'session_armor.audit.AuditMiddleware',
52
+ # ... rest of your middleware ...
53
+ ]
54
+
55
+ # Optional settings (shown with defaults)
56
+ SESSION_ABSOLUTE_TIMEOUT = 28800 # 8 hours
57
+ SESSION_IDLE_TIMEOUT = 1800 # 30 minutes
58
+ SESSION_BIND_IP = True
59
+ SESSION_BIND_USER_AGENT = True
60
+ SESSION_DETECT_CLAIM_DRIFT = True
61
+ SESSION_ARMOR_TRUSTED_PROXY_DEPTH = 1 # Number of trusted reverse proxies
62
+ ```
63
+
64
+ ## Building a Gate
65
+
66
+ ```python
67
+ from session_armor import GateMiddleware
68
+ from django.shortcuts import redirect
69
+
70
+ class ComplianceGate(GateMiddleware):
71
+ gate_id = 'compliance'
72
+ cache_ttl_setting = 'COMPLIANCE_CACHE_TTL'
73
+ default_cache_ttl = 3600
74
+ fail_open = False # Block access if check fails
75
+
76
+ def check(self, request) -> bool:
77
+ return user_accepted_current_terms(request)
78
+
79
+ def on_reject(self, request):
80
+ return redirect('/accept-terms/')
81
+ ```
82
+
83
+ ## Customizing Session Security
84
+
85
+ ```python
86
+ from session_armor import SessionSecurityMiddleware
87
+
88
+ class MySessionSecurity(SessionSecurityMiddleware):
89
+ exempt_paths = ('/health/', '/static/')
90
+
91
+ def get_critical_claims(self, user):
92
+ # Auth0 / OIDC claims that must not change mid-session
93
+ return [user.sub, user.organization_uuid, user.platform]
94
+
95
+ def get_login_url(self, request):
96
+ platform = getattr(request.user, 'platform', '')
97
+ return f'/{platform}/login/' if platform else '/login/'
98
+ ```
99
+
100
+ ## Customizing Audit Logging
101
+
102
+ ```python
103
+ from session_armor import AuditMiddleware
104
+
105
+ class MyAudit(AuditMiddleware):
106
+ exempt_paths = ('/health/', '/static/', '/favicon.ico')
107
+
108
+ def get_user_identity(self, request):
109
+ return {
110
+ 'uid': request.user.sub,
111
+ 'platform': request.user.platform,
112
+ 'org': request.user.organization_uuid,
113
+ }
114
+ ```
115
+
116
+ ---
117
+
118
+ ## Development
119
+
120
+ ```bash
121
+ # Clone and install
122
+ git clone https://github.com/Tunet-xyz/session_armor.git
123
+ cd session_armor
124
+ pip install -e ".[dev]"
125
+
126
+ # Run tests
127
+ pytest
128
+
129
+ # Lint
130
+ ruff check src/session_armor tests
131
+
132
+ # Type check
133
+ mypy src/session_armor
134
+ ```
135
+
136
+ ## License
137
+
138
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,44 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ | Version | Supported |
6
+ | ------- | ------------------ |
7
+ | 0.1.x | :white_check_mark: |
8
+
9
+ ## Reporting a Vulnerability
10
+
11
+ We take security seriously. If you discover a security vulnerability in SessionArmor, please report it responsibly.
12
+
13
+ ### How to Report
14
+
15
+ **Please DO NOT open a public GitHub issue for security vulnerabilities.**
16
+
17
+ Instead, please email security concerns to: **alex@coded.uk**
18
+
19
+ Include the following in your report:
20
+ - Description of the vulnerability
21
+ - Steps to reproduce
22
+ - Potential impact
23
+ - Suggested fix (if any)
24
+
25
+ ### Response Timeline
26
+
27
+ - **Acknowledgement:** Within 48 hours
28
+ - **Initial assessment:** Within 5 business days
29
+ - **Fix release:** Within 30 days for critical issues
30
+
31
+ ### Scope
32
+
33
+ The following are in scope:
34
+ - Session fixation or hijacking bypasses
35
+ - Fingerprint binding bypasses
36
+ - Log injection via sanitization bypass
37
+ - X-Forwarded-For spoofing past proxy depth controls
38
+ - Any bypass of gate middleware security checks
39
+
40
+ ### Out of Scope
41
+
42
+ - Vulnerabilities in Django itself (report to Django security team)
43
+ - Issues requiring physical access to the server
44
+ - Social engineering attacks
@@ -0,0 +1,98 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [tool.hatch.build.targets.wheel]
6
+ packages = ["src/session_armor"]
7
+
8
+ [project]
9
+ name = "SessionArmor"
10
+ version = "0.1.0"
11
+ description = "Defense-grade Django middleware: session security, audit logging, and configurable request gates with hooks."
12
+ readme = "README.md"
13
+ requires-python = ">=3.10"
14
+ license = "MIT"
15
+ keywords = ["django", "middleware", "security", "session", "audit", "gates", "nist", "owasp"]
16
+ authors = [
17
+ { name = "Alex C", email = "alex@coded.uk" },
18
+ ]
19
+ classifiers = [
20
+ "Framework :: Django",
21
+ "Framework :: Django :: 4.2",
22
+ "Framework :: Django :: 5.0",
23
+ "Programming Language :: Python :: 3",
24
+ "Programming Language :: Python :: 3.10",
25
+ "Programming Language :: Python :: 3.11",
26
+ "Programming Language :: Python :: 3.12",
27
+ "Programming Language :: Python :: 3.13",
28
+ "License :: OSI Approved :: MIT License",
29
+ "Topic :: Security",
30
+ "Topic :: Software Development :: Libraries :: Python Modules",
31
+ "Intended Audience :: Developers",
32
+ ]
33
+ dependencies = [
34
+ "Django>=4.2",
35
+ ]
36
+
37
+ [project.optional-dependencies]
38
+ dev = [
39
+ "pytest>=8.0",
40
+ "pytest-django>=4.5",
41
+ "pytest-cov>=4.0.0",
42
+ "ruff>=0.4",
43
+ "mypy>=1.0.0",
44
+ "django-stubs>=4.2.0",
45
+ ]
46
+
47
+ [project.urls]
48
+ Homepage = "https://github.com/Tunet-xyz/session_armor"
49
+ Documentation = "https://github.com/Tunet-xyz/session_armor#readme"
50
+ Repository = "https://github.com/Tunet-xyz/session_armor"
51
+ Issues = "https://github.com/Tunet-xyz/session_armor/issues"
52
+ Changelog = "https://github.com/Tunet-xyz/session_armor/blob/main/CHANGELOG.md"
53
+
54
+ [tool.pytest.ini_options]
55
+ testpaths = ["tests"]
56
+ python_files = ["test_*.py"]
57
+ addopts = "-v --tb=short"
58
+ DJANGO_SETTINGS_MODULE = "tests.settings"
59
+
60
+ [tool.mypy]
61
+ python_version = "3.10"
62
+ warn_return_any = true
63
+ warn_unused_configs = true
64
+ disallow_untyped_defs = false
65
+ check_untyped_defs = true
66
+ plugins = ["mypy_django_plugin.main"]
67
+ ignore_missing_imports = true
68
+
69
+ [tool.django-stubs]
70
+ django_settings_module = "tests.settings"
71
+
72
+ [tool.ruff]
73
+ target-version = "py310"
74
+ line-length = 100
75
+
76
+ [tool.ruff.lint]
77
+ select = [
78
+ "E", # pycodestyle errors
79
+ "W", # pycodestyle warnings
80
+ "F", # pyflakes
81
+ "I", # isort
82
+ "B", # flake8-bugbear
83
+ "C4", # flake8-comprehensions
84
+ "UP", # pyupgrade
85
+ ]
86
+ ignore = [
87
+ "E501", # line too long (handled by formatter)
88
+ "B008", # do not perform function calls in argument defaults
89
+ "B904", # Within except clause, raise with from err
90
+ ]
91
+
92
+ [tool.ruff.lint.isort]
93
+ known-first-party = ["session_armor"]
94
+
95
+ [tool.coverage.run]
96
+ source = ["src/session_armor"]
97
+ branch = true
98
+ omit = ["*/tests/*", "*/__pycache__/*"]