# pargo-auth

Shared authentication middleware for PARGO backend services. Verifies Supabase JWTs and provides FastAPI dependencies.

## Installation

```bash
pip install pargo-auth
```

## Quick Start

```python
from fastapi import FastAPI, Depends
from pargo_auth import get_current_user, AuthenticatedUser

app = FastAPI()

@app.get("/me")
async def get_me(user: AuthenticatedUser = Depends(get_current_user)):
    return {
        "id": user.sub,
        "email": user.email,
    }
```

## Configuration

Set these environment variables:

```bash
SUPABASE_URL=https://your-project.supabase.co
ENV=local  # Skip auth verification in local dev
```

## Usage Patterns

### Basic: Protect individual endpoints

```python
from pargo_auth import get_current_user, AuthenticatedUser

@app.get("/protected")
async def protected(user: AuthenticatedUser = Depends(get_current_user)):
    return {"user_id": user.sub}
```

### Protect entire router

```python
from fastapi import APIRouter, Depends
from pargo_auth import require_auth

router = APIRouter(dependencies=[require_auth()])

@router.get("/data")
async def get_data():  # Auth already required by router
    return {"data": "secret"}
```

### Optional auth (different behavior for logged-in vs anonymous)

```python
from pargo_auth import SupabaseAuth, AuthenticatedUser

auth = SupabaseAuth()

@app.get("/content")
async def get_content(user: AuthenticatedUser | None = Depends(auth.get_user_optional)):
    if user:
        return {"content": "personalized", "user": user.sub}
    return {"content": "generic"}
```

### Custom instance (non-default config)

```python
from pargo_auth import SupabaseAuth

auth = SupabaseAuth(
    supabase_url="https://custom.supabase.co",
    skip_verification_in_dev=False,  # Always verify, even locally
)

@app.get("/strict")
async def strict_endpoint(user = Depends(auth.get_user)):
    return {"user": user.sub}
```

## AuthenticatedUser

The `AuthenticatedUser` object contains:

| Field | Type | Description |
|-------|------|-------------|
| `sub` | `str` | Supabase user ID (stable, use as canonical identity) |
| `email` | `str \| None` | User's email (if available) |
| `email_verified` | `bool` | Whether email is verified |
| `raw_claims` | `dict \| None` | Full JWT payload for custom claims |

## Legacy Support

For backwards compatibility, the middleware also checks for `x-user-id` header if no Bearer token is present. This allows gradual migration from the old auth system.

## Development

```bash
# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest
```

## License

MIT
