cleanup and minor improvements

sync_v2
Laurent 6 months ago
parent 52a0b5ec41
commit a2a4916c2f
  1. 2
      api/urls.py
  2. 3
      api/views.py
  3. 2
      authentication/views.py
  4. 4
      sync/models/base.py
  5. 8
      sync/models/model_log.py
  6. 20
      sync/signals.py
  7. 285
      sync/views.py
  8. 2
      sync/ws_sender.py
  9. 6
      tournaments/backends.py

@ -8,7 +8,7 @@ from authentication.views import CustomAuthToken, Logout, ChangePasswordView
router = routers.DefaultRouter() router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet) router.register(r'users', views.UserViewSet)
router.register(r'user-names', views.ShortUserViewSet) router.register(r'user-agents', views.ShortUserViewSet)
router.register(r'clubs', views.ClubViewSet) router.register(r'clubs', views.ClubViewSet)
router.register(r'tournaments', views.TournamentViewSet) router.register(r'tournaments', views.TournamentViewSet)
router.register(r'events', views.EventViewSet) router.register(r'events', views.EventViewSet)

@ -300,6 +300,9 @@ class ShortUserViewSet(viewsets.ModelViewSet):
serializer_class = ShortUserSerializer serializer_class = ShortUserSerializer
permission_classes = [] # Users are public whereas the other requests are only for logged users permission_classes = [] # Users are public whereas the other requests are only for logged users
def get_queryset(self):
return self.request.user.agents
@api_view(['POST']) @api_view(['POST'])
@permission_classes([IsAuthenticated]) @permission_classes([IsAuthenticated])
def process_refund(request, team_registration_id): def process_refund(request, team_registration_id):

@ -31,7 +31,7 @@ class CustomAuthToken(APIView):
password = request.data.get('password') password = request.data.get('password')
device_id = request.data.get('device_id') device_id = request.data.get('device_id')
logger.info(f'Login attempt from {username}') # logger.info(f'Login attempt from {username}')
user = authenticate(username=username, password=password) user = authenticate(username=username, password=password)
if user is None and is_valid_email(username) == True: if user is None and is_valid_email(username) == True:

@ -35,7 +35,7 @@ class BaseModel(models.Model):
for child in children: for child in children:
if (child.one_to_many or child.one_to_one) and child.auto_created: if (child.one_to_many or child.one_to_one) and child.auto_created:
model_name = child.related_model.__name__ model_name = child.related_model.__name__
# print(f'>>> add children for {model_name}') print(f'>>> add children for {model_name}')
related_objects[model_name] = getattr(self, child.name).all() related_objects[model_name] = getattr(self, child.name).all()
return related_objects return related_objects
@ -58,6 +58,7 @@ class BaseModel(models.Model):
# Get the parent instance using the related name # Get the parent instance using the related name
parent_instance = getattr(self, field.get_accessor_name()) parent_instance = getattr(self, field.get_accessor_name())
if parent_instance: if parent_instance:
print(f'>>> add parent for OneToOneRel : {model_name}')
parents[model_name] = parent_instance parents[model_name] = parent_instance
# Also check for direct foreign key relationships that might represent parent relationships # Also check for direct foreign key relationships that might represent parent relationships
@ -65,6 +66,7 @@ class BaseModel(models.Model):
model_name = field.related_model.__name__ model_name = field.related_model.__name__
parent_instance = getattr(self, field.name) parent_instance = getattr(self, field.name)
if parent_instance: if parent_instance:
print(f'>>> add parent for ForeignKey : {model_name}')
parents[model_name] = parent_instance parents[model_name] = parent_instance
return parents return parents

@ -7,8 +7,6 @@ class ModelOperation(models.TextChoices):
DELETE = 'DELETE', 'DELETE' DELETE = 'DELETE', 'DELETE'
GRANT_ACCESS = 'GRANT_ACCESS', 'GRANT_ACCESS' GRANT_ACCESS = 'GRANT_ACCESS', 'GRANT_ACCESS'
REVOKE_ACCESS = 'REVOKE_ACCESS', 'REVOKE_ACCESS' REVOKE_ACCESS = 'REVOKE_ACCESS', 'REVOKE_ACCESS'
RELATIONSHIP_SET = 'RELATIONSHIP_SET', 'RELATIONSHIP_SET'
RELATIONSHIP_REMOVED = 'RELATIONSHIP_REMOVED', 'RELATIONSHIP_REMOVED'
SHARED_RELATIONSHIP_SET = 'SHARED_RELATIONSHIP_SET', 'SHARED_RELATIONSHIP_SET' SHARED_RELATIONSHIP_SET = 'SHARED_RELATIONSHIP_SET', 'SHARED_RELATIONSHIP_SET'
SHARED_RELATIONSHIP_REMOVED = 'SHARED_RELATIONSHIP_REMOVED', 'SHARED_RELATIONSHIP_REMOVED' SHARED_RELATIONSHIP_REMOVED = 'SHARED_RELATIONSHIP_REMOVED', 'SHARED_RELATIONSHIP_REMOVED'
@ -43,5 +41,11 @@ class ModelLog(models.Model):
self.date = self.date.replace(microsecond=microseconds) self.date = self.date.replace(microsecond=microseconds)
super().save(*args, **kwargs) super().save(*args, **kwargs)
def data_identifier_dict(self):
return {
'model_id': self.model_id,
'store_id': self.store_id
}
def retrieved(self): def retrieved(self):
self.count += 1 self.count += 1

@ -224,11 +224,11 @@ def process_foreign_key_changes(sender, instance, **kwargs):
save_model_log(shared, 'SHARED_RELATIONSHIP_REMOVED', save_model_log(shared, 'SHARED_RELATIONSHIP_REMOVED',
model_name, change['old_value'].id, model_name, change['old_value'].id,
change['old_value'].get_store_id()) change['old_value'].get_store_id())
if owner: # if owner:
print(f"RELATIONSHIP_REMOVED: owner={owner}, model_name={model_name}") # print(f"RELATIONSHIP_REMOVED: owner={owner}, model_name={model_name}")
save_model_log(owner, 'RELATIONSHIP_REMOVED', # save_model_log(owner, 'RELATIONSHIP_REMOVED',
model_name, change['old_value'].id, # model_name, change['old_value'].id,
change['old_value'].get_store_id()) # change['old_value'].get_store_id())
if change['new_value']: if change['new_value']:
model_name = change['new_value'].__class__.__name__ model_name = change['new_value'].__class__.__name__
if shared: if shared:
@ -236,11 +236,11 @@ def process_foreign_key_changes(sender, instance, **kwargs):
save_model_log(shared, 'SHARED_RELATIONSHIP_SET', save_model_log(shared, 'SHARED_RELATIONSHIP_SET',
model_name, change['new_value'].id, model_name, change['new_value'].id,
change['new_value'].get_store_id()) change['new_value'].get_store_id())
if owner: # if owner:
print(f"RELATIONSHIP_SET: owner={owner}, model_name={model_name}") # print(f"RELATIONSHIP_SET: owner={owner}, model_name={model_name}")
save_model_log(owner, 'RELATIONSHIP_SET', # save_model_log(owner, 'RELATIONSHIP_SET',
model_name, change['old_value'].id, # model_name, change['old_value'].id,
change['old_value'].get_store_id()) # change['old_value'].get_store_id())
### Data Access ### Data Access

@ -33,6 +33,7 @@ def add_children_recursively(instance, updates):
for child_model_name, children in child_models.items(): for child_model_name, children in child_models.items():
for child in children: for child in children:
if isinstance(child, BaseModel): if isinstance(child, BaseModel):
print(f'add_children_recursively: {child_model_name}')
serializer = get_serializer(child, child_model_name) serializer = get_serializer(child, child_model_name)
updates[child_model_name][child.id] = serializer.data updates[child_model_name][child.id] = serializer.data
add_children_recursively(child, updates) add_children_recursively(child, updates)
@ -56,6 +57,7 @@ def add_parents_with_hierarchy_organizer(instance, hierarchy_organizer, current_
} }
# Add parent at the next level # Add parent at the next level
print(f'*** add parent: {parent_model_name}: {parent.id}')
hierarchy_organizer.add_item(parent_model_name, parent_data, current_level + 1) hierarchy_organizer.add_item(parent_model_name, parent_data, current_level + 1)
# Recursively process parent's parents # Recursively process parent's parents
@ -130,7 +132,7 @@ class SynchronizationApi(APIView):
result = serializer.data result = serializer.data
response_status = status.HTTP_201_CREATED response_status = status.HTTP_201_CREATED
else: else:
print(f'Data invalid ! {serializer.errors}') print(f'{model_name} POST: Data invalid ! {serializer.errors}')
message = json.dumps(serializer.errors) message = json.dumps(serializer.errors)
response_status = status.HTTP_400_BAD_REQUEST response_status = status.HTTP_400_BAD_REQUEST
elif model_operation == 'PUT': elif model_operation == 'PUT':
@ -145,7 +147,7 @@ class SynchronizationApi(APIView):
result = serializer.data result = serializer.data
response_status = status.HTTP_203_NON_AUTHORITATIVE_INFORMATION response_status = status.HTTP_203_NON_AUTHORITATIVE_INFORMATION
else: else:
print(f'Data invalid ! {serializer.errors}') print(f'{model_name} PUT: Data invalid ! {serializer.errors}')
response_status = status.HTTP_400_BAD_REQUEST response_status = status.HTTP_400_BAD_REQUEST
elif model_operation == 'DELETE': elif model_operation == 'DELETE':
try: try:
@ -181,102 +183,6 @@ class SynchronizationApi(APIView):
'results': results 'results': results
}, status=207) # Multi-Status }, status=207) # Multi-Status
# def get(self, request, *args, **kwargs):
# last_update_str = request.query_params.get('last_update')
# device_id = request.query_params.get('device_id')
# # print(f'last_update_str = {last_update_str}')
# decoded_last_update = unquote(last_update_str) # Decodes %2B into +
# # print(f'last_update_str = {last_update_str}')
# # print(f'decoded_last_update = {decoded_last_update}')
# if not decoded_last_update:
# return Response({"error": "last_update parameter is required"}, status=status.HTTP_400_BAD_REQUEST)
# try:
# last_update = timezone.datetime.fromisoformat(decoded_last_update)
# except ValueError:
# return Response({"error": f"Invalid date format for last_update: {decoded_last_update}"}, status=status.HTTP_400_BAD_REQUEST)
# # print(f'/data GET: {last_update}')
# logs = self.query_model_logs(last_update, request.user, device_id)
# print(f'>>> log count = {len(logs)}')
# updates = defaultdict(dict)
# deletions = defaultdict(list)
# grants = defaultdict(dict)
# revocations = defaultdict(list)
# revocations_parents_organizer = HierarchyOrganizer()
# # revocated_parents = defaultdict(dict)
# last_log_date = None
# for log in logs:
# # log.retrieved()
# # log.save()
# # print(f'log date = {log.date}')
# last_log_date = log.date
# try:
# if log.operation in ['POST', 'PUT']:
# data = get_serialized_data(log.model_name, log.model_id)
# updates[log.model_name][log.model_id] = data
# elif log.operation == 'DELETE':
# deletions[log.model_name].append({'model_id': log.model_id, 'store_id': log.store_id})
# elif log.operation == 'GRANT_ACCESS':
# model = model_registry.get_model(log.model_name)
# instance = model.objects.get(id=log.model_id)
# serializer = get_serializer(instance, log.model_name)
# grants[log.model_name][log.model_id] = serializer.data
# self.add_children_recursively(instance, grants)
# self.add_parents_recursively(instance, grants)
# elif log.operation == 'REVOKE_ACCESS':
# print(f'revoke access {log.model_id} - {log.store_id}')
# revocations[log.model_name].append({
# 'model_id': log.model_id,
# 'store_id': log.store_id
# })
# # Get the model instance and add its parents to hierarchy
# model = model_registry.get_model(log.model_name)
# try:
# instance = model.objects.get(id=log.model_id)
# self.add_parents_with_hierarchy_organizer(instance, revocations_parents_organizer)
# except model.DoesNotExist:
# pass
# except ObjectDoesNotExist:
# pass
# # Convert updates dict to list for each model
# for model_name in updates:
# updates[model_name] = list(updates[model_name].values())
# # Convert deletions set to list for each model
# for model_name in deletions:
# deletions[model_name] = deletions[model_name]
# 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())
# response_data = {
# "updates": dict(updates),
# "deletions": dict(deletions),
# "grants": dict(grants),
# "revocations": dict(revocations),
# "revocation_parents": revocations_parents_organizer.get_organized_data(),
# "date": last_log_date
# }
# # print(f'sync GET response. UP = {len(updates)} / DEL = {len(deletions)} / G = {len(grants)} / R = {len(revocations)}')
# # print(f'sync GET response. response = {response_data}')
# return Response(response_data, status=status.HTTP_200_OK)
## GET ## GET
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
@ -293,8 +199,10 @@ class SynchronizationApi(APIView):
return Response({"error": f"Invalid date format for last_update: {decoded_last_update}"}, return Response({"error": f"Invalid date format for last_update: {decoded_last_update}"},
status=status.HTTP_400_BAD_REQUEST) status=status.HTTP_400_BAD_REQUEST)
print(f'>>> GET last modifications since: {last_update_str} / converted = {last_update}')
logs = self.query_model_logs(last_update, request.user, device_id) logs = self.query_model_logs(last_update, request.user, device_id)
print(f'>>> log count = {len(logs)}') print(f'>>> user = {request.user.username} > log count = {logs.count()}, device_id = {device_id}')
# Process all logs and get response data # Process all logs and get response data
result = LogProcessingResult() result = LogProcessingResult()
@ -303,147 +211,12 @@ class SynchronizationApi(APIView):
return Response(response_data, status=status.HTTP_200_OK) return Response(response_data, status=status.HTTP_200_OK)
# def process_logs(self, logs):
# """Process logs to collect basic operations and handle grant/revoke efficiently."""
# # Create an instance of the LogProcessingResult class
# result = LogProcessingResult()
# last_log_date = None
# for log in logs:
# last_log_date = log.date
# try:
# if log.operation in ['POST', 'PUT']:
# data = get_serialized_data(log.model_name, log.model_id)
# result.updates[log.model_name][log.model_id] = data
# elif log.operation == 'DELETE':
# result.deletions[log.model_name].append({'model_id': log.model_id, 'store_id': log.store_id})
# elif log.operation == 'GRANT_ACCESS':
# # Remove any existing revocations for this model_id
# self._remove_revocation(result.revoke_info, log.model_name, log.model_id)
# # Add to grant instances if not already there
# if log.model_id not in result.grant_instances[log.model_name]:
# model = model_registry.get_model(log.model_name)
# try:
# instance = model.objects.get(id=log.model_id)
# result.grant_instances[log.model_name][log.model_id] = instance
# except model.DoesNotExist:
# pass
# elif log.operation == 'REVOKE_ACCESS':
# print(f'revoke access {log.model_id} - {log.store_id}')
# # Remove any existing grants for this model_id
# self._remove_grant(result.grant_instances, log.model_name, log.model_id)
# # Add to revocations
# result.revoke_info[log.model_name].append({
# 'model_id': log.model_id,
# 'store_id': log.store_id
# })
# elif log.operation == 'RELATIONSHIP_SET':
# data = get_serialized_data(log.model_name, log.model_id)
# result.relationship_sets[log.model_name][log.model_id] = data
# elif log.operation == 'RELATIONSHIP_REMOVED':
# result.relationship_removals[log.model_name].append({
# 'model_id': log.model_id,
# 'store_id': log.store_id
# })
# elif log.operation == 'SHARED_RELATIONSHIP_SET':
# data = get_serialized_data(log.model_name, log.model_id)
# result.shared_relationship_sets[log.model_name][log.model_id] = data
# elif log.operation == 'SHARED_RELATIONSHIP_REMOVED':
# result.shared_relationship_removals[log.model_name].append({
# 'model_id': log.model_id,
# 'store_id': log.store_id
# })
# except ObjectDoesNotExist:
# pass
# # Convert updates dict to list for each model
# for model_name in result.updates:
# result.updates[model_name] = list(result.updates[model_name].values())
# return result, last_log_date
# def _remove_revocation(self, revoke_info, model_name, model_id):
# """Remove any revocation entries for the specified model and ID."""
# if model_name in revoke_info:
# revoke_info[model_name] = [
# r for r in revoke_info[model_name]
# if r['model_id'] != model_id
# ]
# # Clean up empty lists
# if not revoke_info[model_name]:
# del revoke_info[model_name]
# def _remove_grant(self, grant_instances, model_name, model_id):
# """Remove any grant entries for the specified model and ID."""
# if model_name in grant_instances and model_id in grant_instances[model_name]:
# del grant_instances[model_name][model_id]
# # Clean up empty dictionaries
# if not grant_instances[model_name]:
# del grant_instances[model_name]
# def process_grants(self, grant_instances):
# """Process grants and their hierarchies."""
# grants = defaultdict(dict)
# # Process each grant instance
# for model_name, instances in grant_instances.items():
# for model_id, instance in instances.items():
# serializer = get_serializer(instance, model_name)
# grants[model_name][model_id] = serializer.data
# # Add hierarchies only once per instance
# self.add_children_recursively(instance, grants)
# self.add_parents_recursively(instance, grants)
# # Convert to lists
# for model_name in grants:
# grants[model_name] = list(grants[model_name].values())
# return grants
# def process_revocations(self, revoke_info):
# """Process revocations and their hierarchies."""
# revocations = defaultdict(list)
# revocations_parents_organizer = HierarchyOrganizer()
# # First, collect all revocations
# for model_name, items in revoke_info.items():
# revocations[model_name].extend(items)
# # Process parent hierarchies for each revoked item
# model = model_registry.get_model(model_name)
# for item in items:
# try:
# instance = model.objects.get(id=item['model_id'])
# self.add_parents_with_hierarchy_organizer(instance, revocations_parents_organizer)
# except model.DoesNotExist:
# pass
# return revocations, revocations_parents_organizer
def query_model_logs(self, last_update, user, device_id): def query_model_logs(self, last_update, user, device_id):
log_query = Q(date__gt=last_update, user=user) log_query = Q(date__gt=last_update, user=user)
if device_id: if device_id:
log_query &= ~Q(device_id=device_id) # exclude query log_query &= ~Q(device_id=device_id) # exclude query
return ModelLog.objects.filter(log_query).order_by('date') return ModelLog.objects.filter(log_query).order_by('date')
# class LogProcessingResult:
# """Class to hold all the results from log processing."""
# def __init__(self):
# # Initialize all the collections
# self.updates = defaultdict(dict)
# self.deletions = defaultdict(list)
# self.grant_instances = defaultdict(dict) # {model_name: {model_id: instance}}
# self.revoke_info = defaultdict(list) # {model_name: [{model_id, store_id}]}
# self.relationship_sets = defaultdict(dict)
# self.relationship_removals = defaultdict(list)
# self.shared_relationship_sets = defaultdict(dict)
# self.shared_relationship_removals = defaultdict(list)
class LogProcessingResult: class LogProcessingResult:
"""Class to handle all log processing and organize the results.""" """Class to handle all log processing and organize the results."""
@ -453,8 +226,6 @@ class LogProcessingResult:
self.deletions = defaultdict(list) self.deletions = defaultdict(list)
self.grant_instances = defaultdict(dict) # {model_name: {model_id: instance}} self.grant_instances = defaultdict(dict) # {model_name: {model_id: instance}}
self.revoke_info = defaultdict(list) # {model_name: [{model_id, store_id}]} self.revoke_info = defaultdict(list) # {model_name: [{model_id, store_id}]}
self.relationship_sets = defaultdict(dict)
self.relationship_removals = defaultdict(list)
self.shared_relationship_sets = defaultdict(dict) self.shared_relationship_sets = defaultdict(dict)
self.shared_relationship_removals = defaultdict(list) self.shared_relationship_removals = defaultdict(list)
self.last_log_date = None self.last_log_date = None
@ -468,7 +239,7 @@ class LogProcessingResult:
data = get_serialized_data(log.model_name, log.model_id) data = get_serialized_data(log.model_name, log.model_id)
self.updates[log.model_name][log.model_id] = data self.updates[log.model_name][log.model_id] = data
elif log.operation == 'DELETE': elif log.operation == 'DELETE':
self.deletions[log.model_name].append({'model_id': log.model_id, 'store_id': log.store_id}) self.deletions[log.model_name].append(log.data_identifier_dict())
elif log.operation == 'GRANT_ACCESS': elif log.operation == 'GRANT_ACCESS':
# Remove any existing revocations for this model_id # Remove any existing revocations for this model_id
self._remove_revocation(log.model_name, log.model_id) self._remove_revocation(log.model_name, log.model_id)
@ -488,32 +259,25 @@ class LogProcessingResult:
self._remove_grant(log.model_name, log.model_id) self._remove_grant(log.model_name, log.model_id)
# Add to revocations # Add to revocations
self.revoke_info[log.model_name].append({ self.revoke_info[log.model_name].append(log.data_identifier_dict())
'model_id': log.model_id, # elif log.operation == 'RELATIONSHIP_SET':
'store_id': log.store_id # data = get_serialized_data(log.model_name, log.model_id)
}) # self.relationship_sets[log.model_name][log.model_id] = data
elif log.operation == 'RELATIONSHIP_SET': # elif log.operation == 'RELATIONSHIP_REMOVED':
data = get_serialized_data(log.model_name, log.model_id) # self.relationship_removals[log.model_name].append(log.data_identifier_dict())
self.relationship_sets[log.model_name][log.model_id] = data
elif log.operation == 'RELATIONSHIP_REMOVED':
self.relationship_removals[log.model_name].append({
'model_id': log.model_id,
'store_id': log.store_id
})
elif log.operation == 'SHARED_RELATIONSHIP_SET': elif log.operation == 'SHARED_RELATIONSHIP_SET':
data = get_serialized_data(log.model_name, log.model_id) data = get_serialized_data(log.model_name, log.model_id)
self.shared_relationship_sets[log.model_name][log.model_id] = data self.shared_relationship_sets[log.model_name][log.model_id] = data
elif log.operation == 'SHARED_RELATIONSHIP_REMOVED': elif log.operation == 'SHARED_RELATIONSHIP_REMOVED':
self.shared_relationship_removals[log.model_name].append({ self.shared_relationship_removals[log.model_name].append(log.data_identifier_dict())
'model_id': log.model_id,
'store_id': log.store_id
})
except ObjectDoesNotExist: except ObjectDoesNotExist:
pass pass
# Convert updates dict to list for each model # Convert updates dict to list for each model
for model_name in self.updates: for model_name in self.updates:
self.updates[model_name] = list(self.updates[model_name].values()) self.updates[model_name] = list(self.updates[model_name].values())
for model_name in self.shared_relationship_sets:
self.shared_relationship_sets[model_name] = list(self.shared_relationship_sets[model_name].values())
# return self # return self
@ -561,15 +325,20 @@ class LogProcessingResult:
revocations = defaultdict(list) revocations = defaultdict(list)
revocations_parents_organizer = HierarchyOrganizer() revocations_parents_organizer = HierarchyOrganizer()
print(f'*** process_revocations: {len(self.revoke_info)}')
# First, collect all revocations # First, collect all revocations
for model_name, items in self.revoke_info.items(): for model_name, items in self.revoke_info.items():
revocations[model_name].extend(items) revocations[model_name].extend(items)
print(f'*** process_revocations for {model_name}')
# Process parent hierarchies for each revoked item # Process parent hierarchies for each revoked item
model = model_registry.get_model(model_name) model = model_registry.get_model(model_name)
for item in items: for item in items:
try: try:
instance = model.objects.get(id=item['model_id']) instance = model.objects.get(id=item['model_id'])
print(f'*** process revoked item parents of {model_name} : {item['model_id']}')
add_parents_with_hierarchy_organizer(instance, revocations_parents_organizer) add_parents_with_hierarchy_organizer(instance, revocations_parents_organizer)
except model.DoesNotExist: except model.DoesNotExist:
pass pass
@ -581,16 +350,18 @@ class LogProcessingResult:
grants = self.process_grants() grants = self.process_grants()
revocations, revocations_parents_organizer = self.process_revocations() revocations, revocations_parents_organizer = self.process_revocations()
# print(f'self.deletions = {dict(self.deletions)}')
# print(f'self.shared_relationship_sets = {self.shared_relationship_sets}')
# print(f'self.shared_relationship_removals = {self.shared_relationship_removals}')
return { return {
"updates": dict(self.updates), "updates": dict(self.updates),
"deletions": dict(self.deletions), "deletions": dict(self.deletions),
"grants": dict(grants), "grants": dict(grants),
"revocations": dict(revocations), "revocations": dict(revocations),
"revocation_parents": revocations_parents_organizer.get_organized_data(), "revocation_parents": revocations_parents_organizer.get_organized_data(),
"relationship_sets": dict(self.relationship_sets), "shared_relationship_sets": self.shared_relationship_sets,
"relationship_removals": dict(self.relationship_removals), "shared_relationship_removals": self.shared_relationship_removals,
"shared_relationship_sets": dict(self.shared_relationship_sets),
"shared_relationship_removals": dict(self.shared_relationship_removals),
"date": self.last_log_date "date": self.last_log_date
} }

@ -34,7 +34,7 @@ class WebSocketSender:
channel_layer = get_channel_layer() channel_layer = get_channel_layer()
group_name = f"sync_{user_id}" group_name = f"sync_{user_id}"
print(f">>> send to group {group_name}, device_id={device_id}") # print(f">>> send to group {group_name}, device_id={device_id}")
# print(f'channel_layer = {channel_layer}') # print(f'channel_layer = {channel_layer}')
device_id = device_id if device_id else "std_msg_lol" # a not empty message is required! device_id = device_id if device_id else "std_msg_lol" # a not empty message is required!

@ -10,18 +10,18 @@ class EmailOrUsernameModelBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs): def authenticate(self, request, username=None, password=None, **kwargs):
UserModel = get_user_model() UserModel = get_user_model()
print(f"Backend attempting authentication for: {username}") # Debug print # print(f"Backend attempting authentication for: {username}") # Debug print
logger.info(f"Backend attempting authentication for: {username}") logger.info(f"Backend attempting authentication for: {username}")
try: try:
user = UserModel.objects.get( user = UserModel.objects.get(
Q(username__iexact=username) | Q(email__iexact=username) Q(username__iexact=username) | Q(email__iexact=username)
) )
print(f"User found: {user}") # Debug print # print(f"User found: {user}") # Debug print
logger.info(f"User found: {user}") logger.info(f"User found: {user}")
if user.check_password(password): if user.check_password(password):
print("Password check successful") # Debug print # print("Password check successful") # Debug print
logger.info("Password check successful") logger.info("Password check successful")
return user return user
print("Password check failed") # Debug print print("Password check failed") # Debug print

Loading…
Cancel
Save