Coverage for src/resources/ws/sandbox_resource.py : 38%
Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1from flask import request, current_app
2from flask_socketio import Namespace, emit, join_room, leave_room, close_room, rooms, disconnect
3from flask_jwt_extended import decode_token
4from flask_socketio import ConnectionRefusedError
5from uuid import UUID
7from src.addons import socketio
8from src.model import UserModel
9from src.schemas import ProfileBase
10from src.service import ProfileService
13class SandboxResource(Namespace):
14 def is_auth(func):
15 def wrapper(*args, **kwargs):
16 if not 'token' in request.headers:
17 raise ConnectionRefusedError("Token not found !")
19 try:
20 tk = decode_token(request.headers["token"])
21 except Exception as e:
22 raise ConnectionRefusedError("Unauthorized!")
24 # Check identity
25 if not (user := UserModel.query.filter_by(uuid=tk['identity']).first()):
26 raise ConnectionRefusedError("User not found!")
28 # Check permissions
29 # NOTE ws only used in sandbox, that's why we check this permission here
30 if "access_sandbox" not in tk['user_claims']['permissions']:
31 raise ConnectionRefusedError("Permission missing!")
33 return func(*args, connected_user=user, **kwargs)
35 return wrapper
37 @is_auth
38 def on_connect(self, connected_user):
39 current_app.logger.info('Client connected %s' % request.sid)
40 emit('server_response', {'on': 'connect',
41 'action': 'connect', 'message': 'Connected'})
43 @is_auth
44 def on_disconnect(self, connected_user):
45 current_app.logger.info('Client disconnected %s' % request.sid)
47 @is_auth
48 def on_join(self, connected_user):
49 current_app.logger.info('Join %s' % request.sid)
50 room = "user%s" % connected_user.uuid
51 join_room(room)
52 emit('server_response', {
53 'on': 'join',
54 'action': 'join',
55 'message': 'Room successfully joined',
56 'user_uuid': str(connected_user.uuid),
57 'room': room
58 }, room=room)
60 @is_auth
61 def on_leave(self, connected_user):
62 current_app.logger.info('Leave %s' % request.sid)
63 room = "user%s" % connected_user.uuid
64 leave_room(room)
65 emit('server_response', {
66 'on': 'leave',
67 'action': 'leave',
68 'message': 'Room successfully leaved',
69 'user_uuid': str(connected_user.uuid),
70 'room': room
71 }, room=room)
73 @is_auth
74 def on_recommend(self, json, connected_user):
75 current_app.logger.info('Recommend %s' % request.sid)
76 if "profile_uuid" not in json:
77 emit('server_response', {
78 'on': 'recommend', 'message': "Error 400, data must contain 'profile_uuid' attr!"})
79 else:
80 room = "user%s" % connected_user.uuid
82 # Check profile uuid
83 try:
84 profile_uuid = UUID(json["profile_uuid"], version=4)
85 except ValueError:
86 emit('server_response', {
87 'on': 'recommend', 'message': "Error 400, 'profile_uuid' not valid uuid4!"})
88 return
90 current_app.logger.info(
91 "Launch recommendation for profile %s" % profile_uuid)
93 # Join room if needed
94 join_room(room)
95 emit('server_response', {
96 'on': 'recommend',
97 'action': 'join',
98 'message': 'Room joined',
99 'user_uuid': str(connected_user.uuid),
100 'room': room
101 }, room=room)
103 data, code, profile = ProfileService.launch_recommendation(
104 profile_uuid, connected_user)
106 if code == 200:
107 emit('server_response', {
108 'on': 'recommend',
109 'action': 'recommend',
110 'message': '%s, %s' % (code, data["message"]),
111 'profile': ProfileBase.load(profile)
112 }, room=room)
113 else:
114 emit('server_response', {
115 'on': 'recommend',
116 'action': 'recommend',
117 'message': 'Error %s, %s' % (code, data["message"]),
118 'profile': ProfileBase.load(profile)
119 }, room=room)