66 lines
1.7 KiB
Python
66 lines
1.7 KiB
Python
"""
|
|
Utilities for Flask-SQLAlchemy binding.
|
|
|
|
---
|
|
|
|
Copyright (c) 2025 Sakuragasaki46.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
See LICENSE for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
This software is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
"""
|
|
|
|
from functools import partial
|
|
from typing import Any, Callable, Never
|
|
|
|
from flask import abort, request
|
|
from flask_sqlalchemy import SQLAlchemy
|
|
from sqlalchemy.orm import DeclarativeBase, Session
|
|
|
|
from .sqlalchemy import require_auth_base
|
|
|
|
class FlaskAuthSrc(AuthSrc):
|
|
'''
|
|
|
|
'''
|
|
db: SQLAlchemy
|
|
def __init__(self, db: SQLAlchemy):
|
|
super().__init__()
|
|
self.db = db
|
|
def get_session(self) -> Session:
|
|
return self.db.session
|
|
def get_token(self):
|
|
return request.authorization.token
|
|
|
|
def invalid_exc(self, msg: str = 'validation failed') -> Never:
|
|
abort(400, msg)
|
|
def required_exc(self):
|
|
abort(401)
|
|
|
|
def require_auth(cls: type[DeclarativeBase], db: SQLAlchemy) -> Callable[Any, Callable]:
|
|
"""
|
|
Make an auth_required() decorator for Flask views.
|
|
|
|
This looks for a token in the Authorization header, validates it, loads the
|
|
appropriate object, and injects it as the user= parameter.
|
|
|
|
cls is a SQLAlchemy table.
|
|
db is a flask_sqlalchemy.SQLAlchemy() binding.
|
|
|
|
Usage:
|
|
|
|
auth_required = require_auth(User, db)
|
|
|
|
@route('/admin')
|
|
@auth_required(validators=[lambda x: x.is_administrator])
|
|
def super_secret_stuff(user):
|
|
pass
|
|
"""
|
|
return partial(require_auth_base, cls=cls, src=FlaskAuthSrc(db))
|
|
|
|
|
|
__all__ = ('require_auth', )
|