# Authentication and Role Management

This document describes the implemented OBEsoft account system, the Admin > Manager > Teacher permission model, local email testing, Google sign-in configuration, and the correct files to use when extending authentication.

## What is implemented

- One-time first-administrator setup
- Email and password sign-in
- Secure sign-out
- Public Teacher registration
- Email verification
- Resend-verification flow
- Forgot-password and reset-password flow
- Invalidation of old sessions after a password change
- Optional Google OpenID Connect sign-in
- Admin user, role, status, verification, and password management
- Teacher-to-course assignments
- Login and recovery rate limiting
- Audit logs for authentication and administration events
- CSRF checks on authenticated state-changing API calls
- Protection against disabling or demoting the final active administrator

Authentication is enabled by default. Set `OBESOFT_AUTH_ENABLED=false` only for intentional, local compatibility work.

## Role order and permissions

The operational order is:

```text
Admin > Manager > Teacher
```

| Capability                                    | Admin | Manager | Teacher |
| --------------------------------------------- | ----: | ------: | ------: |
| Manage users and roles                        |   Yes |      No |      No |
| Manage Teacher course assignments             |   Yes |     Yes |      No |
| Manage institution settings                   |   Yes |     Yes |      No |
| Create, update, duplicate, and delete courses |   Yes |     Yes |      No |
| View and update assigned courses              |   Yes |     Yes |     Yes |
| Download a database backup                    |   Yes |     Yes |      No |
| Restore a database backup                     |   Yes |      No |      No |

Public registration never accepts a requested role. Every public local or Google-created account receives only the Teacher role. An administrator must explicitly promote an account.

## Account flows

### First launch

If the database contains no users, the application shows the initial administrator form. This account is immediately verified and receives the Admin role. Google sign-in cannot create the first administrator.

### Local registration

1. Select **Register** on the sign-in screen.
2. Enter a display name, email address, and a password of at least 6 characters.
3. OBEsoft creates an inactive-for-login Teacher account and sends a verification link.
4. Open the link to verify the email address.
5. Sign in normally.

### Password recovery

1. Select **Forgot password?**.
2. Submit the account email address.
3. Open the one-time reset link.
4. Choose a password of at least 6 characters.

The response is intentionally the same whether or not an account exists. A successful password reset invalidates all previous sessions for that user.

### Administrator management

An administrator can open `/admin/`, or select **Manage users** from the signed-in account control. The page supports:

- Creating verified users
- Granting Admin, Manager, or Teacher roles
- Enabling and disabling accounts
- Marking an email verified or unverified
- Setting a replacement password
- Assigning and removing Teacher course access

The API refuses an update that would leave the system without an active administrator.

## Local email testing

The default development driver is:

```text
OBESOFT_MAIL_DRIVER=log
```

Verification and reset messages are appended to:

```text
storage/logs/mail.log
```

This path is outside `public/`, ignored by Git, and must not be served by the web server. Open the log locally and paste the generated link into the browser.

For a host with PHP mail delivery configured:

```text
OBESOFT_MAIL_DRIVER=mail
OBESOFT_MAIL_FROM_ADDRESS=no-reply@example.edu
OBESOFT_MAIL_FROM_NAME=OBEsoft
```

Test delivery on the actual host before production use. The application reports a server error if the configured mail driver cannot deliver the message.

## Google sign-in setup

1. Create an OAuth 2.0 Client ID of type **Web application** in Google Cloud Console.
2. Add the exact authorized redirect URI. For the bundled local server it is:

```text
http://127.0.0.1:8000/api/google-callback.php
```

3. Add these values to the private `.env` file in the project root:

```text
OBESOFT_APP_URL=http://127.0.0.1:8000
OBESOFT_GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
OBESOFT_GOOGLE_CLIENT_SECRET=your-client-secret
OBESOFT_GOOGLE_REDIRECT_URI=http://127.0.0.1:8000/api/google-callback.php
```

4. Restart the PHP application.

The `.env` file is loaded automatically, is ignored by Git, and is outside the public web root. Operating-system environment variables take precedence over values in this file.

The Google button is displayed only when both credentials are present. The server uses the authorization-code flow, validates state, issuer, audience, expiry, nonce, verified email, and an optional Google Workspace hosted domain. Existing accounts are linked by a Google-verified matching email. New Google accounts receive the Teacher role.

To restrict sign-in to one Google Workspace domain, add:

```text
OBESOFT_GOOGLE_HOSTED_DOMAIN=example.edu
```

Production deployments must use HTTPS and must register the production HTTPS callback URL in Google Cloud exactly.

## Main implementation files

| Responsibility                                    | File                                                              |
| ------------------------------------------------- | ----------------------------------------------------------------- |
| Sessions, login, permissions, CSRF, OAuth state   | `src/Auth/Auth.php`                                               |
| Registration, verification, and password recovery | `src/Services/AccountService.php`                                 |
| Google OpenID Connect flow                        | `src/Services/GoogleOAuthService.php`                             |
| Rate limiting                                     | `src/Services/AuthRateLimiter.php`                                |
| Verification and reset delivery                   | `src/Services/MailService.php`                                    |
| Admin user and assignment operations              | `src/Services/UserService.php`                                    |
| Local account API                                 | `public/api/auth.php`                                             |
| Google redirect and callback                      | `public/api/google-login.php`, `public/api/google-callback.php`   |
| Admin API                                         | `public/api/users.php`, `public/api/assignments.php`              |
| Sign-in and registration interface                | `public/assets/js/app.js`                                         |
| Admin page                                        | `public/admin/index.php`, `public/assets/js/pages/admin-users.js` |
| Account schema changes                            | `database/migrations/003_account_lifecycle.php`                   |

## Adding a future account feature

- Put browser markup under `public/` and page-specific JavaScript under `public/assets/js/pages/`.
- Put new public HTTP entrypoints under `public/api/`.
- Put business rules in `src/Services/`.
- Put shared session and permission behavior in `src/Auth/`.
- Add schema changes through a new numbered migration, starting with `004_...php`; never edit an applied migration.
- Add isolated HTTP and regression coverage under `tests/`.

Never place secrets, session files, mail logs, reset tokens, or the SQLite database under `public/`.
