44 lines
1.1 KiB
Python
44 lines
1.1 KiB
Python
from functools import wraps
|
|
import hmac
|
|
import secrets
|
|
|
|
from flask import abort, flash, request, session, redirect, url_for
|
|
|
|
def admin_required(f):
|
|
@wraps(f)
|
|
def decorated_function(*args, **kwargs):
|
|
if session.get('is_admin'):
|
|
return f(*args, **kwargs)
|
|
flash('Admin access required', 'warning')
|
|
return redirect(url_for('admin.login'))
|
|
return decorated_function
|
|
|
|
|
|
def get_csrf_token():
|
|
token = session.get('_csrf_token')
|
|
if not token:
|
|
token = secrets.token_urlsafe(32)
|
|
session['_csrf_token'] = token
|
|
return token
|
|
|
|
|
|
def validate_csrf():
|
|
expected = session.get('_csrf_token')
|
|
received = (
|
|
request.headers.get('X-CSRF-Token')
|
|
or request.form.get('_csrf_token')
|
|
)
|
|
if not expected or not received or not hmac.compare_digest(
|
|
str(expected),
|
|
str(received),
|
|
):
|
|
abort(400, description='Invalid CSRF token')
|
|
|
|
|
|
def csrf_protected(f):
|
|
@wraps(f)
|
|
def decorated_function(*args, **kwargs):
|
|
validate_csrf()
|
|
return f(*args, **kwargs)
|
|
return decorated_function
|