Metadata-Version: 2.4
Name: nbsplogin
Version: 1.3.0
Summary: A Flask extension for SSO/Auth functionality
Author-email: TVLuke <tvluke@chaotikum.org>
Project-URL: Homepage, https://git.chaotikum.org/tvluke/nbsplogin
Project-URL: Bug Tracker, https://git.chaotikum.org/tvluke/nbsplogin/issues
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Framework :: Flask
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: flask>=2.0.0
Requires-Dist: blinker>=1.5
Requires-Dist: authlib>=1.0.0
Requires-Dist: requests>=2.25.0

# nbsplogin

A Flask extension for standardized SSO/Auth functionality that provides a reusable implementation of OAuth login flows.

## Features

- Provides a Flask Blueprint with ready-to-use login routes
- Uses Blinker signals to notify your app when users log in or out
- Includes customizable templates and styles
- Handles OAuth for Chaotikum Account (and potentially other providers)
- Emits sanitized user objects via signals

## Installation

Add the following line to your requirements.txt file:

```
git+https://git.chaotikum.org/tvluke/nbsplogin.git
```

Or install directly with pip:

```bash
pip install git+https://git.chaotikum.org/tvluke/nbsplogin.git
```

## Quick Start

```python
from flask import Flask, session
from nbsplogin import NBSPLogin, user_logged_in

app = Flask(__name__)
app.secret_key = "your-secret-key"

# Configure OAuth providers
app.config["NBSPLOGIN_PROVIDERS"] = {
    "chaotikum": {
        "client_id": "your-client-id",
        "client_secret": "your-client-secret",
        "access_token_url": "https://auth.chaotikum.org/token",
        "authorize_url": "https://auth.chaotikum.org/authorize",
        "api_base_url": "https://auth.chaotikum.org/",
        "server_metadata_url": "https://auth.chaotikum.org/.well-known/openid-configuration",
        "client_kwargs": {
            "scope": "openid email profile",
            "prompt": "select_account"
        },
        "text": "Login with Chaotikum",
        "fa": "fas fa-sign-in-alt",  # Optional Font Awesome icon class
        "use_pkce": False  # Optional: Enable PKCE (default: False for backward compatibility)
    }
}

# Initialize the extension
login = NBSPLogin(app)

# Connect to the login signal
@user_logged_in.connect
def handle_user_login(sender, user, **extra):
    session["user_id"] = user["id"]
    # Store user in your database if needed

# Run the app
if __name__ == "__main__":
    app.run(debug=True)
```

## Configuration

### Required Configuration

- `NBSPLOGIN_PROVIDERS`: Dictionary of OAuth providers with their configurations

### Optional Configuration

- `NBSPLOGIN_POST_LOGIN_URL`: URL to redirect to after successful login (default: '/')
- `NBSPLOGIN_POST_LOGOUT_URL`: URL to redirect to after logout (default: '/')

### Provider Configuration Options

Each provider in `NBSPLOGIN_PROVIDERS` supports the following options:

**Required:**
- `client_id`: OAuth client ID
- `client_secret`: OAuth client secret
- `server_metadata_url`: OIDC discovery endpoint URL

**Optional:**
- `access_token_url`: Token endpoint URL (auto-discovered if not provided)
- `authorize_url`: Authorization endpoint URL (auto-discovered if not provided)
- `api_base_url`: Base URL for API calls
- `userinfo_endpoint`: Userinfo endpoint URL (auto-discovered if not provided)
- `client_kwargs`: Additional OAuth parameters (e.g., scope, prompt)
- `text`: Button text for login page (default: "Login with {Provider}")
- `fa`: Font Awesome icon class for button (default: "fas fa-sign-in-alt")
- `use_pkce`: Enable PKCE (Proof Key for Code Exchange) for enhanced security (default: `False` for backward compatibility)

**PKCE (Proof Key for Code Exchange):**

PKCE is a security extension for OAuth 2.0 that prevents authorization code interception attacks. Enable it if your OAuth provider requires or recommends it:

```python
"chaotikum": {
    # ... other config ...
    "use_pkce": True  # Enable PKCE
}
```

### Configuration Methods

#### 1. Direct Configuration in Code

```python
app.config["NBSPLOGIN_PROVIDERS"] = {
    "chaotikum": {
        "client_id": "your-client-id",
        "client_secret": "your-client-secret",
        # other settings...
    }
}
```

#### 2. Using Environment Variables (Recommended)

```python
import os

app.config["NBSPLOGIN_PROVIDERS"] = {
    "chaotikum": {
        "client_id": os.environ.get("CHAOTIKUM_CLIENT_ID"),
        "client_secret": os.environ.get("CHAOTIKUM_CLIENT_SECRET"),
        "access_token_url": "https://auth.chaotikum.org/token",
        "authorize_url": "https://auth.chaotikum.org/authorize",
        "api_base_url": "https://auth.chaotikum.org/",
        "server_metadata_url": "https://auth.chaotikum.org/.well-known/openid-configuration",
        "client_kwargs": {
            "scope": "openid email profile",
            "prompt": "select_account"
        },
        "text": "Login with Chaotikum",
        "fa": "fas fa-sign-in-alt",
        "use_pkce": False  # Optional: Enable PKCE if required
    }
}
```

#### 3. Using a Configuration File

Create a `config.py` file:

```python
# config.py
import os

NBSPLOGIN_PROVIDERS = {
    "chaotikum": {
        "client_id": os.environ.get("CHAOTIKUM_CLIENT_ID"),
        "client_secret": os.environ.get("CHAOTIKUM_CLIENT_SECRET"),
        "access_token_url": "https://auth.chaotikum.org/token",
        "authorize_url": "https://auth.chaotikum.org/authorize",
        "api_base_url": "https://auth.chaotikum.org/",
        "server_metadata_url": "https://auth.chaotikum.org/.well-known/openid-configuration",
        "client_kwargs": {
            "scope": "openid email profile",
            "prompt": "select_account"
        },
        "text": "Login with Chaotikum",
        "fa": "fas fa-sign-in-alt",
        "use_pkce": False  # Optional: Enable PKCE if required
    }
}
NBSPLOGIN_POST_LOGIN_URL = "/dashboard"
NBSPLOGIN_POST_LOGOUT_URL = "/"
```

Then in your app:

```python
app.config.from_pyfile('config.py')
```

#### 4. Using .env File with python-dotenv

Create a `.env` file (add to .gitignore):

```
CHAOTIKUM_CLIENT_ID=your-client-id
CHAOTIKUM_CLIENT_SECRET=your-client-secret
NBSPLOGIN_POST_LOGIN_URL=/dashboard
```

Then in your app:

```python
from dotenv import load_dotenv
import os

load_dotenv()  # load environment variables from .env

# Configure app as in method 2 above
```

## Routes

The extension provides the following routes:

- `/login/`: Login page with provider buttons
- `/login/auth/<provider>`: Initiates OAuth flow for the specified provider
- `/login/callback/<provider>`: Handles OAuth callback
- `/login/logout`: Logs out the current user

## Signals

### user_logged_in

Emitted when a user successfully logs in. Provides a sanitized user object:

```python
@user_logged_in.connect
def handle_user_login(sender, user, **extra):
    """
    user = {
        'id': 'provider_userid',
        'name': 'User Name',
        'email': 'user@example.com',
        'provider': 'provider_name',
        'groups': ['group1', 'group2']
    }
    """
    # Store user in session or database
    session["user_id"] = user["id"]
```

Groups are only avaliable for chaotikum.

### user_logged_out

Emitted when a user logs out:

```python
@user_logged_out.connect
def handle_user_logout(sender, user, **extra):
    # Clear user data
    session.clear()
```

## Customizing Templates

You can override the default templates by creating your own in your app's templates directory:

- `templates/nbsplogin/login.html`: Login page
- `templates/nbsplogin/error.html`: Error page
- `templates/nbsplogin/base.html`: Base template

## Accessing Tokens

Raw tokens are available in `flask.g.sso_tokens` during the request:

```python
from flask import g

@app.route('/protected')
def protected():
    # Access tokens if needed (only available during the callback request)
    tokens = getattr(g, 'sso_tokens', None)
    # ...
```

## Development

```bash
# Clone the repository
git clone https://git.chaotikum.org/tvluke/nbsplogin.git
cd nbsplogin

# Install in development mode
pip install -e .
```

## License

MIT
