# Irene Auth - Production-Grade Authentication Library

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Python](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
[![Rust](https://img.shields.io/badge/rust-1.70+-orange.svg)](https://www.rust-lang.org/)

**Irene Auth** is a production-grade authentication library combining **Rust-powered cryptography** with **Python workflows** for FastAPI applications.

## 🎯 All 8 Core Features Implemented

| # | Feature | Status | Description |
|---|---------|--------|-------------|
| 1 | **User Model** | ✅ | SQLAlchemy models with relationships |
| 2 | **Password Hashing** | ✅ | Argon2id (Rust, memory-hard, GPU-resistant) |
| 3 | **Signup + Login** | ✅ | Complete authentication flows |
| 4 | **JWT Access Tokens** | ✅ | HS256 + RS256 support (Rust) |
| 5 | **Refresh Tokens** | ✅ | Storage, validation, revocation |
| 6 | **RBAC** | ✅ | Role-based access control |
| 7 | **Password Reset** | ✅ | Secure token-based reset flow |
| 8 | **Email Verification** | ✅ | Token-based email verification |

## 🏗️ Architecture

```
┌─────────────────────────────────────┐
│     FastAPI Application (Your Code) │
└─────────────────────────────────────┘
                  │
                  ▼
┌─────────────────────────────────────┐
│   Python Auth Library (irene_auth)  │
│   • Models, workflows, RBAC         │
└─────────────────────────────────────┘
                  │
                  ▼
┌─────────────────────────────────────┐
│   Rust Crypto Module (Secure)      │
│   • Argon2id, JWT, tokens           │
└─────────────────────────────────────┘
```

**Rust handles ALL cryptography**:
- ✅ Argon2id password hashing
- ✅ CSPRNG token generation  
- ✅ SHA-256 token hashing
- ✅ Constant-time comparisons
- ✅ JWT encoding/decoding

**Python handles workflows**:
- ✅ Database operations
- ✅ Business logic
- ✅ FastAPI integration
- ✅ Email sending

## 🚀 Quick Start

### Installation

```bash
pip install irene-auth
```

### Basic Usage

```python
from fastapi import FastAPI, Depends
from irene_auth import AuthManager, AuthConfig, User

app = FastAPI()

# Configure authentication
config = AuthConfig(
    database_url="sqlite:///./auth.db",
    secret_key="your-secret-key-min-32-characters-long"
)
auth = AuthManager(config)

# Signup endpoint
@app.post("/signup")
async def signup(email: str, password: str):
    user, verification_token = auth.signup(email, password)
    # TODO: Send verification email with token
    return {"message": "Check your email for verification"}

# Login endpoint
@app.post("/login")
async def login(email: str, password: str):
    tokens = auth.login(email, password)
    return tokens  # {access_token, refresh_token, token_type}

# Protected endpoint (requires authentication)
@app.get("/profile")
async def get_profile(user: User = Depends(auth.get_current_user)):
    return {
        "email": user.email,
        "is_verified": user.is_verified,
        "roles": [role.name for role in user.roles]
    }

# Admin-only endpoint (requires role)
@app.get("/admin")
async def admin_panel(user: User = Depends(auth.require_role("admin"))):
    return {"message": "Welcome, admin!"}
```

## 📚 Complete Example

See [examples/fastapi_app.py](examples/fastapi_app.py) for a complete working example with all 8 features.

## 🔐 Security Features

### Password Security (Feature 2)
- **Argon2id hashing** (memory-hard, 64 MiB, 3 iterations)
- GPU/ASIC resistant
- Automatic salt generation

### JWT Tokens (Feature 4)
- **HS256** (HMAC-SHA256) symmetric signing
- **RS256** (RSA-SHA256) asymmetric signing  
- Automatic expiration validation
- Custom claims support

### Token Security (Features 5, 7, 8)
- **CSPRNG** token generation (OS-provided)
- **SHA-256** hashing for database storage
- **Constant-time** comparison (prevents timing attacks)
- Time-limited tokens with expiration

### Database Security
- **Never stores** plaintext passwords
- **Never stores** plaintext tokens
- **Constant-time** token verification
- SQL injection protection (SQLAlchemy ORM)

## 🎯 Feature Details

### 1. User Model

```python
from irene_auth.models import User, Role, Base

# SQLAlchemy models with relationships
user = User(email="user@example.com", password_hash="...")
user.roles  # List of roles
user.refresh_tokens  # List of active tokens
```

### 2 & 3. Password Hashing + Signup/Login

```python
# Signup (Feature 3)
user, token = auth.signup("user@example.com", "SecurePass123!")

# Login (Feature 3)
tokens = auth.login("user@example.com", "SecurePass123!")
# Returns: {access_token, refresh_token, token_type}
```

### 4. JWT Access Tokens

```python
# Automatic with login, or manual:
access_token = auth.jwt_manager.create_access_token(user)

# Verify and decode
claims = auth.jwt_manager.decode_access_token(access_token)
```

### 5. Refresh Tokens

```python
# Create refresh token
refresh_token = auth.refresh_manager.create_refresh_token(user, db)

# Use to get new access token
new_access_token = auth.refresh_access_token(refresh_token, db)

# Revoke token
auth.refresh_manager.revoke_token(refresh_token, db)
```

### 6. Role-Based Access Control

```python
# Create roles
auth.rbac_manager.create_role("admin", "Administrator", db)
auth.rbac_manager.create_role("moderator", "Moderator", db)

# Assign to user
auth.rbac_manager.assign_role(user, "admin", db)

# Check permissions
if user.has_role("admin"):
    print("User is admin")

# Protect endpoints
@app.get("/admin")
async def admin_only(user: User = Depends(auth.require_role("admin"))):
    return {"message": "Admin access"}

@app.get("/moderate")
async def moderate(user: User = Depends(auth.require_any_role(["admin", "moderator"]))):
    return {"message": "Can moderate"}
```

### 7. Password Reset

```python
# User requests reset
token = auth.reset_manager.request_password_reset("user@example.com", db)
# TODO: Send email with token

# User submits new password with token
success = auth.reset_manager.reset_password(token, "NewPassword123!", db)
```

### 8. Email Verification

```python
# On signup, token is generated
user, verification_token = auth.signup("user@example.com", "pass")
# TODO: Send verification email

# User clicks link with token
success = auth.verification_manager.verify_email(verification_token, db)

# Resend verification
new_token = auth.verification_manager.resend_verification("user@example.com", db)
```

## ⚙️ Configuration

```python
from irene_auth import AuthConfig

config = AuthConfig(
    database_url="postgresql://user:pass@localhost/db",
    secret_key="your-secret-key-at-least-32-characters",
    algorithm="HS256",  # or "RS256"
    access_token_expire_minutes=15,
    refresh_token_expire_days=30,
    verification_token_expire_hours=24,
    reset_token_expire_hours=1,
    # For RS256:
    private_key_path="/path/to/private.pem",
    public_key_path="/path/to/public.pem"
)
```

## 🔒 Security Best Practices

### DO ✅

- **Use strong secret keys** (32+ characters, random)
- **Use HTTPS** in production
- **Validate email addresses** before signup
- **Send verification emails** to confirm ownership
- **Implement rate limiting** on auth endpoints
- **Log authentication events** for auditing
- **Rotate refresh tokens** on use (optional)
- **Revoke tokens** on logout
- **Use short-lived access tokens** (15-30 minutes)
- **Store refresh tokens securely** on client

### DON'T ❌

- **DON'T** store passwords in plaintext
- **DON'T** store tokens in plaintext (database)
- **DON'T** send tokens in URLs (use headers/body)
- **DON'T** ignore verification (email enumeration risk)
- **DON'T** use weak secret keys
- **DON'T** skip HTTPS in production
- **DON'T** expose detailed error messages
- **DON'T** allow unlimited login attempts

## 📖 API Reference

### Core Functions (from Rust)

```python
import irene_auth

# Password operations
hash = irene_auth.hash_password("password")
is_valid = irene_auth.verify_password("password", hash)

# Token operations
token = irene_auth.generate_token(32)
token_hash = irene_auth.hash_token(token)
is_valid = irene_auth.verify_token_hash(token, token_hash)

# JWT operations
jwt = irene_auth.jwt_encode({"sub": "123"}, b"secret", 3600, "HS256")
claims = irene_auth.jwt_decode(jwt, b"secret", ["HS256"])
```

### Python Classes

- **AuthManager**: Main authentication coordinator
- **JWTManager**: JWT token creation/validation
- **RefreshTokenManager**: Refresh token lifecycle
- **PasswordResetManager**: Password reset flow
- **EmailVerificationManager**: Email verification flow
- **RBACManager**: Role and permission management

## 🧪 Testing

```bash
# Install dev dependencies
pip install irene-auth[dev]

# Run tests
pytest

# Run with coverage
pytest --cov=irene_auth
```

## 🚢 Publishing to PyPI

```bash
# Build wheel
maturin build --release

# Publish
maturin publish
```

## 📝 License

MIT License - see [LICENSE](LICENSE) file

## 🙏 Acknowledgments

Built with:
- [Rust](https://www.rust-lang.org/) - Systems programming language
- [PyO3](https://pyo3.rs/) - Rust-Python bindings
- [FastAPI](https://fastapi.tiangolo.com/) - Modern Python web framework
- [SQLAlchemy](https://www.sqlalchemy.org/) - Python SQL toolkit
- [Argon2](https://github.com/P-H-C/phc-winner-argon2) - Password hashing
- [jsonwebtoken](https://github.com/Keats/jsonwebtoken) - JWT implementation

## 🤝 Contributing

Contributions welcome! Please:
1. Fork the repository
2. Create a feature branch
3. Add tests
4. Submit a pull request

**Security issues**: Report privately to security@example.com

## 📧 Support

- **Documentation**: See this README and [examples/](examples/)
- **Issues**: GitHub Issues
- **Discussions**: GitHub Discussions

---

**Production-ready authentication for FastAPI** | **Rust-powered security** | **All 8 core features** 🚀
