u
This commit is contained in:
parent
4e1b8b9a02
commit
1bf4e86d4c
6 changed files with 42 additions and 49 deletions
|
|
@ -320,18 +320,24 @@ ACCOUNT_USERNAME_REQUIRED = False
|
|||
ACCOUNT_USER_MODEL_USERNAME_FIELD = None
|
||||
# https://docs.allauth.org/en/latest/account/configuration.html
|
||||
ACCOUNT_EMAIL_VERIFICATION = "mandatory"
|
||||
ACCOUNT_LOGIN_METHODS = {"email"}
|
||||
ACCOUNT_LOGOUT_ON_GET = True
|
||||
LOGOUT_ON_PASSWORD_CHANGE = False
|
||||
ACCOUNT_LOGOUT_ON_PASSWORD_CHANGE = False
|
||||
ACCOUNT_CHANGE_EMAIL = True
|
||||
# ACCOUNT_EMAIL_VERIFICATION_BY_CODE_ENABLED = True
|
||||
HEADLESS_SERVE_SPECIFICATION = True
|
||||
|
||||
ACCOUNT_EMAIL_CONFIRMATION_HMAC = True
|
||||
ACCOUNT_CONFIRM_EMAIL_ON_GET = True
|
||||
ACCOUNT_MAX_EMAIL_ADDRESSES = 2
|
||||
|
||||
ACCOUNT_EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL = None
|
||||
ACCOUNT_EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL = None
|
||||
# ACCOUNT_RATE_LIMITS = {
|
||||
# "confirm_email": "1/4m", # 1 confirmation email every 4 minutes
|
||||
# }
|
||||
HEADLESS_FRONTEND_URLS = {
|
||||
"account_signup":"http://localhost:3000/account/signup",
|
||||
"account_confirm_email": "http://127.0.0.1:3000/account/email-confirmation/{key}/",
|
||||
# Key placeholders are automatically populated. You are free to adjust this
|
||||
# to your own needs, e.g.
|
||||
|
|
@ -368,7 +374,7 @@ REST_FRAMEWORK = {
|
|||
'dj_rest_auth.jwt_auth.JWTCookieAuthentication',
|
||||
),
|
||||
"DEFAULT_PERMISSION_CLASSES": (
|
||||
'rest_framework.permissions.AllowAny',
|
||||
# 'rest_framework.permissions.AllowAny',
|
||||
"rest_framework.permissions.IsAuthenticated",
|
||||
),
|
||||
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ CORS_ALLOW_HEADERS = [
|
|||
"user-agent",
|
||||
"x-csrftoken",
|
||||
"x-requested-with",
|
||||
"x-session-token",
|
||||
]
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16,37 +16,6 @@ from rest_framework.views import APIView
|
|||
from rest_framework.response import Response
|
||||
from rest_framework.permissions import AllowAny
|
||||
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.permissions import AllowAny
|
||||
|
||||
class SetCookieExampleView(APIView):
|
||||
permission_classes = [AllowAny]
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
# الحصول على قيمة 'target' من البيانات المرسلة مع الطلب
|
||||
target = request.META.get('HTTP_ORIGIN', 'No origin provided') # افتراض قيمة افتراضية
|
||||
|
||||
# طباعة 'target' في وحدة التحكم
|
||||
print(f"Target received: {target}")
|
||||
|
||||
# إعداد الاستجابة
|
||||
response = Response({
|
||||
"message": "Cookie set successfully!",
|
||||
"target": target, # إضافة 'target' إلى الاستجابة كإخراج اختباري
|
||||
})
|
||||
|
||||
# إعداد الكوكي بدون أمان (HTTP فقط)
|
||||
response.set_cookie(
|
||||
key='my_cookie_name', # اسم الكوكي
|
||||
value='my_cookie_value', # قيمة الكوكي
|
||||
max_age=3600, # وقت انتهاء الصلاحية بالثواني
|
||||
httponly=False, # يمكن الوصول للكوكي من JavaScript
|
||||
samesite=None, # السماح باستخدام الكوكي عبر المواقع (Cross-Site)
|
||||
)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
|
|
@ -54,10 +23,9 @@ urlpatterns = [
|
|||
# Django Admin, use {% url 'admin:index' %}
|
||||
path(settings.ADMIN_URL, admin.site.urls),
|
||||
# User management
|
||||
path("ex/", SetCookieExampleView.as_view(), name="ex"),
|
||||
# path("users/", include("lms.users.urls", namespace="users")),
|
||||
path("accounts/", include("allauth.urls")),
|
||||
path("auth/", include("allauth.headless.urls")),
|
||||
# path("auth/", include("allauth.headless.urls")),
|
||||
# Your stuff: custom urls includes go here
|
||||
# ...
|
||||
# Media files
|
||||
|
|
@ -72,15 +40,13 @@ urlpatterns += [
|
|||
|
||||
# path('authw/', include('dj_rest_auth.urls')),
|
||||
# path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
|
||||
# path('auth/', include('lms.accounts.urls')),
|
||||
path('auth/', include('lms.accounts.urls')),
|
||||
|
||||
# path('app/', include('lms.app.urls')),
|
||||
path('app/', include('lms.app.urls')),
|
||||
|
||||
|
||||
# API base url
|
||||
# path("api/", include("config.api_router")),
|
||||
# DRF auth token
|
||||
path("api/auth-token/", obtain_auth_token),
|
||||
# path("api/auth-token/", obtain_auth_token),
|
||||
path("api/schema/", SpectacularAPIView.as_view(), name="api-schema"),
|
||||
path(
|
||||
"api/docs/",
|
||||
|
|
|
|||
|
|
@ -9,11 +9,14 @@ from django.contrib.auth import get_user_model
|
|||
from rest_framework.exceptions import ValidationError
|
||||
from allauth.account.utils import send_email_confirmation
|
||||
from rest_framework.response import Response
|
||||
from .validation_error import CustomValidationError
|
||||
|
||||
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
class CustomLoginSerializer(LoginSerializer):
|
||||
|
||||
email = serializers.EmailField(required=True)
|
||||
password = serializers.CharField(style={'input_type': 'password'}, write_only=True)
|
||||
|
||||
|
|
@ -22,24 +25,28 @@ class CustomLoginSerializer(LoginSerializer):
|
|||
password = attrs.get('password')
|
||||
|
||||
if not email or not password:
|
||||
raise serializers.ValidationError(_("Please enter both email and password."))
|
||||
raise CustomValidationError(_("Please enter both email and password."))
|
||||
|
||||
# البحث عن المستخدم بالبريد الإلكتروني
|
||||
users = User.objects.filter(email=email)
|
||||
email_address = EmailAddress.objects.filter(email=email).first()
|
||||
|
||||
if not users.exists():
|
||||
raise serializers.ValidationError(_("No account found with this email."))
|
||||
raise CustomValidationError(_("No account found with this email."))
|
||||
|
||||
if not email_address.verified:
|
||||
CustomValidationError(_("Email not verified. Please verify your email first."))
|
||||
|
||||
if users.count() > 1:
|
||||
raise serializers.ValidationError(_("Multiple accounts found with this email. Please contact support."))
|
||||
raise CustomValidationError(_("Multiple accounts found with this email. Please contact support."))
|
||||
|
||||
user = users.first()
|
||||
|
||||
if not user.check_password(password):
|
||||
raise serializers.ValidationError(_("Incorrect password."))
|
||||
raise CustomValidationError(_("Incorrect password."))
|
||||
|
||||
if not self.is_email_verified(user):
|
||||
raise serializers.ValidationError(_("Email not verified. Please verify your email first."))
|
||||
raise CustomValidationError(_("Email not verified. Please verify your email first."))
|
||||
|
||||
# إضافة المستخدم إلى الـ attrs
|
||||
attrs['user'] = user
|
||||
|
|
@ -66,10 +73,10 @@ class CustomRegisterSerializer(RegisterSerializer):
|
|||
email_address = EmailAddress.objects.filter(email=email).first()
|
||||
if email_address:
|
||||
if email_address.verified:
|
||||
raise ValidationError({'email': 'This email is already.'})
|
||||
CustomValidationError({'email': 'This email is already.'})
|
||||
else:
|
||||
send_email_confirmation(request, email_address.user)
|
||||
raise ValidationError({'email': 'A confirmation email has been sent. Please confirm your email.'})
|
||||
CustomValidationError({'email': 'A confirmation email has been sent. Please confirm your email.'})
|
||||
|
||||
user = super().save(request)
|
||||
user.full_name = self.data.get('full_name', '')
|
||||
|
|
@ -88,7 +95,7 @@ class ChangeEmailSerializer(serializers.Serializer):
|
|||
|
||||
def validate_email(self, value):
|
||||
if EmailAddress.objects.filter(email=value).exists() or User.objects.filter(email=value).exists():
|
||||
raise serializers.ValidationError("This email is already in use.")
|
||||
raise CustomValidationError("This email is already in use.")
|
||||
return value
|
||||
|
||||
def save(self, user):
|
||||
|
|
|
|||
13
lms/accounts/validation_error.py
Normal file
13
lms/accounts/validation_error.py
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
from rest_framework.exceptions import APIException
|
||||
|
||||
|
||||
class CustomValidationError(APIException):
|
||||
status_code = 400
|
||||
default_detail = 'A validation error occurred.'
|
||||
default_code = 'validation_error'
|
||||
|
||||
def __init__(self, detail=None, code=None):
|
||||
if detail is not None:
|
||||
self.detail = detail
|
||||
if code is not None:
|
||||
self.status_code = code
|
||||
|
|
@ -15,7 +15,7 @@ class CourseViewSet(ModelViewSet):
|
|||
A ViewSet for viewing and editing Course instances.
|
||||
"""
|
||||
queryset = Course.objects.all()
|
||||
permission_classes = [IsOwnerOrReadOnly]
|
||||
permission_classes = [IsAuthenticated, IsOwnerOrReadOnly]
|
||||
serializer_class = CourseSerializer
|
||||
|
||||
def perform_create(self, serializer):
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue