From 91e42d6d92a68509d370d8652da1d191257d5c2f Mon Sep 17 00:00:00 2001 From: Patrick Jentsch Date: Tue, 9 May 2023 14:18:59 +0200 Subject: [PATCH 1/2] Revert changes and fix some typos --- app/models.py | 100 +++++++++++++++++++++++--------------------------- 1 file changed, 46 insertions(+), 54 deletions(-) diff --git a/app/models.py b/app/models.py index 61587dd7..22969c2f 100644 --- a/app/models.py +++ b/app/models.py @@ -1678,33 +1678,28 @@ class Corpus(HashidMixin, db.Model): @db.event.listens_for(JobResult, 'after_delete') @db.event.listens_for(SpaCyNLPPipelineModel, 'after_delete') @db.event.listens_for(TesseractOCRPipelineModel, 'after_delete') -def ressource_after_delete(mapper, connection, ressource): - jsonpatch = [{'op': 'remove', 'path': ressource.jsonpatch_path}] - room = f'/users/{ressource.user_hashid}' +def resource_after_delete(mapper, connection, resource): + jsonpatch = [ + { + 'op': 'remove', + 'path': resource.jsonpatch_path + } + ] + room = f'/users/{resource.user_hashid}' socketio.emit('PATCH', jsonpatch, room=room) @db.event.listens_for(CorpusFollowerAssociation, 'after_delete') -def corpus_follower_association_after_delete_handler(mapper, connection, ressource): - corpus_owner_hashid = ressource.corpus.user.hashid - corpus_hashid = ressource.corpus.hashid - # Send a PATCH to the corpus owner - jsonpatch_path = f'/users/{corpus_owner_hashid}/corpora/{corpus_hashid}/corpus_follower_associations/{ressource.hashid}' - jsonpatch = [{'op': 'remove', 'path': jsonpatch_path}] - room = f'/users/{corpus_owner_hashid}' - socketio.emit('PATCH', jsonpatch, room=room) - # Send a PATCH to the followers (the deleted follower and others with permission "MANAGE_FOLLOWERS") - followers = [ - x for x in ressource.corpus.corpus_follower_associations - if x.follower_id == ressource.follower_id - or x.role.has_permission('MANAGE_FOLLOWERS') +def cfa_after_delete_handler(mapper, connection, cfa): + jsonpatch_path = f'/users/{cfa.corpus.user.hashid}/corpora/{cfa.corpus.hashid}/corpus_follower_associations/{cfa.hashid}' + jsonpatch = [ + { + 'op': 'remove', + 'path': jsonpatch_path + } ] - for follower in followers: - jsonpatch_path = f'/users/{follower.hashid}/corpus_follower_associations/{ressource.hashid}' - jsonpatch = [{'op': 'remove', 'path': jsonpatch_path}] - room = f'/users/{follower.hashid}' - socketio.emit('PATCH', jsonpatch, room=room) - + room = f'/users/{cfa.corpus.user.hashid}' + socketio.emit('PATCH', jsonpatch, room=room) @db.event.listens_for(Corpus, 'after_insert') @@ -1714,38 +1709,34 @@ def corpus_follower_association_after_delete_handler(mapper, connection, ressour @db.event.listens_for(JobResult, 'after_insert') @db.event.listens_for(SpaCyNLPPipelineModel, 'after_insert') @db.event.listens_for(TesseractOCRPipelineModel, 'after_insert') -def ressource_after_insert_handler(mapper, connection, ressource): - value = ressource.to_json_serializeable() +def resource_after_insert_handler(mapper, connection, resource): + jsonpatch_value = resource.to_json_serializeable() for attr in mapper.relationships: - value[attr.key] = {} + jsonpatch_value[attr.key] = {} jsonpatch = [ - {'op': 'add', 'path': ressource.jsonpatch_path, 'value': value} + { + 'op': 'add', + 'path': resource.jsonpatch_path, + 'value': jsonpatch_value + } ] - room = f'/users/{ressource.user_hashid}' + room = f'/users/{resource.user_hashid}' socketio.emit('PATCH', jsonpatch, room=room) @db.event.listens_for(CorpusFollowerAssociation, 'after_insert') -def corpus_follower_association_after_insert_handler(mapper, connection, ressource): - corpus_owner_hashid = ressource.corpus.user.hashid - corpus_hashid = ressource.corpus.hashid - value = ressource.to_json_serializeable() - # Send a PATCH to the corpus owner - jsonpatch_path = f'/users/{corpus_owner_hashid}/corpora/{corpus_hashid}/corpus_follower_associations/{ressource.hashid}' - jsonpatch = [{'op': 'add', 'path': jsonpatch_path, 'value': value}] - room = f'/users/{corpus_owner_hashid}' - socketio.emit('PATCH', jsonpatch, room=room) - # Send a PATCH to the followers (the deleted follower and others with permission "MANAGE_FOLLOWERS") - followers = [ - x for x in ressource.corpus.corpus_follower_associations - if x.follower_id == ressource.follower_id - or x.role.has_permission('MANAGE_FOLLOWERS') +def cfa_after_insert_handler(mapper, connection, cfa): + jsonpatch_value = cfa.to_json_serializeable() + jsonpatch_path = f'/users/{cfa.corpus.user.hashid}/corpora/{cfa.corpus.hashid}/corpus_follower_associations/{cfa.hashid}' + jsonpatch = [ + { + 'op': 'add', + 'path': jsonpatch_path, + 'value': jsonpatch_value + } ] - for follower in followers: - jsonpatch_path = f'/users/{follower.hashid}/corpus_follower_associations/{ressource.hashid}' - jsonpatch = [{'op': 'add', 'path': jsonpatch_path, 'value': value}] - room = f'/users/{follower.hashid}' - socketio.emit('PATCH', jsonpatch, room=room) + room = f'/users/{cfa.corpus.user.hashid}' + socketio.emit('PATCH', jsonpatch, room=room) @db.event.listens_for(Corpus, 'after_update') @@ -1755,28 +1746,29 @@ def corpus_follower_association_after_insert_handler(mapper, connection, ressour @db.event.listens_for(JobResult, 'after_update') @db.event.listens_for(SpaCyNLPPipelineModel, 'after_update') @db.event.listens_for(TesseractOCRPipelineModel, 'after_update') -def ressource_after_update_handler(mapper, connection, ressource): +def resource_after_update_handler(mapper, connection, resource): jsonpatch = [] - for attr in db.inspect(ressource).attrs: + for attr in db.inspect(resource).attrs: if attr.key in mapper.relationships: continue if not attr.load_history().has_changes(): continue + jsonpatch_path = f'{resource.jsonpatch_path}/{attr.key}' if isinstance(attr.value, datetime): - value = f'{attr.value.isoformat()}Z' + jsonpatch_value = f'{attr.value.isoformat()}Z' elif isinstance(attr.value, Enum): - value = attr.value.name + jsonpatch_value = attr.value.name else: - value = attr.value + jsonpatch_value = attr.value jsonpatch.append( { 'op': 'replace', - 'path': f'{ressource.jsonpatch_path}/{attr.key}', - 'value': value + 'path': jsonpatch_path, + 'value': jsonpatch_value } ) if jsonpatch: - room = f'/users/{ressource.user_hashid}' + room = f'/users/{resource.user_hashid}' socketio.emit('PATCH', jsonpatch, room=room) From 595bda98ef56f9a0f30dacb6ab9801ef25bee99d Mon Sep 17 00:00:00 2001 From: Patrick Jentsch Date: Tue, 9 May 2023 15:32:09 +0200 Subject: [PATCH 2/2] Fix wrong admin check --- app/users/events.py | 54 +++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/app/users/events.py b/app/users/events.py index 532bf42d..fd6dc6db 100644 --- a/app/users/events.py +++ b/app/users/events.py @@ -12,7 +12,7 @@ def get_user(user_hashid, backrefs=False, relationships=False): user = User.query.get(user_id) if user is None: return {'status': 404, 'statusText': 'Not found'} - if not (user == current_user or current_user.is_administrator): + if not (user == current_user or current_user.is_administrator()): return {'status': 403, 'statusText': 'Forbidden'} return { 'body': user.to_json_serializeable( @@ -24,25 +24,6 @@ def get_user(user_hashid, backrefs=False, relationships=False): } -# @socketio.on('GET /users/') -# @socketio_login_required -# def get_user(user_hashid): -# user_id = hashids.decode(user_hashid) -# user = User.query.get(user_id) -# if user is None: -# return {'options': {'status': 404, 'statusText': 'Not found'}} -# if not (user == current_user or current_user.is_administrator): -# return {'options': {'status': 403, 'statusText': 'Forbidden'}} -# return { -# 'body': user.to_json_serializable2(), -# 'options': { -# 'status': 200, -# 'statusText': 'OK', -# 'headers': {'Content-Type: application/json'} -# } -# } - - @socketio.on('SUBSCRIBE /users/') @socketio_login_required def subscribe_user(user_hashid): @@ -50,7 +31,7 @@ def subscribe_user(user_hashid): user = User.query.get(user_id) if user is None: return {'status': 404, 'statusText': 'Not found'} - if not (user == current_user or current_user.is_administrator): + if not (user == current_user or current_user.is_administrator()): return {'status': 403, 'statusText': 'Forbidden'} join_room(f'/users/{user.hashid}') return {'status': 200, 'statusText': 'OK'} @@ -63,7 +44,36 @@ def unsubscribe_user(user_hashid): user = User.query.get(user_id) if user is None: return {'status': 404, 'statusText': 'Not found'} - if not (user == current_user or current_user.is_administrator): + if not (user == current_user or current_user.is_administrator()): return {'status': 403, 'statusText': 'Forbidden'} leave_room(f'/users/{user.hashid}') return {'status': 200, 'statusText': 'OK'} + + +# @socketio.on('GET User') +# @socketio_login_required +# def n_get_user(user_hashid): +# # This constructs a JSON response which can easily be converted to a Response object +# # Ref: https://developer.mozilla.org/en-US/docs/Web/API/Response/Response +# user_id = hashids.decode(user_hashid) +# user = User.query.get(user_id) +# if user is None: +# return {'options': {'status': 404, 'statusText': 'Not found'}} +# if not (user == current_user or current_user.is_administrator()): +# return {'options': {'status': 403, 'statusText': 'Forbidden'}} +# body = { +# 'id': user.hashid, +# # ... +# 'relationships': { +# 'corpora': {corpus.hashid for corpus in user.corpora}, +# 'jobs': [job.hashid for job in user.jobs] +# } +# } +# return { +# 'body': user.to_json_serializable(), +# 'options': { +# 'status': 200, +# 'statusText': 'OK', +# 'headers': {'Content-Type: application/json'} +# } +# }