Fixed middleware authentication issues
This commit is contained in:
@@ -193,17 +193,121 @@ async def customer_orders(
|
||||
|
||||
### require_role()
|
||||
|
||||
Custom role enforcement for specific roles.
|
||||
Custom role enforcement for specific roles. This method returns a decorator factory that creates role-checking decorators for any role name.
|
||||
|
||||
**Usage**:
|
||||
**Method Signature**:
|
||||
```python
|
||||
@app.get("/custom-endpoint")
|
||||
@auth_manager.require_role("custom_role")
|
||||
async def custom_endpoint(current_user: User):
|
||||
return {"message": "Custom role access"}
|
||||
def require_role(self, required_role: str) -> Callable
|
||||
```
|
||||
|
||||
**Returns**: Decorator function that validates role
|
||||
**Parameters**:
|
||||
- `required_role` (str): The exact role name required (e.g., "admin", "vendor", "custom_role")
|
||||
|
||||
**Returns**: A decorator function that:
|
||||
1. Accepts a function as input
|
||||
2. Returns a wrapper that validates the current user's role
|
||||
3. Raises `HTTPException(403)` if the role doesn't match
|
||||
|
||||
**Usage Example**:
|
||||
```python
|
||||
from fastapi import Depends, APIRouter
|
||||
from middleware.auth import auth_manager
|
||||
from models.database.user import User
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@router.get("/moderator-only")
|
||||
@auth_manager.require_role("moderator")
|
||||
async def moderator_endpoint(current_user: User):
|
||||
"""Only users with role='moderator' can access this."""
|
||||
return {"message": "Moderator access granted"}
|
||||
|
||||
# Can also be used with custom roles
|
||||
@router.get("/special-access")
|
||||
@auth_manager.require_role("special_user")
|
||||
async def special_endpoint(current_user: User):
|
||||
return {"data": "special content"}
|
||||
```
|
||||
|
||||
**Error Response**:
|
||||
```json
|
||||
{
|
||||
"detail": "Required role 'moderator' not found. Current role: 'vendor'"
|
||||
}
|
||||
```
|
||||
|
||||
**Note**: For standard roles (admin, vendor, customer), prefer using the dedicated methods (`require_admin()`, `require_vendor()`, `require_customer()`) as they provide better error handling and custom exceptions.
|
||||
|
||||
### create_default_admin_user()
|
||||
|
||||
Creates a default admin user if one doesn't already exist. This is typically used during initial application setup or database seeding.
|
||||
|
||||
**Method Signature**:
|
||||
```python
|
||||
def create_default_admin_user(self, db: Session) -> User
|
||||
```
|
||||
|
||||
**Parameters**:
|
||||
- `db` (Session): SQLAlchemy database session
|
||||
|
||||
**Returns**: `User` object (either the existing admin user or the newly created one)
|
||||
|
||||
**Behavior**:
|
||||
1. Checks if a user with username "admin" already exists
|
||||
2. If not found, creates a new admin user with:
|
||||
- Username: `admin`
|
||||
- Email: `admin@example.com`
|
||||
- Password: `admin123` (hashed with bcrypt)
|
||||
- Role: `admin`
|
||||
- Status: Active
|
||||
3. If found, returns the existing user without modification
|
||||
|
||||
**Usage Example**:
|
||||
```python
|
||||
from app.core.database import SessionLocal
|
||||
from middleware.auth import auth_manager
|
||||
|
||||
# During application startup or database initialization
|
||||
db = SessionLocal()
|
||||
try:
|
||||
admin_user = auth_manager.create_default_admin_user(db)
|
||||
print(f"Admin user ready: {admin_user.username}")
|
||||
finally:
|
||||
db.close()
|
||||
```
|
||||
|
||||
**Security Warning**:
|
||||
⚠️ The default credentials (`admin` / `admin123`) should be changed immediately after first login in production environments. Consider using environment variables for initial admin credentials:
|
||||
|
||||
```python
|
||||
# Example: Custom admin creation with env variables
|
||||
import os
|
||||
|
||||
def create_admin_from_env(db: Session):
|
||||
admin_username = os.getenv("ADMIN_USERNAME", "admin")
|
||||
admin_password = os.getenv("ADMIN_PASSWORD", "admin123")
|
||||
admin_email = os.getenv("ADMIN_EMAIL", "admin@example.com")
|
||||
|
||||
# Check if admin exists
|
||||
admin = db.query(User).filter(User.username == admin_username).first()
|
||||
if not admin:
|
||||
admin = User(
|
||||
username=admin_username,
|
||||
email=admin_email,
|
||||
hashed_password=auth_manager.hash_password(admin_password),
|
||||
role="admin",
|
||||
is_active=True
|
||||
)
|
||||
db.add(admin)
|
||||
db.commit()
|
||||
return admin
|
||||
```
|
||||
|
||||
**Typical Use Cases**:
|
||||
- Initial database setup scripts
|
||||
- Application bootstrap/initialization
|
||||
- Development environment setup
|
||||
- Testing fixtures
|
||||
|
||||
## JWT Token Structure
|
||||
|
||||
|
||||
Reference in New Issue
Block a user