Metadata-Version: 2.4
Name: scg-auth
Version: 1.0.0
Summary: A lightweight, zero-dependency OAuth 2.0 client library — Authorization Code, Client Credentials, Implicit, and Device Code flows with PKCE and CSRF protection
Home-page: https://github.com/analyticswithharry/scg-auth
Author: Analytics With Harry - Squid Consultancy Group Limited
Author-email: hemantthapa1998@gmail.com
Project-URL: Bug Reports, https://github.com/analyticswithharry/scg-auth/issues
Project-URL: Source, https://github.com/analyticswithharry/scg-auth
Project-URL: Documentation, https://github.com/analyticswithharry/scg-auth#readme
Project-URL: Homepage, https://github.com/analyticswithharry/scg-auth
Keywords: oauth,oauth2,authentication,auth,pkce,authorization-code,client-credentials,device-code,security,scg,token,csrf
Classifier: Development Status :: 5 - Production/Stable
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.7
Classifier: Programming Language :: Python :: 3.8
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 :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Security :: Cryptography
Classifier: Topic :: System :: Systems Administration :: Authentication/Directory
Requires-Python: >=3.7
Description-Content-Type: text/markdown
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: keywords
Dynamic: project-url
Dynamic: requires-python
Dynamic: summary

# scg-auth (Python)

A lightweight, **zero-dependency** OAuth 2.0 client library for Python.

Supports all major OAuth 2.0 flows with built-in PKCE and CSRF protection.
Uses the Python standard library only — no `requests`, no third-party packages.

## Features

- **Authorization Code Flow** — with PKCE (S256) support
- **Client Credentials Flow** — machine-to-machine / service accounts
- **Refresh Token** — seamless token renewal
- **Device Code Flow** — CLI tools, smart TVs, IoT devices
- **Implicit Flow** — parse-only (deprecated in OAuth 2.1)
- **State / CSRF protection** — automatic state generation and validation
- **Token management** — in-memory storage with expiry checking
- **Zero dependencies** — standard library only (`urllib`, `hashlib`, `secrets`, etc.)

## Installation

```bash
pip install scg-auth
```

## Quick Start

### Authorization Code Flow (with PKCE)

```python
from scg_auth import SCGAuth

client = SCGAuth(
    client_id="your-client-id",
    client_secret="your-client-secret",
    authorization_url="https://provider.example.com/oauth/authorize",
    token_url="https://provider.example.com/oauth/token",
    redirect_uri="https://yourapp.com/callback",
    scopes=["openid", "profile", "email"],
)

# 1. Generate the authorization URL
result = client.generate_auth_url(pkce=True)
# Redirect user to result["url"], store result["state"] and result["code_verifier"]

# 2. Handle the callback
tokens = client.exchange_code(
    code,
    state=returned_state,      # validates CSRF automatically
    code_verifier=code_verifier,
)
print(tokens["access_token"])

# 3. Refresh when near expiry
if client.is_token_expired(buffer_seconds=120):
    tokens = client.refresh_token(tokens["refresh_token"])
```

### Client Credentials Flow

```python
tokens = client.client_credentials()
print(tokens["access_token"])
```

### Device Code Flow

```python
device_auth = client.device_code()
print(f"Visit {device_auth['verification_uri']} and enter: {device_auth['user_code']}")

tokens = client.poll_device_token(device_auth)
print(tokens["access_token"])
```

## API

### `SCGAuth(client_id, authorization_url, token_url, ...)`

| Parameter                  | Type      | Required | Description                                       |
| -------------------------- | --------- | -------- | ------------------------------------------------- |
| `client_id`                | str       | ✓        | OAuth client ID                                   |
| `authorization_url`        | str       | ✓        | Provider authorization endpoint                   |
| `token_url`                | str       | ✓        | Provider token endpoint                           |
| `client_secret`            | str       |          | Client secret (required for confidential clients) |
| `redirect_uri`             | str       |          | Redirect URI                                      |
| `scopes`                   | list[str] |          | Default scopes                                    |
| `device_authorization_url` | str       |          | Device authorization endpoint                     |

### Methods

| Method                                                     | Description                          |
| ---------------------------------------------------------- | ------------------------------------ |
| `generate_auth_url(pkce, state, scopes, response_type)`    | Build auth URL + register CSRF state |
| `validate_state(state)`                                    | Validate CSRF state from callback    |
| `exchange_code(code, state, code_verifier)`                | Exchange code for tokens             |
| `client_credentials(scopes)`                               | Client Credentials flow              |
| `refresh_token(refresh_token)`                             | Refresh an access token              |
| `device_code(scopes)`                                      | Initiate Device Code flow            |
| `poll_device_token(response, timeout, interval)`           | Poll until user authorizes           |
| `generate_implicit_url(state, scopes)`                     | Build Implicit flow auth URL         |
| `parse_implicit_response(url_or_fragment, validate_state)` | Parse Implicit flow response         |
| `get_stored_tokens()`                                      | Get cached tokens                    |
| `is_token_expired(buffer_seconds)`                         | Check token expiry                   |
| `clear_tokens()`                                           | Clear cached tokens                  |

## Running Tests

```bash
cd python
python -m pytest test_scg_auth.py -v
# or
python test_scg_auth.py
```

## License

MIT — [Analytics With Harry](https://github.com/analyticswithharry) / Squid Consultancy Group Limited
