|
|
|
|
@ -12,18 +12,13 @@ User = get_user_model() |
|
|
|
|
|
|
|
|
|
@receiver(pre_save) |
|
|
|
|
def presave_handler(sender, instance, **kwargs): |
|
|
|
|
try: |
|
|
|
|
sender.objects.get(pk=instance.pk) |
|
|
|
|
created = False |
|
|
|
|
except sender.DoesNotExist: |
|
|
|
|
created = True |
|
|
|
|
synchronization_prepare(sender, instance, created, **kwargs) |
|
|
|
|
synchronization_prepare(sender, instance, **kwargs) |
|
|
|
|
|
|
|
|
|
@receiver(pre_delete) |
|
|
|
|
def predelete_handler(sender, instance, **kwargs): |
|
|
|
|
synchronization_prepare(sender, instance, False, **kwargs) |
|
|
|
|
# @receiver(pre_delete) |
|
|
|
|
# def predelete_handler(sender, instance, **kwargs): |
|
|
|
|
# synchronization_prepare(sender, instance, False, **kwargs) |
|
|
|
|
|
|
|
|
|
def synchronization_prepare(sender, instance, created, **kwargs): |
|
|
|
|
def synchronization_prepare(sender, instance, **kwargs): |
|
|
|
|
|
|
|
|
|
signal = kwargs.get('signal') |
|
|
|
|
|
|
|
|
|
@ -35,15 +30,11 @@ def synchronization_prepare(sender, instance, created, **kwargs): |
|
|
|
|
if not isinstance(instance, BaseModel) and not isinstance(instance, User): |
|
|
|
|
return |
|
|
|
|
|
|
|
|
|
device_id = None |
|
|
|
|
if hasattr(instance, '_device_id'): |
|
|
|
|
device_id = instance._device_id |
|
|
|
|
|
|
|
|
|
# print(f'kwargs = {kwargs}') |
|
|
|
|
save_model_log_if_possible(instance, signal, created, device_id) |
|
|
|
|
|
|
|
|
|
if signal == pre_save: |
|
|
|
|
# print('yes') |
|
|
|
|
device_id = None |
|
|
|
|
if hasattr(instance, '_device_id'): |
|
|
|
|
device_id = instance._device_id |
|
|
|
|
|
|
|
|
|
detect_foreign_key_changes(sender, instance, device_id) |
|
|
|
|
|
|
|
|
|
@receiver([post_save, post_delete]) |
|
|
|
|
@ -58,6 +49,15 @@ def synchronization_notifications(sender, instance, created=False, **kwargs): |
|
|
|
|
if not isinstance(instance, BaseModel) and not isinstance(instance, User): |
|
|
|
|
return |
|
|
|
|
|
|
|
|
|
device_id = None |
|
|
|
|
if hasattr(instance, '_device_id'): |
|
|
|
|
device_id = instance._device_id |
|
|
|
|
|
|
|
|
|
process_foreign_key_changes(sender, instance, device_id, **kwargs) |
|
|
|
|
|
|
|
|
|
signal = kwargs.get('signal') |
|
|
|
|
save_model_log_if_possible(instance, signal, created, device_id) |
|
|
|
|
|
|
|
|
|
# print(f'*** instance._state.db: {instance._state.db}') |
|
|
|
|
notify_impacted_users(instance) |
|
|
|
|
|
|
|
|
|
@ -117,12 +117,11 @@ def save_model_log_if_possible(instance, signal, created, device_id): |
|
|
|
|
print(f'>>> Model Log could not be created because no linked user could be found: {instance}, {signal}') |
|
|
|
|
|
|
|
|
|
def save_model_log(users, model_operation, model_name, model_id, store_id, device_id): |
|
|
|
|
now = timezone.now() |
|
|
|
|
# print(f'ML users = {len(users)}') |
|
|
|
|
existing_log = ModelLog.objects.filter(users__in=users, model_id=model_id, operation=model_operation).first() |
|
|
|
|
if existing_log: |
|
|
|
|
# print(f'update existing log {existing_log.users} ') |
|
|
|
|
existing_log.date = now |
|
|
|
|
existing_log.date = timezone.now() |
|
|
|
|
existing_log.device_id = device_id |
|
|
|
|
# existing_log.operation = model_operation |
|
|
|
|
existing_log.save() |
|
|
|
|
@ -130,7 +129,7 @@ def save_model_log(users, model_operation, model_name, model_id, store_id, devic |
|
|
|
|
else: |
|
|
|
|
model_log = ModelLog() |
|
|
|
|
model_log.operation = model_operation |
|
|
|
|
model_log.date = now |
|
|
|
|
model_log.date = timezone.now() |
|
|
|
|
model_log.model_name = model_name |
|
|
|
|
model_log.model_id = model_id |
|
|
|
|
model_log.store_id = store_id |
|
|
|
|
@ -158,17 +157,38 @@ def detect_foreign_key_changes(sender, instance, device_id): |
|
|
|
|
old_value = getattr(old_instance, field.name, None) |
|
|
|
|
new_value = getattr(instance, field.name, None) |
|
|
|
|
if old_value != new_value: |
|
|
|
|
for data_access in data_access_list: |
|
|
|
|
if old_value: |
|
|
|
|
model_name = old_value.__class__.__name__ |
|
|
|
|
save_model_log(data_access.concerned_users(), 'REVOKE_ACCESS', model_name, old_value.id, old_value.get_store_id(), device_id) |
|
|
|
|
if new_value: |
|
|
|
|
model_name = new_value.__class__.__name__ |
|
|
|
|
save_model_log(data_access.concerned_users(), 'GRANT_ACCESS', model_name, new_value.id, new_value.get_store_id(), device_id) |
|
|
|
|
|
|
|
|
|
# REVOKE access for old_value and GRANT new_value |
|
|
|
|
print(f"Foreign key changed in {sender.__name__}: " |
|
|
|
|
f"{field.name} from {old_value} to {new_value}") |
|
|
|
|
instance._fk_changes.append({ |
|
|
|
|
'data_access_list': data_access_list, |
|
|
|
|
'old_value': old_value, |
|
|
|
|
'new_value': new_value |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
# for data_access in data_access_list: |
|
|
|
|
# if old_value: |
|
|
|
|
# model_name = old_value.__class__.__name__ |
|
|
|
|
# save_model_log(data_access.concerned_users(), 'REVOKE_ACCESS', model_name, old_value.id, old_value.get_store_id(), device_id) |
|
|
|
|
# if new_value: |
|
|
|
|
# model_name = new_value.__class__.__name__ |
|
|
|
|
# save_model_log(data_access.concerned_users(), 'GRANT_ACCESS', model_name, new_value.id, new_value.get_store_id(), device_id) |
|
|
|
|
|
|
|
|
|
# # REVOKE access for old_value and GRANT new_value |
|
|
|
|
# print(f"Foreign key changed in {sender.__name__}: " |
|
|
|
|
# f"{field.name} from {old_value} to {new_value}") |
|
|
|
|
|
|
|
|
|
def process_foreign_key_changes(sender, instance, device_id, **kwargs): |
|
|
|
|
if hasattr(instance, '_fk_changes'): |
|
|
|
|
for change in instance._fk_changes: |
|
|
|
|
for data_access in change['data_access_list']: |
|
|
|
|
if change['old_value']: |
|
|
|
|
model_name = change['old_value'].__class__.__name__ |
|
|
|
|
save_model_log(data_access.concerned_users(), 'REVOKE_ACCESS', |
|
|
|
|
model_name, change['old_value'].id, |
|
|
|
|
change['old_value'].get_store_id(), device_id) |
|
|
|
|
if change['new_value']: |
|
|
|
|
model_name = change['new_value'].__class__.__name__ |
|
|
|
|
save_model_log(data_access.concerned_users(), 'GRANT_ACCESS', |
|
|
|
|
model_name, change['new_value'].id, |
|
|
|
|
change['new_value'].get_store_id(), device_id) |
|
|
|
|
|
|
|
|
|
@receiver(post_delete) |
|
|
|
|
def delete_data_access_if_necessary(sender, instance, **kwargs): |
|
|
|
|
|