# User propagation

* adds exception catching if gibberish data is sent to POST endpoint of user data propagation
* commits 'changed' manage.py and jspdf.debug.js despite being identical with repo files (git wants it, git gets it)
This commit is contained in:
2026-06-13 13:33:17 +02:00
parent 9ee016a8bb
commit 1f6c81874b
3 changed files with 265 additions and 221 deletions
Executable → Regular
View File
+59 -15
View File
@@ -7,9 +7,10 @@ Created on: 10.05.24
""" """
import base64 import base64
import hashlib import hashlib
import http
import json import json
from cryptography.fernet import Fernet from cryptography.fernet import Fernet, InvalidToken
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.http import HttpRequest, JsonResponse from django.http import HttpRequest, JsonResponse
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
@@ -27,34 +28,77 @@ class PropagateUserView(View):
proper rights management) proper rights management)
""" """
class PropagateStatus:
UNPROCESSED = "unprocessed"
UPDATED = "updated"
CREATED = "created"
@method_decorator(csrf_exempt) @method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
return super().dispatch(request, *args, **kwargs) return super().dispatch(request, *args, **kwargs)
def post(self, request: HttpRequest, *args, **kwargs): def post(self, request: HttpRequest, *args, **kwargs):
response_data = {
"success": None,
"status": None
}
# Decrypt # Decrypt
encrypted_body = request.body encrypted_body = request.body
_hash = hashlib.md5() _hash = hashlib.md5()
_hash.update(PROPAGATION_SECRET.encode("utf-8")) _hash.update(PROPAGATION_SECRET.encode("utf-8"))
key = base64.urlsafe_b64encode(_hash.hexdigest().encode("utf-8")) key = base64.urlsafe_b64encode(_hash.hexdigest().encode("utf-8"))
fernet = Fernet(key) fernet = Fernet(key)
body = fernet.decrypt(encrypted_body).decode("utf-8")
body = json.loads(body)
try: try:
status = "updated" body = fernet.decrypt(encrypted_body).decode("utf-8")
user = User.resolve_user_using_propagation_data(body) body = json.loads(body)
user = user.update_user_using_propagation_data(body) except InvalidToken:
except ObjectDoesNotExist: response_data["error"] = "Invalid Token"
user = User(**body) response_data["success"] = False
status = "created" response_data["status"] = self.PropagateStatus.UNPROCESSED
return JsonResponse(
status=http.HTTPStatus.UNPROCESSABLE_CONTENT,
data=response_data
)
except (json.JSONDecodeError) as e:
response_data["error"] = str(e)
response_data["success"] = False
response_data["status"] = self.PropagateStatus.UNPROCESSED
return JsonResponse(
status=http.HTTPStatus.UNPROCESSABLE_CONTENT,
data=response_data
)
# Process decrypted user data
processing_ret_vals = self.__process_user_data(body)
response_data["success"] = processing_ret_vals[0]
response_data["status"] = processing_ret_vals[1]
user = processing_ret_vals[2]
user.set_unusable_password() user.set_unusable_password()
user.save() user.save()
data = { return JsonResponse(
"success": True, status=http.HTTPStatus.OK,
"status": status data=response_data
} )
return JsonResponse(data) def __process_user_data(self, body: dict) -> (bool, str, User):
""" Process decrypted user data
Args:
body:
Returns:
success (bool): Whether the processing was successful
status (str): In which way the data was used ('created' | 'updated')
user (User): Processed user object
"""
try:
user = User.resolve_user_using_propagation_data(body)
user = user.update_user_using_propagation_data(body)
status = self.PropagateStatus.UPDATED
except ObjectDoesNotExist:
user = User(**body)
status = self.PropagateStatus.CREATED
return True, status, user