Skip to content
11 changes: 7 additions & 4 deletions backend/src/zango/api/app_auth/profile/v1/views.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from django.contrib.auth import authenticate
from django.contrib.auth import authenticate, update_session_auth_hash
from django.core.exceptions import ValidationError

from zango.api.app_auth.profile.v1.utils import PasswordValidationMixin
Expand Down Expand Up @@ -31,12 +31,14 @@ def put(self, request, *args, **kwargs):


class PasswordChangeViewAPIV1(ZangoSessionAppAPIView, PasswordValidationMixin):
def clean_password(self, email, password):
def clean_password(self, request, password):
"""
Validates that the email is not already in use.
"""
try:
user = authenticate(username=email, password=password)
user = authenticate(
username=request.user.email, password=password, request=request
)
except Exception:
raise ValidationError(
"The current password you have entered is wrong. Please try again!"
Expand All @@ -57,7 +59,7 @@ def put(self, request, *args, **kwargs):
new_password = request.data.get("new_password")
success = False
try:
self.clean_password(request.user.email, current_password)
self.clean_password(request, current_password)
self.clean_password2(request.user, current_password, new_password)
request.user.set_password(new_password)
request.user.save()
Expand All @@ -67,6 +69,7 @@ def put(self, request, *args, **kwargs):
success = True
response = {}
status = 200
update_session_auth_hash(request, request.user)
return get_api_response(success, response, status)
except ValidationError as e:
response = {"message": e.message}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Module containing custom template filters
"""

import json
import os
import re

Expand Down Expand Up @@ -70,3 +71,12 @@ def use_latest(build_path):
if re.match(filep, filename):
return os.path.join(buildir, filename)
return build_path


@register.filter
def parse_json(value):
"""Parse JSON string and return dictionary"""
try:
return json.loads(value)
except (json.JSONDecodeError, TypeError):
return {}
74 changes: 74 additions & 0 deletions backend/src/zango/core/toast.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import json

from typing import Dict, Literal, Optional, TypedDict

from django.contrib import messages
from django.http import request


class ActionSchema(TypedDict, total=False):
text: str
url: Optional[str]


def ztoast(
request: request.HttpRequest,
message: str,
title: str = "",
level: Literal["success", "error", "warning", "info"] = "success",
primary_action: ActionSchema | None = None,
secondary_action: ActionSchema | None = None,
duration: int | None = None,
extra_tags: str = "",
):
"""
Displays a toast notification with the specified parameters.

Args:
request: The HTTP request object.
message: The message content of the toast notification.
title: The title of the toast notification. Defaults to an empty string,
which will result in the title being set to the capitalized `level`.
level: The severity level of the toast notification. Defaults to "success".
Accepted values are "success", "error", "warning", and "info".
primary_action: An optional primary action for the toast, defined by an
ActionSchema dictionary with 'text' and 'url' keys.
secondary_action: An optional secondary action for the toast, defined by an
ActionSchema dictionary with 'text' and 'url' keys.
duration: The duration the toast should be visible, in milliseconds. Defaults to None.
extra_tags: Additional tags to categorize the toast notification. Defaults to "".

Raises:
ValueError: If `level` is not one of the accepted values.

"""

if title == "":
title = level.capitalize()

msg_level = messages.SUCCESS

if level == "success":
msg_level = messages.SUCCESS
elif level == "error":
msg_level = messages.ERROR
elif level == "warning":
msg_level = messages.WARNING
elif level == "info":
msg_level = messages.INFO
else:
raise ValueError("Invalid level: %s" % level)

msg: Dict[str, str | ActionSchema | None | int] = {
"message": message,
"title": title,
"primary_action": primary_action,
"secondary_action": secondary_action,
}
if duration is not None:
msg["duration"] = duration
if extra_tags:
extra_tags = f"{extra_tags} zango"
else:
extra_tags = "zango"
messages.add_message(request, msg_level, json.dumps(msg), extra_tags=extra_tags)