Merge branch 'main' into storefront-nuxt
This commit is contained in:
commit
ae1f291a51
4 changed files with 78 additions and 73 deletions
|
|
@ -1,11 +1,13 @@
|
||||||
import logging
|
import logging
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
from django.contrib.auth.models import Permission
|
from django.contrib.auth.models import Permission
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
from django.db.models import Q
|
||||||
|
|
||||||
from engine.core.models import Vendor
|
from engine.core.models import Vendor
|
||||||
from engine.vibes_auth.models import Group
|
from engine.vibes_auth.models import Group, User
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
@ -155,4 +157,7 @@ class Command(BaseCommand):
|
||||||
perms = Permission.objects.filter(codename__in=e_commerce_admin_permissions)
|
perms = Permission.objects.filter(codename__in=e_commerce_admin_permissions)
|
||||||
e_commerce_admin.permissions.add(*perms)
|
e_commerce_admin.permissions.add(*perms)
|
||||||
|
|
||||||
|
valid_codes = [code for code, _ in settings.LANGUAGES]
|
||||||
|
(User.objects.filter(Q(language="") | ~Q(language__in=valid_codes)).update(language=settings.LANGUAGE_CODE))
|
||||||
|
|
||||||
self.stdout.write(self.style.SUCCESS("Successfully initialized must-have instances!"))
|
self.stdout.write(self.style.SUCCESS("Successfully initialized must-have instances!"))
|
||||||
|
|
|
||||||
|
|
@ -16,5 +16,7 @@ BAD_KEYS_TO_LISTEN = [
|
||||||
"is_staff",
|
"is_staff",
|
||||||
"is_superuser",
|
"is_superuser",
|
||||||
"is_active",
|
"is_active",
|
||||||
"active",
|
"is_verified",
|
||||||
|
"groups",
|
||||||
|
"user_permissions",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ from graphene_file_upload.scalars import Upload
|
||||||
|
|
||||||
from engine.core.graphene import BaseMutation
|
from engine.core.graphene import BaseMutation
|
||||||
from engine.core.utils.messages import permission_denied_message
|
from engine.core.utils.messages import permission_denied_message
|
||||||
|
from engine.core.utils.security import is_safe_key
|
||||||
from engine.vibes_auth.graphene.object_types import UserType
|
from engine.vibes_auth.graphene.object_types import UserType
|
||||||
from engine.vibes_auth.models import User
|
from engine.vibes_auth.models import User
|
||||||
from engine.vibes_auth.serializers import (
|
from engine.vibes_auth.serializers import (
|
||||||
|
|
@ -107,65 +108,62 @@ class UpdateUser(BaseMutation):
|
||||||
try:
|
try:
|
||||||
user = User.objects.get(uuid=uuid)
|
user = User.objects.get(uuid=uuid)
|
||||||
|
|
||||||
|
if not (info.context.user.has_perm("vibes_auth.change_user") or info.context.user == user):
|
||||||
|
raise PermissionDenied(permission_denied_message)
|
||||||
|
|
||||||
|
email = kwargs.get("email")
|
||||||
|
|
||||||
|
if (email is not None and not is_valid_email(email)) or User.objects.filter(email=email).exclude(
|
||||||
|
uuid=uuid
|
||||||
|
).exists():
|
||||||
|
raise BadRequest(_("malformed email"))
|
||||||
|
|
||||||
|
phone_number = kwargs.get("phone_number")
|
||||||
|
|
||||||
|
if (phone_number is not None and not is_valid_phone_number(phone_number)) or (
|
||||||
|
User.objects.filter(phone_number=phone_number).exclude(uuid=uuid).exists() and phone_number is not None
|
||||||
|
):
|
||||||
|
raise BadRequest(_(f"malformed phone number: {phone_number}"))
|
||||||
|
|
||||||
|
password = kwargs.get("password", "")
|
||||||
|
confirm_password = kwargs.get("confirm_password", "")
|
||||||
|
|
||||||
|
if password:
|
||||||
|
validate_password(password=password, user=user)
|
||||||
|
|
||||||
|
if not compare_digest(password, "") and compare_digest(password, confirm_password):
|
||||||
|
user.set_password(password)
|
||||||
|
user.save()
|
||||||
|
|
||||||
|
attribute_pairs = kwargs.pop("attributes", "")
|
||||||
|
|
||||||
|
if attribute_pairs:
|
||||||
|
for attribute_pair in attribute_pairs.split(";"):
|
||||||
|
if "-" in attribute_pair:
|
||||||
|
attr, value = attribute_pair.split("-", 1)
|
||||||
|
if not user.attributes:
|
||||||
|
user.attributes = {}
|
||||||
|
user.attributes.update({attr: value})
|
||||||
|
else:
|
||||||
|
raise BadRequest(_(f"Invalid attribute format: {attribute_pair}"))
|
||||||
|
|
||||||
|
for attr, value in kwargs.items():
|
||||||
|
if attr == "password" or attr == "confirm_password":
|
||||||
|
continue
|
||||||
|
if is_safe_key(attr) or info.context.user.has_perm("vibes_auth.change_user"):
|
||||||
|
setattr(user, attr, value)
|
||||||
|
|
||||||
|
user.save()
|
||||||
|
|
||||||
|
return UpdateUser(user=user)
|
||||||
|
|
||||||
except User.DoesNotExist as dne:
|
except User.DoesNotExist as dne:
|
||||||
name = "User"
|
name = "User"
|
||||||
raise Http404(_(f"{name} does not exist: {uuid}")) from dne
|
raise Http404(_(f"{name} does not exist: {uuid}")) from dne
|
||||||
|
except Exception as e:
|
||||||
if not (info.context.user.has_perm("vibes_auth.change_user") or info.context.user == user):
|
logger.warning("Could not update user: %s", str(e))
|
||||||
raise PermissionDenied(permission_denied_message)
|
logger.debug(traceback.format_exc())
|
||||||
|
raise BadRequest(str(e)) from e
|
||||||
email = kwargs.get("email")
|
|
||||||
|
|
||||||
if (email is not None and not is_valid_email(email)) or User.objects.filter(email=email).exclude(
|
|
||||||
uuid=uuid
|
|
||||||
).exists():
|
|
||||||
raise BadRequest(_("malformed email"))
|
|
||||||
|
|
||||||
phone_number = kwargs.get("phone_number")
|
|
||||||
|
|
||||||
if (phone_number is not None and not is_valid_phone_number(phone_number)) or (
|
|
||||||
User.objects.filter(phone_number=phone_number).exclude(uuid=uuid).exists() and phone_number is not None
|
|
||||||
):
|
|
||||||
raise BadRequest(_(f"malformed phone number: {phone_number}"))
|
|
||||||
|
|
||||||
password = kwargs.get("password", "")
|
|
||||||
confirm_password = kwargs.get("confirm_password", "")
|
|
||||||
|
|
||||||
if password:
|
|
||||||
validate_password(password=password, user=user)
|
|
||||||
|
|
||||||
if not compare_digest(password, "") and compare_digest(password, confirm_password):
|
|
||||||
user.set_password(password)
|
|
||||||
user.save()
|
|
||||||
|
|
||||||
attribute_pairs = kwargs.pop("attributes", "")
|
|
||||||
|
|
||||||
if attribute_pairs:
|
|
||||||
for attribute_pair in attribute_pairs.split(";"):
|
|
||||||
if "-" in attribute_pair:
|
|
||||||
attr, value = attribute_pair.split("-", 1)
|
|
||||||
if not user.attributes:
|
|
||||||
user.attributes = {}
|
|
||||||
user.attributes.update({attr: value})
|
|
||||||
else:
|
|
||||||
raise BadRequest(_(f"Invalid attribute format: {attribute_pair}"))
|
|
||||||
|
|
||||||
for attr, value in kwargs.items():
|
|
||||||
if attr == "password" or attr == "confirm_password":
|
|
||||||
continue
|
|
||||||
if attr not in [
|
|
||||||
"groups",
|
|
||||||
"user_permissions",
|
|
||||||
"is_verified",
|
|
||||||
"is_staff",
|
|
||||||
"is_active",
|
|
||||||
"is_superuser",
|
|
||||||
] or info.context.user.has_perm("vibes_auth.change_user"):
|
|
||||||
setattr(user, attr, value)
|
|
||||||
|
|
||||||
user.save()
|
|
||||||
|
|
||||||
return UpdateUser(user=user)
|
|
||||||
|
|
||||||
|
|
||||||
class DeleteUser(BaseMutation):
|
class DeleteUser(BaseMutation):
|
||||||
|
|
|
||||||
30
uv.lock
30
uv.lock
|
|
@ -215,11 +215,11 @@ wheels = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "asgiref"
|
name = "asgiref"
|
||||||
version = "3.10.0"
|
version = "3.11.0"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/46/08/4dfec9b90758a59acc6be32ac82e98d1fbfc321cb5cfa410436dbacf821c/asgiref-3.10.0.tar.gz", hash = "sha256:d89f2d8cd8b56dada7d52fa7dc8075baa08fb836560710d38c292a7a3f78c04e", size = 37483, upload-time = "2025-10-05T09:15:06.557Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/76/b9/4db2509eabd14b4a8c71d1b24c8d5734c52b8560a7b1e1a8b56c8d25568b/asgiref-3.11.0.tar.gz", hash = "sha256:13acff32519542a1736223fb79a715acdebe24286d98e8b164a73085f40da2c4", size = 37969, upload-time = "2025-11-19T15:32:20.106Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/17/9c/fc2331f538fbf7eedba64b2052e99ccf9ba9d6888e2f41441ee28847004b/asgiref-3.10.0-py3-none-any.whl", hash = "sha256:aef8a81283a34d0ab31630c9b7dfe70c812c95eba78171367ca8745e88124734", size = 24050, upload-time = "2025-10-05T09:15:05.11Z" },
|
{ url = "https://files.pythonhosted.org/packages/91/be/317c2c55b8bbec407257d45f5c8d1b6867abc76d12043f2d3d58c538a4ea/asgiref-3.11.0-py3-none-any.whl", hash = "sha256:1db9021efadb0d9512ce8ffaf72fcef601c7b73a8807a1bb2ef143dc6b14846d", size = 24096, upload-time = "2025-11-19T15:32:19.004Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1076,14 +1076,14 @@ wheels = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "django-unfold"
|
name = "django-unfold"
|
||||||
version = "0.71.0"
|
version = "0.72.0"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "django" },
|
{ name = "django" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/ec/5b/406eae1a429b15ba04f4dfaaf53aa64fb03bcfdc6bdd0753a41027aa3daa/django_unfold-0.71.0.tar.gz", hash = "sha256:995a296f1c15f172b0d8458ff12beb420ea7e9a666fa865a60ec03f70aaf4066", size = 1101347, upload-time = "2025-11-11T16:24:03.289Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/55/e6/045b68207d8b4b395623d39d803e6566ea2c110e56665e3ff6bda07de6aa/django_unfold-0.72.0.tar.gz", hash = "sha256:43a0e8a4383037a24b73666c9f721faef12bd500c4628b4fc39d0dafd2e9c0a2", size = 1102339, upload-time = "2025-11-24T09:03:47.347Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/16/94/ad8ba84410655e0207ffcc7c6cba0875e9f79f914e3f2e2de883f706f7c9/django_unfold-0.71.0-py3-none-any.whl", hash = "sha256:76d4019aa9052ebe2e040d868be895d8581018fdf7debca943084aa0e79c2e31", size = 1213722, upload-time = "2025-11-11T16:24:01.985Z" },
|
{ url = "https://files.pythonhosted.org/packages/2d/dd/6cdb80d5d377f2bdf3b39b639025bb8655b96fac08aa3673ae1e4b3e3384/django_unfold-0.72.0-py3-none-any.whl", hash = "sha256:61448ad42ff7a33c7ad66d14071b24224bb476038a14a1bbe719a774db496e34", size = 1215396, upload-time = "2025-11-24T09:03:45.568Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2161,7 +2161,7 @@ wheels = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jupyterlab"
|
name = "jupyterlab"
|
||||||
version = "4.4.10"
|
version = "4.5.0"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "async-lru" },
|
{ name = "async-lru" },
|
||||||
|
|
@ -2178,9 +2178,9 @@ dependencies = [
|
||||||
{ name = "tornado" },
|
{ name = "tornado" },
|
||||||
{ name = "traitlets" },
|
{ name = "traitlets" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/6a/5d/75c42a48ff5fc826a7dff3fe4004cda47c54f9d981c351efacfbc9139d3c/jupyterlab-4.4.10.tar.gz", hash = "sha256:521c017508af4e1d6d9d8a9d90f47a11c61197ad63b2178342489de42540a615", size = 22969303, upload-time = "2025-10-22T14:50:58.768Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/df/e5/4fa382a796a6d8e2cd867816b64f1ff27f906e43a7a83ad9eb389e448cd8/jupyterlab-4.5.0.tar.gz", hash = "sha256:aec33d6d8f1225b495ee2cf20f0514f45e6df8e360bdd7ac9bace0b7ac5177ea", size = 23989880, upload-time = "2025-11-18T13:19:00.365Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/f7/46/1eaa5db8d54a594bdade67afbcae42e9a2da676628be3eb39f36dcff6390/jupyterlab-4.4.10-py3-none-any.whl", hash = "sha256:65939ab4c8dcd0c42185c2d0d1a9d60b254dc8c46fc4fdb286b63c51e9358e07", size = 12293385, upload-time = "2025-10-22T14:50:54.075Z" },
|
{ url = "https://files.pythonhosted.org/packages/6c/1e/5a4d5498eba382fee667ed797cf64ae5d1b13b04356df62f067f48bb0f61/jupyterlab-4.5.0-py3-none-any.whl", hash = "sha256:88e157c75c1afff64c7dc4b801ec471450b922a4eae4305211ddd40da8201c8a", size = 12380641, upload-time = "2025-11-18T13:18:56.252Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2573,7 +2573,7 @@ wheels = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "notebook"
|
name = "notebook"
|
||||||
version = "7.4.7"
|
version = "7.5.0"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "jupyter-server" },
|
{ name = "jupyter-server" },
|
||||||
|
|
@ -2582,9 +2582,9 @@ dependencies = [
|
||||||
{ name = "notebook-shim" },
|
{ name = "notebook-shim" },
|
||||||
{ name = "tornado" },
|
{ name = "tornado" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/04/09/f6f64ba156842ef68d3ea763fa171a2f7e7224f200a15dd4af5b83c34756/notebook-7.4.7.tar.gz", hash = "sha256:3f0a04027dfcee8a876de48fba13ab77ec8c12f72f848a222ed7f5081b9e342a", size = 13937702, upload-time = "2025-09-27T08:00:22.536Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/89/ac/a97041621250a4fc5af379fb377942841eea2ca146aab166b8fcdfba96c2/notebook-7.5.0.tar.gz", hash = "sha256:3b27eaf9913033c28dde92d02139414c608992e1df4b969c843219acf2ff95e4", size = 14052074, upload-time = "2025-11-19T08:36:20.093Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/6c/d7/06d13087e20388926e7423d2489e728d2e59f2453039cdb0574a7c070e76/notebook-7.4.7-py3-none-any.whl", hash = "sha256:362b7c95527f7dd3c4c84d410b782872fd9c734fb2524c11dd92758527b6eda6", size = 14342894, upload-time = "2025-09-27T08:00:18.496Z" },
|
{ url = "https://files.pythonhosted.org/packages/73/96/00df2a4760f10f5af0f45c4955573cae6189931f9a30265a35865f8c1031/notebook-7.5.0-py3-none-any.whl", hash = "sha256:3300262d52905ca271bd50b22617681d95f08a8360d099e097726e6d2efb5811", size = 14460968, upload-time = "2025-11-19T08:36:15.869Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -3800,14 +3800,14 @@ wheels = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tinycss2"
|
name = "tinycss2"
|
||||||
version = "1.4.0"
|
version = "1.5.1"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "webencodings" },
|
{ name = "webencodings" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/7a/fd/7a5ee21fd08ff70d3d33a5781c255cbe779659bd03278feb98b19ee550f4/tinycss2-1.4.0.tar.gz", hash = "sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7", size = 87085, upload-time = "2024-10-24T14:58:29.895Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/a3/ae/2ca4913e5c0f09781d75482874c3a95db9105462a92ddd303c7d285d3df2/tinycss2-1.5.1.tar.gz", hash = "sha256:d339d2b616ba90ccce58da8495a78f46e55d4d25f9fd71dfd526f07e7d53f957", size = 88195, upload-time = "2025-11-23T10:29:10.082Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl", hash = "sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289", size = 26610, upload-time = "2024-10-24T14:58:28.029Z" },
|
{ url = "https://files.pythonhosted.org/packages/60/45/c7b5c3168458db837e8ceab06dc77824e18202679d0463f0e8f002143a97/tinycss2-1.5.1-py3-none-any.whl", hash = "sha256:3415ba0f5839c062696996998176c4a3751d18b7edaaeeb658c9ce21ec150661", size = 28404, upload-time = "2025-11-23T10:29:08.676Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue