u
This commit is contained in:
parent
573e911d01
commit
49cd076b63
5 changed files with 103 additions and 41 deletions
|
|
@ -75,6 +75,7 @@ THIRD_PARTY_APPS = [
|
||||||
"crispy_forms",
|
"crispy_forms",
|
||||||
"crispy_bootstrap5",
|
"crispy_bootstrap5",
|
||||||
"allauth",
|
"allauth",
|
||||||
|
'allauth.headless',
|
||||||
"allauth.account",
|
"allauth.account",
|
||||||
"allauth.mfa",
|
"allauth.mfa",
|
||||||
"allauth.socialaccount",
|
"allauth.socialaccount",
|
||||||
|
|
@ -233,7 +234,7 @@ EMAIL_TIMEOUT = 5
|
||||||
# Django Admin URL.
|
# Django Admin URL.
|
||||||
ADMIN_URL = "admin/"
|
ADMIN_URL = "admin/"
|
||||||
# https://docs.djangoproject.com/en/dev/ref/settings/#admins
|
# https://docs.djangoproject.com/en/dev/ref/settings/#admins
|
||||||
ADMINS = [("""Ahmed Nagi""", "ahmed10nagi@gmail.com")]
|
ADMINS = [("""ص""", "e@gmail.com")]
|
||||||
# https://docs.djangoproject.com/en/dev/ref/settings/#managers
|
# https://docs.djangoproject.com/en/dev/ref/settings/#managers
|
||||||
MANAGERS = ADMINS
|
MANAGERS = ADMINS
|
||||||
# https://cookiecutter-django.readthedocs.io/en/latest/settings.html#other-environment-settings
|
# https://cookiecutter-django.readthedocs.io/en/latest/settings.html#other-environment-settings
|
||||||
|
|
@ -330,8 +331,22 @@ ACCOUNT_EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL = None
|
||||||
# ACCOUNT_RATE_LIMITS = {
|
# ACCOUNT_RATE_LIMITS = {
|
||||||
# "confirm_email": "1/4m", # 1 confirmation email every 4 minutes
|
# "confirm_email": "1/4m", # 1 confirmation email every 4 minutes
|
||||||
# }
|
# }
|
||||||
|
HEADLESS_FRONTEND_URLS = {
|
||||||
|
"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.
|
||||||
|
#
|
||||||
|
# "https://app.project.org/account/email/verify-email?token={key}",
|
||||||
|
"account_reset_password": "https://app.project.org/account/password/reset",
|
||||||
|
"account_reset_password_from_key": "https://app.project.org/account/password/reset/key/{key}",
|
||||||
|
# "account_signup": "https://app.project.org/account/signup",
|
||||||
|
# Fallback in case the state containing the `next` URL is lost and the handshake
|
||||||
|
# with the third-party provider fails.
|
||||||
|
# "socialaccount_login_error": "https://app.project.org/account/provider/callback",
|
||||||
|
}
|
||||||
|
HEADLESS_ONLY = True
|
||||||
# https://docs.allauth.org/en/latest/account/configuration.html
|
# https://docs.allauth.org/en/latest/account/configuration.html
|
||||||
ACCOUNT_ADAPTER = "lms.accounts.adapters.CustomAccountAdapter"
|
# ACCOUNT_ADAPTER = "lms.accounts.adapters.CustomAccountAdapter"
|
||||||
# https://docs.allauth.org/en/latest/account/forms.html
|
# https://docs.allauth.org/en/latest/account/forms.html
|
||||||
# ACCOUNT_FORMS = {"signup": "lms.users.forms.UserSignupForm"}
|
# ACCOUNT_FORMS = {"signup": "lms.users.forms.UserSignupForm"}
|
||||||
# https://docs.allauth.org/en/latest/socialaccount/configuration.html
|
# https://docs.allauth.org/en/latest/socialaccount/configuration.html
|
||||||
|
|
@ -353,6 +368,7 @@ REST_FRAMEWORK = {
|
||||||
'dj_rest_auth.jwt_auth.JWTCookieAuthentication',
|
'dj_rest_auth.jwt_auth.JWTCookieAuthentication',
|
||||||
),
|
),
|
||||||
"DEFAULT_PERMISSION_CLASSES": (
|
"DEFAULT_PERMISSION_CLASSES": (
|
||||||
|
'rest_framework.permissions.AllowAny',
|
||||||
"rest_framework.permissions.IsAuthenticated",
|
"rest_framework.permissions.IsAuthenticated",
|
||||||
),
|
),
|
||||||
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
|
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
|
||||||
|
|
@ -384,8 +400,17 @@ SPECTACULAR_SETTINGS = {
|
||||||
"TITLE": "Learning Management System API",
|
"TITLE": "Learning Management System API",
|
||||||
"DESCRIPTION": "Documentation of API endpoints of Learning Management System",
|
"DESCRIPTION": "Documentation of API endpoints of Learning Management System",
|
||||||
"VERSION": "1.0.0",
|
"VERSION": "1.0.0",
|
||||||
"SERVE_PERMISSIONS": ["rest_framework.permissions.IsAdminUser"],
|
# "SERVE_PERMISSIONS": ["rest_framework.permissions.IsAdminUser"],
|
||||||
"SCHEMA_PATH_PREFIX": "/api/",
|
"SCHEMA_PATH_PREFIX": "/api/",
|
||||||
|
'SERVE_INCLUDE_SCHEMA': False,
|
||||||
}
|
}
|
||||||
# Your stuff...
|
# Your stuff...
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
# CSRF_COOKIE_SECURE = False # لأنك لا تستخدم HTTPS محليًا
|
||||||
|
# CSRF_COOKIE_SAMESITE = 'None' # للسماح بالطلبات عبر النطاقات
|
||||||
|
# CSRF_COOKIE_HTTPONLY = False # للسماح للـ JavaScript بالوصول إذا لزم الأمر
|
||||||
|
|
||||||
|
# SESSION_COOKIE_SECURE = False
|
||||||
|
# SESSION_COOKIE_SAMESITE = 'None'
|
||||||
|
# SESSION_COOKIE_HTTPONLY = True
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,13 +12,52 @@ from drf_spectacular.views import SpectacularSwaggerView
|
||||||
from rest_framework.authtoken.views import obtain_auth_token
|
from rest_framework.authtoken.views import obtain_auth_token
|
||||||
from lms.accounts.views import *
|
from lms.accounts.views import *
|
||||||
|
|
||||||
|
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 = [
|
urlpatterns = [
|
||||||
path("", TemplateView.as_view(template_name="pages/home.html"), name="home"),
|
path("", TemplateView.as_view(template_name="pages/home.html"), name="home"),
|
||||||
# Django Admin, use {% url 'admin:index' %}
|
# Django Admin, use {% url 'admin:index' %}
|
||||||
path(settings.ADMIN_URL, admin.site.urls),
|
path(settings.ADMIN_URL, admin.site.urls),
|
||||||
# User management
|
# User management
|
||||||
|
path("ex/", SetCookieExampleView.as_view(), name="ex"),
|
||||||
|
# path("users/", include("lms.users.urls", namespace="users")),
|
||||||
path("accounts/", include("allauth.urls")),
|
path("accounts/", include("allauth.urls")),
|
||||||
|
path("auth/", include("allauth.headless.urls")),
|
||||||
# Your stuff: custom urls includes go here
|
# Your stuff: custom urls includes go here
|
||||||
# ...
|
# ...
|
||||||
# Media files
|
# Media files
|
||||||
|
|
@ -31,11 +70,11 @@ if settings.DEBUG:
|
||||||
# API URLS
|
# API URLS
|
||||||
urlpatterns += [
|
urlpatterns += [
|
||||||
|
|
||||||
path('authw/', include('dj_rest_auth.urls')),
|
# path('authw/', include('dj_rest_auth.urls')),
|
||||||
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
|
# 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
|
# API base url
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,6 @@ router.register(r'modules', ModuleViewSet, basename='modules')
|
||||||
router.register(r'lessons', LessonViewSet, basename='lessons')
|
router.register(r'lessons', LessonViewSet, basename='lessons')
|
||||||
router.register(r'enrollment', EnrollmentViewSet, basename='enrollment')
|
router.register(r'enrollment', EnrollmentViewSet, basename='enrollment')
|
||||||
router.register(r'quiz', QuizViewSet, basename='quiz')
|
router.register(r'quiz', QuizViewSet, basename='quiz')
|
||||||
router.register(r'certificate', CertificateViewSet, basename='certificate')
|
# router.register(r'certificate', CertificateViewSet, basename='certificate')
|
||||||
|
|
||||||
urlpatterns = router.urls
|
urlpatterns = router.urls
|
||||||
|
|
@ -259,8 +259,6 @@ class QuizViewSet(ModelViewSet):
|
||||||
if module.course.owner != request.user:
|
if module.course.owner != request.user:
|
||||||
return Response({"detail": "You can only create quizzes for your own courses"}, status=status.HTTP_403_FORBIDDEN)
|
return Response({"detail": "You can only create quizzes for your own courses"}, status=status.HTTP_403_FORBIDDEN)
|
||||||
# Create a new quiz
|
# Create a new quiz
|
||||||
# data = request.data.copy() # نسخ البيانات لتجنب التعديل على الأصل
|
|
||||||
# data.pop('module', None) # إزالة المفتاح module إذا كان موجودًا
|
|
||||||
quiz = Quiz.objects.create(module=module)
|
quiz = Quiz.objects.create(module=module)
|
||||||
serializer = self.get_serializer(quiz)
|
serializer = self.get_serializer(quiz)
|
||||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||||
|
|
@ -295,40 +293,40 @@ class QuizViewSet(ModelViewSet):
|
||||||
return Response({"detail": "Quiz deleted successfully"}, status=status.HTTP_204_NO_CONTENT)
|
return Response({"detail": "Quiz deleted successfully"}, status=status.HTTP_204_NO_CONTENT)
|
||||||
|
|
||||||
|
|
||||||
class CertificateViewSet(ModelViewSet):
|
# class CertificateViewSet(ModelViewSet):
|
||||||
queryset = Certificate.objects.all()
|
# queryset = Certificate.objects.all()
|
||||||
serializer_class = CertificateSerializer
|
# serializer_class = CertificateSerializer
|
||||||
permission_classes = []
|
# permission_classes = []
|
||||||
|
|
||||||
def get_permissions(self):
|
# def get_permissions(self):
|
||||||
if self.action == 'create':
|
# if self.action == 'create':
|
||||||
# permission_classes = [Isowner]
|
# # permission_classes = [Isowner]
|
||||||
pass
|
# pass
|
||||||
elif self.action in ['update', 'destroy']:
|
# elif self.action in ['update', 'destroy']:
|
||||||
permission_classes = [IsAdmin]
|
# permission_classes = [IsAdmin]
|
||||||
else:
|
# # else:
|
||||||
permission_classes = []
|
# # permission_classes = []
|
||||||
return [permission() for permission in permission_classes]
|
# # return [permission() for permission in permission_classes]
|
||||||
|
|
||||||
|
|
||||||
def create(self, request, *args, **kwargs):
|
# def create(self, request, *args, **kwargs):
|
||||||
|
|
||||||
# Get course data from the request
|
# # Get course data from the request
|
||||||
courseId = request.data.get('course')
|
# courseId = request.data.get('course')
|
||||||
student_id = request.data.get('student')
|
# student_id = request.data.get('student')
|
||||||
# Check if the course exists
|
# # Check if the course exists
|
||||||
try:
|
# try:
|
||||||
course = Course.objects.get(id=courseId)
|
# course = Course.objects.get(id=courseId)
|
||||||
student = User.objects.get(id=student_id, role='student')
|
# student = User.objects.get(id=student_id, role='student')
|
||||||
except User.DoesNotExist:
|
# except User.DoesNotExist:
|
||||||
return Response({"detail": "Student not found"}, status=status.HTTP_404_NOT_FOUND)
|
# return Response({"detail": "Student not found"}, status=status.HTTP_404_NOT_FOUND)
|
||||||
except Course.DoesNotExist:
|
# except Course.DoesNotExist:
|
||||||
return Response({"detail": "Course not found"}, status=status.HTTP_404_NOT_FOUND)
|
# return Response({"detail": "Course not found"}, status=status.HTTP_404_NOT_FOUND)
|
||||||
# Ensure the current owner is the course owner
|
# # Ensure the current owner is the course owner
|
||||||
if course.owner != request.user:
|
# if course.owner != request.user:
|
||||||
return Response({"detail": "You can only create certificate for your own courses"}, status=status.HTTP_403_FORBIDDEN)
|
# return Response({"detail": "You can only create certificate for your own courses"}, status=status.HTTP_403_FORBIDDEN)
|
||||||
|
|
||||||
certificate = Certificate.objects.create(course=course, student=student)
|
# certificate = Certificate.objects.create(course=course, student=student)
|
||||||
serializer = self.get_serializer(certificate)
|
# serializer = self.get_serializer(certificate)
|
||||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
# return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||||
|
|
||||||
Loading…
Add table
Reference in a new issue