move socketio decorators

This commit is contained in:
Patrick Jentsch 2024-05-04 14:55:05 +02:00
parent 882987ba68
commit e1cfd394fa
9 changed files with 44 additions and 70 deletions

View File

@ -1,7 +1,7 @@
from flask_login import current_user from flask_login import current_user
from flask_socketio import disconnect, Namespace from flask_socketio import disconnect, Namespace
from app import db, hashids from app import db, hashids
from app.extensions.flask_socketio_extras import admin_required from app.decorators import socketio_admin_required
from app.models import User from app.models import User
@ -12,7 +12,7 @@ class AdminNamespace(Namespace):
disconnect() disconnect()
@admin_required @socketio_admin_required
def on_set_user_confirmed(self, user_hashid: str, confirmed_value: bool): def on_set_user_confirmed(self, user_hashid: str, confirmed_value: bool):
# Decode the user hashid # Decode the user hashid
user_id = hashids.decode(user_hashid) user_id = hashids.decode(user_hashid)

View File

@ -9,7 +9,7 @@ from inspect import signature
from threading import Lock from threading import Lock
from typing import Callable, Dict, List, Optional from typing import Callable, Dict, List, Optional
from app import db, docker_client, hashids, socketio from app import db, docker_client, hashids, socketio
from app.extensions.flask_socketio_extras import login_required from app.decorators import socketio_login_required
from app.models import Corpus, CorpusStatus from app.models import Corpus, CorpusStatus
from . import extensions from . import extensions
@ -87,11 +87,11 @@ CQI_API_FUNCTION_NAMES: List[str] = [
class CQiNamespace(Namespace): class CQiNamespace(Namespace):
@login_required @socketio_login_required
def on_connect(self): def on_connect(self):
pass pass
@login_required @socketio_login_required
def on_init(self, db_corpus_hashid: str): def on_init(self, db_corpus_hashid: str):
db_corpus_id: int = hashids.decode(db_corpus_hashid) db_corpus_id: int = hashids.decode(db_corpus_hashid)
db_corpus: Optional[Corpus] = Corpus.query.get(db_corpus_id) db_corpus: Optional[Corpus] = Corpus.query.get(db_corpus_id)
@ -134,7 +134,7 @@ class CQiNamespace(Namespace):
} }
return {'code': 200, 'msg': 'OK'} return {'code': 200, 'msg': 'OK'}
@login_required @socketio_login_required
def on_exec(self, fn_name: str, fn_args: Dict = {}): def on_exec(self, fn_name: str, fn_args: Dict = {}):
try: try:
cqi_client: CQiClient = session['cqi_over_sio']['cqi_client'] cqi_client: CQiClient = session['cqi_over_sio']['cqi_client']

View File

@ -1,12 +1,12 @@
from flask_login import current_user from flask_login import current_user
from flask_socketio import join_room from flask_socketio import join_room
from app import hashids, socketio from app import hashids, socketio
from app.extensions.flask_socketio_extras import login_required from app.decorators import socketio_login_required
from app.models import Corpus from app.models import Corpus
@socketio.on('GET /corpora/<corpus_id>') @socketio.on('GET /corpora/<corpus_id>')
@login_required @socketio_login_required
def get_corpus(corpus_hashid): def get_corpus(corpus_hashid):
corpus_id = hashids.decode(corpus_hashid) corpus_id = hashids.decode(corpus_hashid)
corpus = Corpus.query.get(corpus_id) corpus = Corpus.query.get(corpus_id)
@ -29,7 +29,7 @@ def get_corpus(corpus_hashid):
@socketio.on('SUBSCRIBE /corpora/<corpus_id>') @socketio.on('SUBSCRIBE /corpora/<corpus_id>')
@login_required @socketio_login_required
def subscribe_corpus(corpus_hashid): def subscribe_corpus(corpus_hashid):
corpus_id = hashids.decode(corpus_hashid) corpus_id = hashids.decode(corpus_hashid)
corpus = Corpus.query.get(corpus_id) corpus = Corpus.query.get(corpus_id)

View File

@ -1,7 +1,6 @@
from flask import abort, current_app, request from flask import abort, request
from flask_login import current_user from flask_login import current_user
from functools import wraps from functools import wraps
from threading import Thread
from typing import List, Union from typing import List, Union
from werkzeug.exceptions import NotAcceptable from werkzeug.exceptions import NotAcceptable
from app.models import Permission from app.models import Permission
@ -22,22 +21,28 @@ def admin_required(f):
return permission_required(Permission.ADMINISTRATE)(f) return permission_required(Permission.ADMINISTRATE)(f)
def background(f): def socketio_login_required(f):
'''
' This decorator executes a function in a Thread.
' Decorated functions need to be executed within a code block where an
' app context exists.
'
' NOTE: An app object is passed as a keyword argument to the decorated
' function.
'''
@wraps(f) @wraps(f)
def wrapped(*args, **kwargs): def wrapper(*args, **kwargs):
kwargs['app'] = current_app._get_current_object() if current_user.is_authenticated:
thread = Thread(target=f, args=args, kwargs=kwargs) return f(*args, **kwargs)
thread.start() return {'code': 401, 'body': 'Unauthorized'}
return thread return wrapper
return wrapped
def socketio_permission_required(permission):
def decorator(f):
@wraps(f)
def wrapper(*args, **kwargs):
if not current_user.can(permission):
return {'code': 403, 'body': 'Forbidden'}
return f(*args, **kwargs)
return wrapper
return decorator
def socketio_admin_required(f):
return socketio_permission_required(Permission.ADMINISTRATE)(f)
def content_negotiation( def content_negotiation(

View File

@ -1 +0,0 @@

View File

@ -1,3 +0,0 @@
from .decorators import login_required
from .decorators import permission_required
from .decorators import admin_required

View File

@ -1,27 +0,0 @@
from flask_login import current_user
from functools import wraps
from app.models import Permission as UserPermission
def login_required(f):
@wraps(f)
def wrapper(*args, **kwargs):
if current_user.is_authenticated:
return f(*args, **kwargs)
return {'code': 401, 'body': 'Unauthorized'}
return wrapper
def permission_required(permission):
def decorator(f):
@wraps(f)
def wrapper(*args, **kwargs):
if not current_user.can(permission):
return {'code': 403, 'body': 'Forbidden'}
return f(*args, **kwargs)
return wrapper
return decorator
def admin_required(f):
return permission_required(UserPermission.ADMINISTRATE)(f)

View File

@ -1,12 +1,12 @@
from flask_login import current_user from flask_login import current_user
from flask_socketio import join_room, leave_room from flask_socketio import join_room, leave_room
from app import hashids, socketio from app import hashids, socketio
from app.extensions.flask_socketio_extras import login_required from app.decorators import socketio_login_required
from app.models import User from app.models import User
@socketio.on('GET /users/<user_id>') @socketio.on('GET /users/<user_id>')
@login_required @socketio_login_required
def get_user(user_hashid): def get_user(user_hashid):
user_id = hashids.decode(user_hashid) user_id = hashids.decode(user_hashid)
user = User.query.get(user_id) user = User.query.get(user_id)
@ -22,7 +22,7 @@ def get_user(user_hashid):
@socketio.on('SUBSCRIBE /users/<user_id>') @socketio.on('SUBSCRIBE /users/<user_id>')
@login_required @socketio_login_required
def subscribe_user(user_hashid): def subscribe_user(user_hashid):
user_id = hashids.decode(user_hashid) user_id = hashids.decode(user_hashid)
user = User.query.get(user_id) user = User.query.get(user_id)
@ -35,7 +35,7 @@ def subscribe_user(user_hashid):
@socketio.on('UNSUBSCRIBE /users/<user_id>') @socketio.on('UNSUBSCRIBE /users/<user_id>')
@login_required @socketio_login_required
def unsubscribe_user(user_hashid): def unsubscribe_user(user_hashid):
user_id = hashids.decode(user_hashid) user_id = hashids.decode(user_hashid)
user = User.query.get(user_id) user = User.query.get(user_id)

View File

@ -1,12 +1,12 @@
from flask_login import current_user from flask_login import current_user
from flask_socketio import join_room from flask_socketio import join_room
from app import hashids, socketio from app import hashids, socketio
from app.extensions.flask_socketio_extras import admin_required, login_required from app.decorators import socketio_admin_required, socketio_login_required
from app.models import User from app.models import User
@socketio.on('GET /users') @socketio.on('GET /users')
@admin_required @socketio_admin_required
def get_users(): def get_users():
users = User.query.filter_by().all() users = User.query.filter_by().all()
return { return {
@ -20,14 +20,14 @@ def get_users():
@socketio.on('SUBSCRIBE /users') @socketio.on('SUBSCRIBE /users')
@admin_required @socketio_admin_required
def subscribe_users(): def subscribe_users():
join_room('/users') join_room('/users')
return {'options': {'status': 200, 'statusText': 'OK'}} return {'options': {'status': 200, 'statusText': 'OK'}}
@socketio.on('GET /users/<user_id>') @socketio.on('GET /users/<user_id>')
@login_required @socketio_login_required
def get_user(user_hashid): def get_user(user_hashid):
user_id = hashids.decode(user_hashid) user_id = hashids.decode(user_hashid)
user = User.query.get(user_id) user = User.query.get(user_id)
@ -46,7 +46,7 @@ def get_user(user_hashid):
@socketio.on('SUBSCRIBE /users/<user_id>') @socketio.on('SUBSCRIBE /users/<user_id>')
@login_required @socketio_login_required
def subscribe_user(user_hashid): def subscribe_user(user_hashid):
user_id = hashids.decode(user_hashid) user_id = hashids.decode(user_hashid)
user = User.query.get(user_id) user = User.query.get(user_id)
@ -59,7 +59,7 @@ def subscribe_user(user_hashid):
@socketio.on('GET /public_users') @socketio.on('GET /public_users')
@login_required @socketio_login_required
def get_public_users(): def get_public_users():
users = User.query.filter_by(is_public=True).all() users = User.query.filter_by(is_public=True).all()
return { return {
@ -76,14 +76,14 @@ def get_public_users():
@socketio.on('SUBSCRIBE /users') @socketio.on('SUBSCRIBE /users')
@admin_required @socketio_admin_required
def subscribe_users(): def subscribe_users():
join_room('/public_users') join_room('/public_users')
return {'options': {'status': 200, 'statusText': 'OK'}} return {'options': {'status': 200, 'statusText': 'OK'}}
@socketio.on('GET /public_users/<user_id>') @socketio.on('GET /public_users/<user_id>')
@login_required @socketio_login_required
def get_user(user_hashid): def get_user(user_hashid):
user_id = hashids.decode(user_hashid) user_id = hashids.decode(user_hashid)
user = User.query.filter_by(id=user_id, is_public=True).first() user = User.query.filter_by(id=user_id, is_public=True).first()
@ -102,7 +102,7 @@ def get_user(user_hashid):
@socketio.on('SUBSCRIBE /public_users/<user_id>') @socketio.on('SUBSCRIBE /public_users/<user_id>')
@login_required @socketio_login_required
def subscribe_user(user_hashid): def subscribe_user(user_hashid):
user_id = hashids.decode(user_hashid) user_id = hashids.decode(user_hashid)
user = User.query.filter_by(id=user_id, is_public=True).first() user = User.query.filter_by(id=user_id, is_public=True).first()