From e1cfd394fa2e321dad9e73dc2aac7621b0d00cf5 Mon Sep 17 00:00:00 2001
From: Patrick Jentsch
Date: Sat, 4 May 2024 14:55:05 +0200
Subject: [PATCH] move socketio decorators
---
app/admin/events.py | 4 +-
app/corpora/cqi_over_sio/__init__.py | 8 ++--
app/corpora/events.py | 6 +--
app/decorators.py | 39 +++++++++++--------
app/extensions/__init__.py | 1 -
.../flask_socketio_extras/__init__.py | 3 --
.../flask_socketio_extras/decorators.py | 27 -------------
app/users/events.py | 8 ++--
app/users/nevents.py | 18 ++++-----
9 files changed, 44 insertions(+), 70 deletions(-)
delete mode 100644 app/extensions/__init__.py
delete mode 100644 app/extensions/flask_socketio_extras/__init__.py
delete mode 100644 app/extensions/flask_socketio_extras/decorators.py
diff --git a/app/admin/events.py b/app/admin/events.py
index e5ed7b0b..01cefa55 100644
--- a/app/admin/events.py
+++ b/app/admin/events.py
@@ -1,7 +1,7 @@
from flask_login import current_user
from flask_socketio import disconnect, Namespace
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
@@ -12,7 +12,7 @@ class AdminNamespace(Namespace):
disconnect()
- @admin_required
+ @socketio_admin_required
def on_set_user_confirmed(self, user_hashid: str, confirmed_value: bool):
# Decode the user hashid
user_id = hashids.decode(user_hashid)
diff --git a/app/corpora/cqi_over_sio/__init__.py b/app/corpora/cqi_over_sio/__init__.py
index 90d9719e..25102c94 100644
--- a/app/corpora/cqi_over_sio/__init__.py
+++ b/app/corpora/cqi_over_sio/__init__.py
@@ -9,7 +9,7 @@ from inspect import signature
from threading import Lock
from typing import Callable, Dict, List, Optional
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 . import extensions
@@ -87,11 +87,11 @@ CQI_API_FUNCTION_NAMES: List[str] = [
class CQiNamespace(Namespace):
- @login_required
+ @socketio_login_required
def on_connect(self):
pass
- @login_required
+ @socketio_login_required
def on_init(self, db_corpus_hashid: str):
db_corpus_id: int = hashids.decode(db_corpus_hashid)
db_corpus: Optional[Corpus] = Corpus.query.get(db_corpus_id)
@@ -134,7 +134,7 @@ class CQiNamespace(Namespace):
}
return {'code': 200, 'msg': 'OK'}
- @login_required
+ @socketio_login_required
def on_exec(self, fn_name: str, fn_args: Dict = {}):
try:
cqi_client: CQiClient = session['cqi_over_sio']['cqi_client']
diff --git a/app/corpora/events.py b/app/corpora/events.py
index cc0baad1..9a0e3a36 100644
--- a/app/corpora/events.py
+++ b/app/corpora/events.py
@@ -1,12 +1,12 @@
from flask_login import current_user
from flask_socketio import join_room
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
@socketio.on('GET /corpora/')
-@login_required
+@socketio_login_required
def get_corpus(corpus_hashid):
corpus_id = hashids.decode(corpus_hashid)
corpus = Corpus.query.get(corpus_id)
@@ -29,7 +29,7 @@ def get_corpus(corpus_hashid):
@socketio.on('SUBSCRIBE /corpora/')
-@login_required
+@socketio_login_required
def subscribe_corpus(corpus_hashid):
corpus_id = hashids.decode(corpus_hashid)
corpus = Corpus.query.get(corpus_id)
diff --git a/app/decorators.py b/app/decorators.py
index 5fbd7671..051807ab 100644
--- a/app/decorators.py
+++ b/app/decorators.py
@@ -1,7 +1,6 @@
-from flask import abort, current_app, request
+from flask import abort, request
from flask_login import current_user
from functools import wraps
-from threading import Thread
from typing import List, Union
from werkzeug.exceptions import NotAcceptable
from app.models import Permission
@@ -22,22 +21,28 @@ def admin_required(f):
return permission_required(Permission.ADMINISTRATE)(f)
-def background(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.
- '''
+def socketio_login_required(f):
@wraps(f)
- def wrapped(*args, **kwargs):
- kwargs['app'] = current_app._get_current_object()
- thread = Thread(target=f, args=args, kwargs=kwargs)
- thread.start()
- return thread
- return wrapped
+ def wrapper(*args, **kwargs):
+ if current_user.is_authenticated:
+ return f(*args, **kwargs)
+ return {'code': 401, 'body': 'Unauthorized'}
+ return wrapper
+
+
+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(
diff --git a/app/extensions/__init__.py b/app/extensions/__init__.py
deleted file mode 100644
index 8b137891..00000000
--- a/app/extensions/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/app/extensions/flask_socketio_extras/__init__.py b/app/extensions/flask_socketio_extras/__init__.py
deleted file mode 100644
index 866c0cc9..00000000
--- a/app/extensions/flask_socketio_extras/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from .decorators import login_required
-from .decorators import permission_required
-from .decorators import admin_required
diff --git a/app/extensions/flask_socketio_extras/decorators.py b/app/extensions/flask_socketio_extras/decorators.py
deleted file mode 100644
index 8e8d0a05..00000000
--- a/app/extensions/flask_socketio_extras/decorators.py
+++ /dev/null
@@ -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)
diff --git a/app/users/events.py b/app/users/events.py
index e010ce10..8132f818 100644
--- a/app/users/events.py
+++ b/app/users/events.py
@@ -1,12 +1,12 @@
from flask_login import current_user
from flask_socketio import join_room, leave_room
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
@socketio.on('GET /users/')
-@login_required
+@socketio_login_required
def get_user(user_hashid):
user_id = hashids.decode(user_hashid)
user = User.query.get(user_id)
@@ -22,7 +22,7 @@ def get_user(user_hashid):
@socketio.on('SUBSCRIBE /users/')
-@login_required
+@socketio_login_required
def subscribe_user(user_hashid):
user_id = hashids.decode(user_hashid)
user = User.query.get(user_id)
@@ -35,7 +35,7 @@ def subscribe_user(user_hashid):
@socketio.on('UNSUBSCRIBE /users/')
-@login_required
+@socketio_login_required
def unsubscribe_user(user_hashid):
user_id = hashids.decode(user_hashid)
user = User.query.get(user_id)
diff --git a/app/users/nevents.py b/app/users/nevents.py
index de79161c..c67817b8 100644
--- a/app/users/nevents.py
+++ b/app/users/nevents.py
@@ -1,12 +1,12 @@
from flask_login import current_user
from flask_socketio import join_room
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
@socketio.on('GET /users')
-@admin_required
+@socketio_admin_required
def get_users():
users = User.query.filter_by().all()
return {
@@ -20,14 +20,14 @@ def get_users():
@socketio.on('SUBSCRIBE /users')
-@admin_required
+@socketio_admin_required
def subscribe_users():
join_room('/users')
return {'options': {'status': 200, 'statusText': 'OK'}}
@socketio.on('GET /users/')
-@login_required
+@socketio_login_required
def get_user(user_hashid):
user_id = hashids.decode(user_hashid)
user = User.query.get(user_id)
@@ -46,7 +46,7 @@ def get_user(user_hashid):
@socketio.on('SUBSCRIBE /users/')
-@login_required
+@socketio_login_required
def subscribe_user(user_hashid):
user_id = hashids.decode(user_hashid)
user = User.query.get(user_id)
@@ -59,7 +59,7 @@ def subscribe_user(user_hashid):
@socketio.on('GET /public_users')
-@login_required
+@socketio_login_required
def get_public_users():
users = User.query.filter_by(is_public=True).all()
return {
@@ -76,14 +76,14 @@ def get_public_users():
@socketio.on('SUBSCRIBE /users')
-@admin_required
+@socketio_admin_required
def subscribe_users():
join_room('/public_users')
return {'options': {'status': 200, 'statusText': 'OK'}}
@socketio.on('GET /public_users/')
-@login_required
+@socketio_login_required
def get_user(user_hashid):
user_id = hashids.decode(user_hashid)
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/')
-@login_required
+@socketio_login_required
def subscribe_user(user_hashid):
user_id = hashids.decode(user_hashid)
user = User.query.filter_by(id=user_id, is_public=True).first()