|
|
|
|
@ -15,7 +15,7 @@ from django.core.exceptions import ObjectDoesNotExist |
|
|
|
|
from collections import defaultdict |
|
|
|
|
from urllib.parse import unquote |
|
|
|
|
|
|
|
|
|
from .utils import get_serializer, build_serializer_class, get_data, get_serialized_data |
|
|
|
|
from .utils import get_serializer, build_serializer_class, get_data, get_serialized_data, HierarchyOrganizer |
|
|
|
|
|
|
|
|
|
from .models import ModelLog, BaseModel, SideStoreModel, DataAccess |
|
|
|
|
|
|
|
|
|
@ -24,31 +24,41 @@ from .registry import sync_registry |
|
|
|
|
class HierarchyApiView(APIView): |
|
|
|
|
|
|
|
|
|
def add_children_recursively(self, instance, updates): |
|
|
|
|
""" |
|
|
|
|
Recursively add all children of an instance to the updates dictionary. |
|
|
|
|
""" |
|
|
|
|
# print(f"Instance class: {instance.__class__}") |
|
|
|
|
child_models = instance.get_children_by_model() |
|
|
|
|
|
|
|
|
|
for child_model_name, children in child_models.items(): |
|
|
|
|
for child in children: |
|
|
|
|
if isinstance(child, BaseModel): |
|
|
|
|
serializer = get_serializer(child, child_model_name) |
|
|
|
|
# serializer_class = build_serializer_class(child_model_name) |
|
|
|
|
# serializer = serializer_class(child) |
|
|
|
|
updates[child_model_name][child.id] = serializer.data |
|
|
|
|
self.add_children_recursively(child, updates) |
|
|
|
|
|
|
|
|
|
# def add_parents_recursively(self, instance, updates): |
|
|
|
|
# parent_models = instance.get_parents_by_model() |
|
|
|
|
|
|
|
|
|
# for parent_model_name, parent in parent_models.items(): |
|
|
|
|
# # print(f'parent = {parent_model_name}') |
|
|
|
|
# if isinstance(parent, BaseModel): |
|
|
|
|
# serializer_class = build_serializer_class(parent_model_name) |
|
|
|
|
# serializer = serializer_class(parent) |
|
|
|
|
# updates[parent_model_name][parent.id] = serializer.data |
|
|
|
|
# self.add_parents_recursively(parent, updates) |
|
|
|
|
""" |
|
|
|
|
Recursively add all children of an instance to the updates dictionary. |
|
|
|
|
""" |
|
|
|
|
child_models = instance.get_children_by_model() |
|
|
|
|
|
|
|
|
|
for child_model_name, children in child_models.items(): |
|
|
|
|
for child in children: |
|
|
|
|
if isinstance(child, BaseModel): |
|
|
|
|
serializer = get_serializer(child, child_model_name) |
|
|
|
|
updates[child_model_name][child.id] = serializer.data |
|
|
|
|
self.add_children_recursively(child, updates) |
|
|
|
|
|
|
|
|
|
def add_parents_with_hierarchy_organizer(self, instance, hierarchy_organizer, current_level=0): |
|
|
|
|
""" |
|
|
|
|
Recursively add all parents of an instance to the hierarchy organizer. |
|
|
|
|
Parents are added at a higher level than their children. |
|
|
|
|
""" |
|
|
|
|
parent_models = instance.get_parents_by_model() |
|
|
|
|
|
|
|
|
|
for parent_model_name, parent in parent_models.items(): |
|
|
|
|
if isinstance(parent, BaseModel): |
|
|
|
|
store_id = None |
|
|
|
|
if isinstance(parent, SideStoreModel): |
|
|
|
|
store_id = parent.store_id |
|
|
|
|
|
|
|
|
|
parent_data = { |
|
|
|
|
'model_id': parent.id, |
|
|
|
|
'store_id': store_id |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
# Add parent at the next level |
|
|
|
|
hierarchy_organizer.add_item(parent_model_name, parent_data, current_level + 1) |
|
|
|
|
|
|
|
|
|
# Recursively process parent's parents |
|
|
|
|
self.add_parents_with_hierarchy_organizer(parent, hierarchy_organizer, current_level + 1) |
|
|
|
|
|
|
|
|
|
def add_parents_recursively(self, instance, dictionary, minimal=False): |
|
|
|
|
""" |
|
|
|
|
@ -69,9 +79,6 @@ class HierarchyApiView(APIView): |
|
|
|
|
} |
|
|
|
|
else: |
|
|
|
|
serializer = get_serializer(parent, parent_model_name) |
|
|
|
|
# Add full serialized data |
|
|
|
|
# serializer_class = build_serializer_class(parent_model_name) |
|
|
|
|
# serializer = serializer_class(parent) |
|
|
|
|
dictionary[parent_model_name][parent.id] = serializer.data |
|
|
|
|
|
|
|
|
|
self.add_parents_recursively(parent, dictionary, minimal) |
|
|
|
|
@ -155,7 +162,9 @@ class SynchronizationApi(HierarchyApiView): |
|
|
|
|
deletions = defaultdict(list) |
|
|
|
|
grants = defaultdict(dict) |
|
|
|
|
revocations = defaultdict(list) # New dictionary for revocations |
|
|
|
|
revocation_parents = defaultdict(dict) |
|
|
|
|
revocations_parents_organizer = HierarchyOrganizer() |
|
|
|
|
|
|
|
|
|
# revocated_parents = defaultdict(dict) |
|
|
|
|
|
|
|
|
|
last_log_date = None |
|
|
|
|
for log in logs: |
|
|
|
|
@ -170,15 +179,10 @@ class SynchronizationApi(HierarchyApiView): |
|
|
|
|
elif log.operation == 'GRANT_ACCESS': |
|
|
|
|
|
|
|
|
|
model = sync_registry.get_model(log.model_name) |
|
|
|
|
|
|
|
|
|
# model = apps.get_model('tournaments', model_name=log.model_name) |
|
|
|
|
instance = model.objects.get(id=log.model_id) |
|
|
|
|
# serializer_class = build_serializer_class(log.model_name) |
|
|
|
|
# serializer = serializer_class(instance) |
|
|
|
|
serializer = get_serializer(instance, log.model_name) |
|
|
|
|
|
|
|
|
|
grants[log.model_name][log.model_id] = serializer.data |
|
|
|
|
# instance = model.objects.get(id=log.model_id) |
|
|
|
|
self.add_children_recursively(instance, grants) |
|
|
|
|
self.add_parents_recursively(instance, grants) |
|
|
|
|
elif log.operation == 'REVOKE_ACCESS': |
|
|
|
|
@ -188,11 +192,11 @@ class SynchronizationApi(HierarchyApiView): |
|
|
|
|
'store_id': log.store_id |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
# Get the model instance and add its parents to revocation_parents |
|
|
|
|
# Get the model instance and add its parents to hierarchy |
|
|
|
|
model = sync_registry.get_model(log.model_name) |
|
|
|
|
try: |
|
|
|
|
instance = model.objects.get(id=log.model_id) |
|
|
|
|
self.add_parents_recursively(instance, revocation_parents, minimal=True) |
|
|
|
|
self.add_parents_with_hierarchy_organizer(instance, revocations_parents_organizer) |
|
|
|
|
except model.DoesNotExist: |
|
|
|
|
pass |
|
|
|
|
except ObjectDoesNotExist: |
|
|
|
|
@ -209,15 +213,15 @@ class SynchronizationApi(HierarchyApiView): |
|
|
|
|
for model_name in grants: |
|
|
|
|
grants[model_name] = list(grants[model_name].values()) |
|
|
|
|
|
|
|
|
|
for model_name in revocation_parents: |
|
|
|
|
revocation_parents[model_name] = list(revocation_parents[model_name].values()) |
|
|
|
|
# for model_name in revocation_parents: |
|
|
|
|
# revocation_parents[model_name] = list(revocation_parents[model_name].values()) |
|
|
|
|
|
|
|
|
|
response_data = { |
|
|
|
|
"updates": dict(updates), |
|
|
|
|
"deletions": dict(deletions), |
|
|
|
|
"grants": dict(grants), |
|
|
|
|
"revocations": dict(revocations), |
|
|
|
|
"revocation_parents": dict(revocation_parents), |
|
|
|
|
"revocation_parents": revocations_parents_organizer.get_organized_data(), |
|
|
|
|
"date": last_log_date |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|