# Authease

Authease is a lightweight, flexible authentication package for Django applications. It provides essential tools for handling user authentication, including JWT-based authentication, email verification via OTP, password reset, password change, and OAuth support — making it easy for developers to integrate into their Django projects without building an authentication system from scratch.

## Table of Contents
- [Features](#features)
- [Requirements](#requirements)
- [Installation](#installation)
- [Configuration](#configuration)
- [Usage](#usage)
  - [Example Setup](#example-setup)
- [API Endpoints](#api-endpoints)
- [Advanced Configuration](#advanced-configuration)
- [Documentation](#documentation)
- [Issues](#issues)
- [Contributing](#contributing)
- [License](#license)
- [Contact](#contact)

---

## Features

- **Password-Based Authentication**: Secure user registration, login, and password reset functionality.
- **Email Verification (OTP)**: Configurable one-time password verification with adjustable code length and expiry time.
- **Password Change**: Authenticated users can change their password securely.
- **Rate Limiting / Throttling**: Built-in throttle classes for login, password reset, and OTP verification to prevent abuse.
- **OAuth Integration**: Support for Google and GitHub OAuth for social login.
- **Template-Based Frontend**: Optional minimal Django template views (session-based auth) for register, login, email verification, password reset, and account settings — ready to use with one line in `urls.py`. Templates are intentionally bare-bones so you can wrap them in your own site layout.
- **Customizable Security**: Works with Django's authentication backend and supports JWT for session and token-based authentication.
- **Dynamic Password Generation**: Automatically generates secure passwords for social login users.
- **Extensible User Model**: Provides an abstract base user class (`AbstractAutheaseUser`) that you can extend with custom fields while keeping all authease functionality.
- **Easy Setup & Integration**: Minimal setup with high customizability to suit various Django project needs.

## Requirements

To use Authease, the following packages will be installed in your Django environment:

- Django >= 5.0.6
- djangorestframework >= 3.15.1
- djangorestframework-simplejwt >= 5.3.1
- google-api-python-client >= 2.136.0

Note: All necessary dependencies will be installed automatically if not already present.

## Installation

To install Authease, use the following command:

```bash
pip install authease
```

## Configuration
### 1. Add to Installed Apps

Add **Authease** to your `INSTALLED_APPS` list in your Django `settings.py` file:

```python
INSTALLED_APPS = [
    # Other Django apps
    'rest_framework',  # For Django REST Framework
    'rest_framework_simplejwt.token_blacklist',  # Required for logout/token blacklisting
    'authease.auth_core',
    'authease.oauth',
]
```
### 2. Update the `AUTH_USER_MODEL` Setting
Authease provides a custom user model that must be set in your Django project. If you don't need custom fields on the user model, simply point to Authease's built-in `User`:
```python
AUTH_USER_MODEL = 'auth_core.User'
```
This step is essential for Authease's authentication functionalities to work properly. Ensure this is configured before running migrations or creating any user-related data in the database.

#### Extending the User Model (Optional)
If you need to add custom fields to the user model, extend `AbstractAutheaseUser` in your own app instead of using the default `User`:

```python
# myapp/models.py
from authease.auth_core.models import AbstractAutheaseUser
from django.db import models

class CustomUser(AbstractAutheaseUser):
    phone_number = models.CharField(max_length=20, blank=True)
    bio = models.TextField(blank=True)

    class Meta:
        verbose_name = "User"
        verbose_name_plural = "Users"
```

Then update your settings to point to your custom model:
```python
AUTH_USER_MODEL = 'myapp.CustomUser'
```

Your custom model inherits all authease fields (`email`, `first_name`, `last_name`, `is_verified`, `auth_provider`, etc.) and functionality (`tokens()`, `get_full_name`, `UserManager`) automatically.

### 3. Configure Environment Variables
**Authease** requires several environment variables for configuration. Add the following to your `settings.py` or `.env` file:
```python
# Django Secret Key
SECRET_KEY = '<your_secret_key>'

# Email Settings
# EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'  # Test locally on console
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'  # For production

EMAIL_HOST = '<your_email_host>'
EMAIL_PORT = '<your_email_port>'
EMAIL_USE_TLS = True  # Or False depending on your email provider's requirements
EMAIL_HOST_USER = '<your_email_host_user>'
EMAIL_HOST_PASSWORD = '<your_email_host_password>'
DEFAULT_FROM_EMAIL = '<your_default_from_email>'

# For Google OAuth
GOOGLE_CLIENT_ID = '<your_google_client_id>'
GOOGLE_CLIENT_SECRET = '<your_google_client_secret>'

# For GitHub OAuth
GITHUB_CLIENT_ID = '<your_github_client_id>'
GITHUB_CLIENT_SECRET = '<your_github_client_secret>'
```
Replace the placeholder values with your actual credentials. Ensure these values are correctly set to allow account verification and OAuth functionalities.

### 4. Specify Password Reset Timeout
Add the following setting to your `settings.py` to specify the timeout duration for password reset links:
```python
PASSWORD_RESET_TIMEOUT = 1800  # Set timeout to 30 minutes (1800 seconds)
```

### 5. Site-specific Configurations
Configure the following settings in your `settings.py` file:
```python
SITE_NAME = "Your Site Name"
SITE_URL = "https://www.yoursite.com"
```
- `SITE_NAME`: The name of your site or application, used in email templates and other communications.
- `SITE_URL`: The base URL of your site (e.g., `https://www.example.com`), used to generate links in emails. Use `"#"` as a placeholder if you don't have a URL yet.

### 6. Authease Settings (Optional)
Configure optional Authease-specific settings in your `settings.py`:
```python
# OTP Configuration
AUTHEASE_OTP_LENGTH = 6          # Length of the OTP code (default: 6)
AUTHEASE_OTP_EXPIRY_MINUTES = 15 # OTP expiry time in minutes (default: 15)
OTP_RESEND_COOLDOWN = 60         # Cooldown in seconds between OTP resend requests (default: 60)
```

### 7. Throttle Configuration
Authease uses throttle classes to rate-limit sensitive endpoints. Add the following to your `REST_FRAMEWORK` settings:
```python
REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_RATES': {
        'login': '5/min',
        'password_reset': '3/min',
        'otp_verify': '5/min',
    }
}
```
These rates are customizable. The throttles are applied to:
- `login` — Login endpoint
- `password_reset` — Password reset request endpoint
- `otp_verify` — Email verification (OTP) endpoint

### 8. Migrate Database

Run the migrations to set up the necessary database tables for **Authease**:
```bash
python manage.py migrate
```

## Usage
#### Authease provides built-in views for user authentication, including:

- Registration
- Login
- Email Verification (OTP)
- Resend OTP
- Password Reset (request, confirm, set new password)
- Password Change (authenticated)
- Logout
- Token Refresh
- Google OAuth
- GitHub OAuth

### Example Setup:
### 1. Include the Auth Routes
Add the following URL patterns to your main `urls.py` to enable Authease's authentication routes in your project:
```python
from django.urls import path, include

urlpatterns = [
    # Other URL patterns for your project
    path('auth/', include('authease.auth_core.urls')),  # Authease authentication routes
    path('oauth/', include('authease.oauth.urls')),  # Authease OAuth routes
]
```

### Available Endpoints

When mounted at `auth/` and `oauth/`, the following endpoints are available:

**Auth Core:**
- `auth/register/`
- `auth/verify_email/`
- `auth/resend_otp/`
- `auth/login/`
- `auth/test_auth/`
- `auth/password_reset/`
- `auth/password_reset_confirm/<uidb64>/<token>/`
- `auth/set_new_password/`
- `auth/change_password/`
- `auth/logout/`
- `auth/token/refresh/`

**OAuth:**
- `oauth/google/`
- `oauth/github/`

### 2. Using Individual Views
If you want to set up specific routes individually, you can include each view as needed:
- **Register View Example**

  Use Authease's built-in `RegisterUserView` for user registration:
  ```python
  from authease.auth_core.views import RegisterUserView

  urlpatterns = [
      path('register/', RegisterUserView.as_view(), name='register'),
  ]
  ```


### 3. Template-Based Frontend (Optional)

If you're building a Django app with server-rendered templates (not a REST API), authease provides a set of minimal, ready-to-use views with session-based authentication. The included templates use Bootstrap 5 for basic form styling but are intentionally bare-bones — no navbar, no footer, no branding — so they work for any type of project (ecommerce, blog, SaaS, etc.). You simply override `authease/base.html` to wrap them in your own site layout.

Add one line to your `urls.py`:

```python
urlpatterns = [
    path('accounts/', include('authease.auth_core.frontend_urls')),
]
```

This gives you the following pages out of the box:

| URL | Name | Description |
|-----|------|-------------|
| `accounts/register/` | `authease-register` | Registration form |
| `accounts/verify-email/` | `authease-verify-email` | OTP verification with countdown timer |
| `accounts/resend-otp/` | `authease-resend-otp` | Resend OTP (with cooldown) |
| `accounts/login/` | `authease-login` | Login with session auth |
| `accounts/logout/` | `authease-logout` | Logout and redirect |
| `accounts/reset-password/` | `authease-password-reset` | Request password reset email |
| `accounts/reset-password-confirm/<uidb64>/<token>/` | `authease-password-reset-confirm` | Set new password from reset link |
| `accounts/settings/` | `authease-settings` | Account info, profile form, change password |
| `accounts/settings/profile/` | `authease-update-profile` | Update profile (POST) |
| `accounts/settings/password/` | `authease-change-password` | Change password (POST) |

The frontend views use Django's session-based authentication (`django.contrib.auth.login`/`logout`) instead of JWT tokens.

**Customizing templates:** All templates extend `authease/base.html`, which provides empty blocks for `{% block navbar %}`, `{% block footer %}`, and `{% block content %}`. To add your own site layout, create `templates/authease/base.html` in your project and define those blocks:

```html
<!-- your_project/templates/authease/base.html -->
{% extends "your_base.html" %}

{% block content %}
    {% if messages %}
    {% for message in messages %}
        <div class="alert alert-{{ message.tags }}">{{ message }}</div>
    {% endfor %}
    {% endif %}

    {% block content %}{% endblock %}
{% endblock %}
```

**Custom user model fields:** The settings page automatically detects extra fields on your custom user model (fields not in `AbstractAutheaseUser`) and renders form inputs for them — no configuration needed.

**Using alongside the API:** The frontend views share the same models and utilities as the API views. You can mount both in the same project (e.g. `auth/api/` for the REST API and `accounts/` for template views).

- #### OAuth Integration Example
  To enable Google and GitHub OAuth in your application, include their respective views:
  ```python
  from authease.oauth.views import GoogleSignInView, GithubSignInView

  urlpatterns = [
      path('auth/google/', GoogleSignInView.as_view(), name='google_auth'),
      path('auth/github/', GithubSignInView.as_view(), name='github_auth'),
  ]
  ```

## API Endpoints

| Method | Endpoint | Auth Required | Description |
|--------|----------|:---:|-------------|
| POST | `register/` | No | Register a new user |
| POST | `verify_email/` | No | Verify email with OTP code |
| POST | `resend_otp/` | No | Resend OTP verification code |
| POST | `login/` | No | Login and receive JWT tokens |
| GET | `test_auth/` | Yes | Test that authentication is working |
| POST | `password_reset/` | No | Request a password reset email |
| GET | `password_reset_confirm/<uidb64>/<token>/` | No | Confirm password reset token validity |
| PATCH | `set_new_password/` | No | Set a new password after reset |
| POST | `change_password/` | Yes | Change password (authenticated users) |
| POST | `logout/` | Yes | Logout and blacklist refresh token |
| POST | `token/refresh/` | No | Refresh JWT access token |
| POST | `google/` | No | Sign in with Google OAuth |
| POST | `github/` | No | Sign in with GitHub OAuth |

## Advanced Configuration
To enable JWT token-based authentication, configure djangorestframework-simplejwt in your `settings.py`:
```python
from datetime import timedelta

SIMPLE_JWT = {
    # Token Lifetimes
    "ACCESS_TOKEN_LIFETIME": timedelta(hours=12),   # Customize as per your use case
    "REFRESH_TOKEN_LIFETIME": timedelta(days=1),

    # Token Header Configuration
    "AUTH_HEADER_TYPES": ("Bearer",),               # Default is "Bearer"
    "AUTH_HEADER_NAME": "HTTP_AUTHORIZATION",       # Ensures proper header lookup

    # Rotation and Blacklisting
    "ROTATE_REFRESH_TOKENS": True,                  # Issue a new refresh token on each refresh
    "BLACKLIST_AFTER_ROTATION": True,               # Blacklist the old refresh token after rotation

    # Custom Claims and Validation
    "ALGORITHM": "HS256",                           # Ensure you're using a secure algorithm
    "SIGNING_KEY": SECRET_KEY,                      # Use Django's SECRET_KEY or a separate secure key
    "VERIFYING_KEY": None,                          # Public key for asymmetric algorithms like RS256
    "AUDIENCE": None,                               # Add audience claim if needed
    "ISSUER": None,                                 # Add issuer claim if needed

    # Sliding Tokens (Optional)
    "SLIDING_TOKEN_LIFETIME": timedelta(hours=12),  # For sliding sessions (if used), Customize as per your use case
    "SLIDING_TOKEN_REFRESH_LIFETIME": timedelta(days=1),

    # Miscellaneous
    "USER_ID_FIELD": "id",                          # Primary key field for user
    "USER_ID_CLAIM": "user_id",                     # Claim in the token for user ID
    "AUTH_TOKEN_CLASSES": ("rest_framework_simplejwt.tokens.AccessToken",),
    "TOKEN_TYPE_CLAIM": "token_type",               # Claim for identifying token type
    "JTI_CLAIM": "jti",                             # JWT ID claim for unique identification
}
```

## Documentation
https://pypi.org/project/authease/#description

## Issues
If you encounter any issues or bugs while using Authease, please check the following before reporting:

1. **Ensure Compatibility:** Verify that you are using compatible versions of Python and Django.
2. **Configuration Review:** Double-check that all necessary environment variables are set up correctly in your `settings.py` and `.env` file.
3. **Check Logs:** Review your server or Django logs for any specific error messages that may indicate missing configurations or dependencies.
4. **Documentation:** Refer to the documentation to ensure that all steps for installation and setup have been followed.

**Reporting Issues**

If the issue persists, please follow these steps to report it:

1. **Search Existing Issues:** First, check if someone has already reported the issue on the [GitHub Issues page](https://github.com/Oluwatemmy/authease/issues).
2. **Open a New Issue:** If no existing issue matches yours, create a new issue providing as much detail as possible. Include:
- A clear title and description.
- Steps to reproduce the issue.
- Expected and actual behavior.
- Any relevant logs or error messages.
3. **Environment Details:** Include your environment details such as OS, Python version, Django version, and any other relevant setup information.

## Contributing
We welcome contributions to Authease! Please fork the repository, create a new branch, and submit a pull request. Be sure to review the contribution guidelines before submitting.

## License
Authease is licensed under the MIT License. See [LICENSE](https://github.com/Oluwatemmy/authease/blob/main/LICENSE) for more information.

## Contact
For questions or feedback, please contact the package author, **Oluwaseyi Ajayi**, at [oluwaseyitemitope456@gmail.com](oluwaseyitemitope456@gmail.com).