Metadata-Version: 2.4
Name: django-ecp-auth
Version: 0.1.0
Summary: Django authentication package using Electronic Digital Signatures (ECP/ЕЦП)
Author-email: ECP Auth Team <ecp-auth@example.com>
License: MIT License
        
        Copyright (c) 2026 ECP Auth Team
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Homepage, https://github.com/ecp-auth/django-ecp-auth
Project-URL: Documentation, https://github.com/ecp-auth/django-ecp-auth#readme
Project-URL: Repository, https://github.com/ecp-auth/django-ecp-auth
Project-URL: Issues, https://github.com/ecp-auth/django-ecp-auth/issues
Keywords: django,authentication,ecp,digital-signature,x509,certificate
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Web Environment
Classifier: Framework :: Django
Classifier: Framework :: Django :: 5.0
Classifier: Framework :: Django :: 6.0
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Security
Classifier: Topic :: Security :: Cryptography
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: Django>=5.0
Requires-Dist: cryptography>=42.0
Requires-Dist: pycryptodome>=3.20
Requires-Dist: asn1crypto>=1.5
Requires-Dist: certvalidator>=0.11
Requires-Dist: Jinja2>=3.1
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-django>=4.8; extra == "dev"
Requires-Dist: pytest-cov>=4.1; extra == "dev"
Requires-Dist: ruff>=0.3; extra == "dev"
Requires-Dist: mypy>=1.8; extra == "dev"
Dynamic: license-file

# django-ecp-auth

[![Python 3.12+](https://img.shields.io/badge/python-3.12%2B-blue.svg)](https://www.python.org/downloads/)
[![Django 5.0+](https://img.shields.io/badge/django-5.0%2B-green.svg)](https://www.djangoproject.com/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

**Django authentication package using Electronic Digital Signatures (ECP/ЕЦП).**

A reusable Django package that provides user authentication and registration using X.509 digital certificates and a challenge-response protocol. Built from scratch without any third-party ECP/signature libraries.

## Features

- 🔐 **PKCS#12 Certificate Authentication** — upload `.p12`/`.pfx` files for login
- 🛡️ **Challenge-Response Protocol** — secure nonce-based signature verification
- 📜 **X.509 Certificate Validation** — expiration, key usage, chain validation
- 🔑 **RSA & ECDSA Support** — SHA-256, SHA-384, SHA-512 hash algorithms
- 🧩 **Django Auth Backend** — integrates with Django's authentication system
- 🔗 **Custom Middleware** — ECP session management and cleanup
- 📋 **Django Admin** — manage user certificates from the admin panel
- 🎨 **Ready-to-use Templates** — Django DTL + Jinja2 templates included
- 📡 **Signals** — hook into auth events (login, logout, register)

## Installation

```bash
pip install django-ecp-auth
```

Or install from source:

```bash
git clone https://github.com/ecp-auth/django-ecp-auth.git
cd django-ecp-auth
pip install -e .
```

## Quick Start

### 1. Add to `INSTALLED_APPS`

```python
INSTALLED_APPS = [
    # ...
    'ecp_auth',
]
```

### 2. Add Authentication Backend

```python
AUTHENTICATION_BACKENDS = [
    'ecp_auth.backends.ECPAuthenticationBackend',
    'django.contrib.auth.backends.ModelBackend',  # Keep for admin login
]
```

### 3. Add Middleware

```python
MIDDLEWARE = [
    # ...
    'ecp_auth.middleware.ECPSessionMiddleware',
]
```

### 4. Include URL Patterns

```python
from django.urls import include, path

urlpatterns = [
    # ...
    path('auth/', include('ecp_auth.urls')),
]
```

### 5. Run Migrations

```bash
python manage.py migrate
```

### 6. Visit the Auth Pages

- **Login:** `http://localhost:8000/auth/login/`
- **Register:** `http://localhost:8000/auth/register/`

## Configuration

Add these settings to your `settings.py` (all are optional):

```python
# Challenge-Response
ECP_AUTH_CHALLENGE_TIMEOUT = 300        # Nonce timeout in seconds (default: 5 min)
ECP_AUTH_CHALLENGE_LENGTH = 32          # Nonce length in bytes (default: 32)

# Certificate Validation
ECP_AUTH_REQUIRE_KEY_USAGE = True       # Require digitalSignature key usage
ECP_AUTH_ALLOW_SELF_SIGNED = True       # Allow self-signed certificates
ECP_AUTH_VALIDATE_CHAIN = False         # Enable certificate chain validation
ECP_AUTH_TRUSTED_CA_DIR = '/path/to/ca/certs'  # Trusted CA directory

# Redirects
ECP_AUTH_LOGIN_REDIRECT_URL = '/'              # After login
ECP_AUTH_LOGOUT_REDIRECT_URL = '/auth/login/'  # After logout
```

## Authentication Flow

```
1. User uploads PKCS#12 file (.p12/.pfx) with password
2. Server extracts X.509 certificate and private key
3. Server validates the certificate (expiration, key usage, etc.)
4. Server generates a random challenge nonce
5. Server signs the nonce with the user's private key
6. User confirms the signature
7. Server verifies the signature against the certificate
8. User is authenticated and logged in
```

## Signals

Connect to authentication events:

```python
from ecp_auth.signals import ecp_login_success, ecp_user_registered

@receiver(ecp_login_success)
def on_ecp_login(sender, request, user, certificate_info, **kwargs):
    print(f"User {user.username} logged in via ECP")

@receiver(ecp_user_registered)
def on_ecp_register(sender, request, user, certificate_info, **kwargs):
    print(f"New user registered: {user.username}")
```

## Available Signals

| Signal | Arguments |
|--------|-----------|
| `ecp_login_success` | `request`, `user`, `certificate_info` |
| `ecp_login_failed` | `request`, `reason`, `certificate_info` |
| `ecp_user_registered` | `request`, `user`, `certificate_info` |
| `ecp_logout` | `request`, `user` |
| `ecp_certificate_linked` | `user`, `certificate_info` |

## Development

```bash
# Clone and install with dev dependencies
git clone https://github.com/ecp-auth/django-ecp-auth.git
cd django-ecp-auth
pip install -e ".[dev]"

# Run tests
pytest tests/ -v

# Run with coverage
pytest tests/ -v --cov=ecp_auth --cov-report=term-missing
```

## Dependencies

- **Django** ≥ 5.0
- **cryptography** ≥ 42.0
- **pycryptodome** ≥ 3.20
- **asn1crypto** ≥ 1.5
- **certvalidator** ≥ 0.11
- **Jinja2** ≥ 3.1

## License

MIT License. See [LICENSE](LICENSE) for details.
