added data encrption for customer

main
mtyton 2023-07-22 20:39:12 +02:00
rodzic 24f98cc3de
commit 3580a3b1e1
8 zmienionych plików z 152 dodań i 40 usunięć

Wyświetl plik

@ -42,6 +42,11 @@ class PaymentMethodAdmin(ModelAdmin):
list_display = ("name", "active")
class DeliveryMethodAdmin(ModelAdmin):
model = models.DeliveryMethod
list_display = ("name", "active")
class DocumentTemplateAdmin(ModelAdmin):
model = models.DocumentTemplate
list_display = ("name", )
@ -58,7 +63,8 @@ class StoreAdminGroup(ModelAdminGroup):
ProductTemplateAdmin,
ProductAdmin,
DocumentTemplateAdmin,
PaymentMethodAdmin
PaymentMethodAdmin,
DeliveryMethodAdmin
)

Wyświetl plik

@ -9,6 +9,7 @@ from typing import (
from dataclasses import dataclass
from django.http.request import HttpRequest
from django.conf import settings
from django.core import signing
from store.models import (
Product,
@ -116,3 +117,25 @@ class SessionCart(BaseCart):
def clear(self) -> None:
self._cart = {}
self.save_cart()
class CustomerData:
def _encrypt_data(self, data: dict[str, Any]) -> str:
signer = signing.Signer()
return signer.sign_object(data)
def _decrypt_data(self, data: str) -> dict[str, Any]:
signer = signing.Signer()
return signer.unsign_object(data)
def __init__(self, data: dict[str, Any]=None, encrypted_data: str=None) -> None:
self._data = self._encrypt_data(data) if data else encrypted_data
@property
def data(self) -> dict[str, Any]:
return self._data
@property
def decrypted_data(self) -> dict[str, Any]:
return self._decrypt_data(self._data)

Wyświetl plik

@ -1,10 +1,14 @@
from django import forms
from phonenumber_field.formfields import PhoneNumberField
from phonenumber_field.phonenumber import PhoneNumber
from django.db.models import Model
from store.models import (
ProductTemplate,
ProductCategoryParamValue,
Product
Product,
PaymentMethod,
DeliveryMethod
)
@ -38,6 +42,27 @@ class CustomerDataForm(forms.Form):
choices=(("PL", "Polska"), ), label="Kraj",
widget=forms.Select(attrs={"class": "form-control"})
)
payment_method = forms.ModelChoiceField(
queryset=PaymentMethod.objects.filter(active=True), label="Sposób płatności",
widget=forms.Select(attrs={"class": "form-control"})
)
delivery_method = forms.ModelChoiceField(
queryset=DeliveryMethod.objects.filter(active=True), label="Sposób dostawy",
widget=forms.Select(attrs={"class": "form-control"})
)
def clean(self):
"""Clean method should return JSON serializable"""
cleaned_data = super().clean()
new_cleaned_data = {}
for key, value in cleaned_data.items():
if isinstance(value, PhoneNumber):
new_cleaned_data[key] = str(value)
elif isinstance(value, Model):
new_cleaned_data[key] = value.pk
else:
new_cleaned_data[key] = value
return new_cleaned_data
class ButtonToggleSelect(forms.RadioSelect):

Wyświetl plik

@ -0,0 +1,39 @@
# Generated by Django 4.1.9 on 2023-07-22 17:18
from django.db import migrations, models
import django.db.models.deletion
import uuid
class Migration(migrations.Migration):
dependencies = [
("store", "0011_productparam_delete_templateparamvalue_and_more"),
]
operations = [
migrations.CreateModel(
name="DeliveryMethod",
fields=[
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("name", models.CharField(max_length=255)),
("description", models.TextField(blank=True)),
("price", models.FloatField(default=0)),
("active", models.BooleanField(default=True)),
],
),
migrations.AddField(
model_name="order",
name="uuid",
field=models.UUIDField(default=uuid.uuid4, editable=False),
),
migrations.AddField(
model_name="product",
name="uuid",
field=models.UUIDField(default=uuid.uuid4, editable=False),
),
migrations.AddField(
model_name="order",
name="delivery_method",
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to="store.deliverymethod"),
),
]

Wyświetl plik

@ -1,23 +0,0 @@
# Generated by Django 4.1.9 on 2023-07-20 16:50
from django.db import migrations, models
import uuid
class Migration(migrations.Migration):
dependencies = [
("store", "0011_productparam_delete_templateparamvalue_and_more"),
]
operations = [
migrations.AddField(
model_name="order",
name="uuid",
field=models.UUIDField(default=uuid.uuid4, editable=False),
),
migrations.AddField(
model_name="product",
name="uuid",
field=models.UUIDField(default=uuid.uuid4, editable=False),
),
]

Wyświetl plik

@ -432,9 +432,22 @@ class PaymentMethod(models.Model):
description = models.TextField(blank=True)
active = models.BooleanField(default=True)
def __str__(self) -> str:
return self.name
class DeliveryMethod(models.Model):
name = models.CharField(max_length=255)
description = models.TextField(blank=True)
price = models.FloatField(default=0)
active = models.BooleanField(default=True)
def __str__(self) -> str:
return self.name
class Order(models.Model):
payment_method = models.ForeignKey(PaymentMethod, on_delete=models.CASCADE)
delivery_method = models.ForeignKey(DeliveryMethod, on_delete=models.CASCADE, null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
sent = models.BooleanField(default=False)
@ -449,10 +462,12 @@ class Order(models.Model):
@property
def total_price(self) -> Decimal:
return sum(
price = sum(
[order_product.product.price * order_product.quantity
for order_product in self.products.all()]
)
delivery_price = self.delivery_method.price if self.delivery_method else 5.0
return price + delivery_price
@property
def total_price_words(self) -> str:

Wyświetl plik

@ -8,9 +8,9 @@
<div class="container pt-4">
<div class="row">
<div class="col-12 px-4">
<h1>Twoje dane</h1>
<hr class="mt-1" />
<h2>Twoje dane</h2>
</div>
<hr class="mt-2" />
</div>
<div class="col-12">
<div class="row mx-4">
@ -42,12 +42,13 @@
</div>
</div>
</div>
<div class="row mt-3 mx-4">
<div class="col-12">
<label class="order-form-label">Dane Kontaktowe</label>
<div class="row mt-3">
<div class="col-12 px-4">
<h2>Dane do wysyłki</h2>
</div>
<hr class="mt-1" />
<hr class="mt-2" />
</div>
<div class="row mt-3 mx-4">
<div class="col-sm-6 mt-2 pe-sm-2">
<div class="form-outline">
<label class="form-label" for="{{form.street.id}}">{{form.street.label}}</label>
@ -72,7 +73,30 @@
{{form.zip_code}}
</div>
</div>
</div>
<div class="row mt-3">
<div class="col-12 px-4">
<h2>Płatność i wysyłka</h2>
</div>
<hr class="mt-2" />
</div>
<div class="row mt-3 mx-4">
<div class="col-sm-12 mt-2 pe-sm-2">
<div class="form-outline">
<label class="form-label" for="{{form.street.id}}">{{form.payment_method.label}}</label>
{{form.payment_method}}
</div>
</div>
<div class="col-sm-12 mt-2 pe-sm-2">
<div class="form-outline">
<label class="form-label" for="{{form.street.id}}">{{form.delivery_method.label}}</label>
{{form.delivery_method}}
</div>
</div>
</div>
<div class="row mt-3">
<div class="col-12 text-end mt-3">
<div class="form-outline">
<input type="submit" value="Dalej" class="btn btn-success btn-lg">

Wyświetl plik

@ -11,13 +11,15 @@ from django.shortcuts import (
from django.urls import reverse
from django.http import HttpResponseRedirect
from django.contrib import messages
from django.forms import modelformset_factory
from rest_framework.viewsets import ViewSet
from rest_framework.decorators import action
from rest_framework.response import Response
from store.tasks import send_produt_request_email
from store.cart import SessionCart
from store.cart import (
SessionCart,
CustomerData
)
from store.serializers import (
CartSerializer,
CartProductAddSerializer
@ -174,9 +176,8 @@ class OrderView(View):
context = self.get_context_data()
context["form"] = form
return render(request, self.template_name, context)
customer_data = form.data
# TODO - add encryption
request.session["customer_data"] = customer_data
customer_data = CustomerData(data=form.cleaned_data)
request.session["customer_data"] = customer_data.data
return HttpResponseRedirect(reverse("order-confirm"))
@ -184,7 +185,9 @@ class OrderConfirmView(View):
template_name = "store/order_confirm.html"
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]:
customer_data = self.request.session["customer_data"]
customer_data = CustomerData(
encrypted_data=self.request.session["customer_data"]
).decrypted_data
return {
"cart": SessionCart(self.request),
"customer_data": customer_data
@ -193,7 +196,7 @@ class OrderConfirmView(View):
def get(self, request, *args, **kwargs):
cart = SessionCart(self.request)
if cart.is_empty():
# TODO - messages
messages.error(request, "Twój koszyk jest pusty")
return HttpResponseRedirect(reverse("cart"))
return render(request, self.template_name, self.get_context_data())