Metadata-Version: 2.4
Name: python-auth-toolkit
Version: 0.2.0
Summary: All-in-one Python authentication toolkit: password validation, password hashing, email validation, JWT handling, rate limiting, and signup/signin orchestration.
Author: Vinod Kumar
Maintainer: Vinod Kumar
License: MIT
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: bcrypt>=4.0
Requires-Dist: argon2-cffi>=21.3
Requires-Dist: email-validator>=2.0
Requires-Dist: PyJWT>=2.0.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Requires-Dist: mypy; extra == "dev"
Requires-Dist: cryptography; extra == "dev"
Dynamic: license-file

# python-auth-toolkit

[![PyPI version](https://img.shields.io/pypi/v/python-auth-toolkit.svg)](https://pypi.org/project/python-auth-toolkit/)
[![Python versions](https://img.shields.io/pypi/pyversions/python-auth-toolkit.svg)](https://pypi.org/project/python-auth-toolkit/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

An all-in-one, highly secure, and configurable Python authentication toolkit. It provides robust password strength validation, secure password hashing (Bcrypt & Argon2), email validation/normalization, JWT handling, sliding window rate limiting, and sign-in/sign-up orchestrators.

---

## Features

- **Password Validator**: Fully customizable complexity rules (length, casing, digits, special characters, and common password blocklist).
- **Password Hasher**: Secure password hashing supporting **Bcrypt** and **Argon2id** with timing-safe verification and re-hashing checks.
- **Email Validator**: RFC 5322 compliant syntax validation, unicode NFC normalization, disposable domain blocking, and optional DNS/MX deliverability checks.
- **JWT Handler**: Stateless HS256/RS256 JSON Web Token generation and validation, access/refresh token helpers, none-algorithm defense, and token blacklisting support.
- **Sliding Window Rate Limiter**: Thread-safe in-memory sliding window rate limiter with a `@limiter.limit` decorator supporting custom rate-limiting keys.
- **Signup & Signin Managers**: High-level orchestration layers to coordinate validation, hashing, rate limiting, token generation, and re-hash detection during sign-up and sign-in.

---

## Installation

Install using `pip`:

```bash
pip install python-auth-toolkit
```

For development (including test runner and coverage dependencies):

```bash
pip install "python-auth-toolkit[dev]"
# Or with uv:
uv pip install -e ".[dev]"
```

---

## Quick Start

### 1. Signup & Signin Orchestration

```python
from python_auth_toolkit.signup import SignupManager
from python_auth_toolkit.signin import SigninManager
from python_auth_toolkit.jwt_handler import JWTHandler

# Initialize JWT Handler
jwt_handler = JWTHandler(secret_key="your-super-secret-key-change-me")

# 1. Sign up Flow
signup_mgr = SignupManager(jwt_handler=jwt_handler)
signup_result = signup_mgr.signup("user@example.com", "P@ssw0rd123!")

print(signup_result.email)  # Normalized email
print(signup_result.hashed_password)  # Hashed password (ready for DB)
print(signup_result.verification_token)  # JWT verification token

# Verify Email Verification Token
email = signup_mgr.verify_email_token(signup_result.verification_token)
print(email)  # user@example.com

# 2. Sign in Flow (with automatic Rate Limiting & Re-hash checking)
signin_mgr = SigninManager(jwt_handler=jwt_handler)

signin_result = signin_mgr.signin(
    rate_limit_key="login:user@example.com",
    password="P@ssw0rd123!",
    hashed_password=signup_result.hashed_password,
    payload={"sub": signup_result.email}
)

if signin_result.success:
    print(signin_result.access_token)
    print(signin_result.refresh_token)
    
    # If the default hash parameters were upgraded:
    if signin_result.needs_rehash:
        db.update_user_password(signup_result.email, signin_result.new_hash)
```

### 2. Email Validation & Normalization

```python
from python_auth_toolkit.email_validator import EmailValidator

# Reject disposable emails and add extra domains to blocklist
validator = EmailValidator(block_disposable=True, additional_blocked_domains={"temp-inbox.xyz"})

result = validator.validate_format("user@mailinator.com")
print(result.is_valid)  # False (mailinator.com is disposable)

normalized = validator.normalize("  User@Example.COM  ")
print(normalized)  # User@example.com
```

### 3. JWT Handler & Blacklist

```python
from python_auth_toolkit.jwt_handler import JWTHandler, InMemoryTokenBlacklist

blacklist = InMemoryTokenBlacklist()
handler = JWTHandler(secret_key="my-secret-key", blacklist=blacklist)

# Generate access and refresh tokens
payload = {"sub": "user_id_123"}
access_token = handler.generate_access_token(payload)

# Verify
decoded = handler.verify_token(access_token)
print(decoded["token_type"])  # "access"

# Revoke a token
blacklist.blacklist(decoded["jti"], expires_at=decoded["exp"])

# Subsequent verification fails: Raises InvalidTokenError
handler.verify_token(access_token)
```

### 4. Sliding Window Rate Limiting

```python
from python_auth_toolkit.rate_limiter import SlidingWindowRateLimiter
from python_auth_toolkit.exceptions import RateLimitExceededError

limiter = SlidingWindowRateLimiter()

# Use as a decorator: Limit function to 5 calls per 60 seconds
@limiter.limit(limit=5, window=60)
def login_attempt(username):
    print(f"Login attempt for {username}")

# Or check programmatically
allowed, info = limiter.check_and_record("ip:127.0.0.1", limit=10, window=60)
if not allowed:
    print(f"Too many requests. Retry after {info['reset_after']:.1f}s")
```

---

## Configuration Options

### `PasswordValidator` Parameters
- `min_length` (int, default: 8): Minimum length required.
- `max_length` (int, default: 128): Maximum length allowed.
- `required_uppercase` (bool, default: True): Require at least one uppercase letter.
- `required_lowercase` (bool, default: True): Require at least one lowercase letter.
- `required_digits` (bool, default: True): Require at least one digit.
- `required_special` (bool, default: True): Require at least one special character.
- `block_common_passwords` (bool, default: True): Reject passwords present in the common passwords list.

### `PasswordHasher` Parameters
- `algorithm` (str, default: `'bcrypt'`): Choose between `'bcrypt'` or `'argon2'`.
- `rounds` (int, default: 12): Cost factor rounds for Bcrypt.
- `time_cost` (int, default: 3): Time cost for Argon2.
- `memory_cost` (int, default: 65536): Memory cost in KiB for Argon2.
- `parallelism` (int, default: 4): Parallelism factor threads for Argon2.

### `JWTHandler` Parameters
- `secret_key` (str, default: `None`): Key used to sign HS256 tokens.
- `private_key` (str/bytes, default: `None`): RSA private key (PEM format) for signing RS256 tokens.
- `public_key` (str/bytes, default: `None`): RSA public key (PEM format) for verifying RS256 tokens.
- `default_algorithm` (str, default: `'HS256'`): Default JWT algorithm (`HS256` or `RS256`).
- `access_token_expiry` (int, default: 900): Access token lifetime in seconds (15 mins).
- `refresh_token_expiry` (int, default: 604800): Refresh token lifetime in seconds (7 days).
- `blacklist` (TokenBlacklist, default: `None`): A blacklist instance conforming to `TokenBlacklist` protocol.

---

## License

This project is licensed under the MIT License. See the `LICENSE` file for details.
