# Role-Based Access Control (RBAC) Implementation

## Overview

Role-based access control has been added to your Flask application with minimal changes to existing code.

## How It Works

### 1. **Email-Based Role Assignment**

When a user logs in via Google OAuth, their role is automatically assigned based on their email address:

```python
# In CONFIGURATION section:
ADMIN_EMAILS = {
    "de.globalerc@gmail.com",
    "op.globalerc@gmail.com", 
    "df.globalerc@gmail.com",
}

COMMERCIAL_EMAILS = {
    "joseamor.globalerc@gmail.com",
    "helderoliveira.globalerc@gmail.com",
}
```

**Roles assigned:**
- **admin** → Email in `ADMIN_EMAILS`
- **commercial** → Email in `COMMERCIAL_EMAILS`
- **client** → All other emails

### 2. **Role Storage**

The user's role is stored in **three places**:

1. **User Object**: `current_user.role` (in memory, available in templates and routes)
2. **Session**: `session['user_role']` (server-side session storage)
3. **Database** (optional): Can be extended to persist roles in a database

## Usage Examples

### Example 1: Protect a Route (Admin Only)

```python
@app.route('/admin/settings')
@role_required('admin')
def admin_settings():
    return "Admin settings page"
```

### Example 2: Multiple Roles Allowed

```python
@app.route('/reports')
@role_required('admin', 'commercial')
def reports():
    return "Reports for admin and commercial users"
```

### Example 3: Access Control in Templates

```html
<!-- Show admin panel only for admins -->
{% if current_user.role == 'admin' %}
    <a href="/admin">Admin Panel</a>
{% endif %}

<!-- Show commercial dashboard for commercial users -->
{% if current_user.role == 'commercial' %}
    <a href="/my-sales">My Sales</a>
{% endif %}
```

### Example 4: Check Role in Python

```python
from flask import current_user

@app.route('/dashboard')
@login_required
def dashboard():
    if current_user.role == 'admin':
        # Show admin view
        return render_template('admin_dashboard.html')
    elif current_user.role == 'commercial':
        # Show commercial view
        return render_template('commercial_dashboard.html')
    else:
        # Show client view
        return render_template('client_dashboard.html')
```

### Example 5: Log User Role

```python
@app.route('/some-route')
@login_required
def some_route():
    print(f"User: {current_user.email}, Role: {current_user.role}")
    # ... rest of code
```

## What Changed (Minimal Impact)

### 1. Configuration (Lines 36-60+)
- Added `ADMIN_EMAILS` set
- Added `COMMERCIAL_EMAILS` set
- Kept `USERS_ROLES` dict for backward compatibility

### 2. User Model (Line ~182)
- Updated `User.__init__()` to accept `email` and `role` parameters
- Changed from auto-loading role to accepting it as parameter

### 3. New Decorator (Lines ~189-222)
- Created `@role_required(*allowed_roles)` decorator
- Checks authentication and role before allowing access
- Returns 403 Forbidden if access denied

### 4. OAuth Callback (Lines ~1015-1065)
- Added role assignment: `user_role = get_user_role(user_email)`
- Store role in session: `session['user_role'] = user_role`
- Pass role to User object: `User(user_id, email=user_email, role=user_role)`
- Added logging of assigned role

### 5. Helper Function (Lines ~145-155)
- Updated `get_user_role()` function
- Now uses email lists instead of USERS_ROLES dict
- Returns clear role names: 'admin', 'commercial', 'client'

## Adding New Admin/Commercial Users

To add a new user to a role:

1. **For Admin Role**: Add email to `ADMIN_EMAILS` set
```python
ADMIN_EMAILS = {
    "de.globalerc@gmail.com",
    "op.globalerc@gmail.com",
    "df.globalerc@gmail.com",
    "newadmin@globalerc.gmail.com",  # ← Add here
}
```

2. **For Commercial Role**: Add email to `COMMERCIAL_EMAILS` set
```python
COMMERCIAL_EMAILS = {
    "joseamor.globalerc@gmail.com",
    "helderoliveira.globalerc@gmail.com",
    "newcommercial@globalerc.gmail.com",  # ← Add here
}
```

3. **Restart the Flask app** for changes to take effect

## Existing Routes - No Changes Required

All existing routes continue to work as before. The RBAC system is **opt-in**:

- Routes **without** `@role_required()` → Still require login only
- Routes **with** `@role_required()` → Check role before allowing

## Next Steps

To enforce RBAC on existing routes, simply add the decorator:

```python
# Before (requires login only):
@app.route('/performance')
@login_required
def performance():
    ...

# After (requires login + admin role):
@app.route('/performance')
@login_required
@role_required('admin')
def performance():
    ...
```

## Testing

### Test as Admin User
- Login as: `de.globalerc@gmail.com`
- Should have `current_user.role = 'admin'`
- Should pass `@role_required('admin')` checks

### Test as Commercial User
- Login as: `joseamor.globalerc@gmail.com`
- Should have `current_user.role = 'commercial'`
- Should pass `@role_required('commercial')` checks
- Should fail `@role_required('admin')` checks

### Test as Client User
- Login as: `any-other-email@email.com`
- Should have `current_user.role = 'client'`
- Should pass `@role_required('client')` checks
- Should fail `@role_required('admin')` or `@role_required('commercial')` checks
