diff --git a/.env.example b/.env.example index 7a42722..6337151 100644 --- a/.env.example +++ b/.env.example @@ -25,4 +25,11 @@ PORT= ################## ## RUNNING COMMAND ################## -COMMAND=sh ./resources/scripts/entrypoint.sh \ No newline at end of file +COMMAND=sh ./resources/scripts/entrypoint.sh + + +################## +## CORS and CSRF +################## +CORS_ALLOWED_ORIGINS= +CSRF_TRUSTED_ORIGINS= diff --git a/config/conf/__init__.py b/config/conf/__init__.py index e69de29..4920894 100644 --- a/config/conf/__init__.py +++ b/config/conf/__init__.py @@ -0,0 +1,5 @@ +from .djangorestframework import * +from .simple_jwt import * +from .jazzmin import * +from .cors_headers import * +from .redis import * diff --git a/config/conf/cors_headers.py b/config/conf/cors_headers.py new file mode 100644 index 0000000..7ecd04a --- /dev/null +++ b/config/conf/cors_headers.py @@ -0,0 +1,4 @@ +from config.env import env + +CORS_ALLOWED_ORIGINS = env.list('CORS_ALLOWED_ORIGINS') +CSRF_TRUSTED_ORIGINS = env.list('CSRF_TRUSTED_ORIGINS') \ No newline at end of file diff --git a/config/conf/djangorestframework.py b/config/conf/djangorestframework.py new file mode 100644 index 0000000..8709aea --- /dev/null +++ b/config/conf/djangorestframework.py @@ -0,0 +1,7 @@ +REST_FRAMEWORK = { + 'DEFAULT_AUTHENTICATION_CLASSES': [ + 'rest_framework.authentication.SessionAuthentication', + 'rest_framework.authentication.BasicAuthentication' + 'rest_framework_simplejwt.authentication.JWTAuthentication', + ], +} \ No newline at end of file diff --git a/config/conf/jazzmin.py b/config/conf/jazzmin.py new file mode 100644 index 0000000..d92c9e4 --- /dev/null +++ b/config/conf/jazzmin.py @@ -0,0 +1,44 @@ +JAZZMIN_SETTINGS = { + "site_title": "Quruvchi Boshqaruv", + "site_header": "Quruvchi Boshqaruv", + "site_brand": "Quruvchi Boshqaruv", + "site_logo": None, + "login_logo": None, + "login_logo_dark": None, + "site_logo_classes": "img-circle", + "site_icon": None, + "welcome_sign": "Welcome to the Quruvchi Boshqaruv", + "copyright": "Quruvchi Boshqaruv", + "search_model": [], + "topmenu_links": [ + {"name": "Home", "url": "admin:index", "permissions": ["auth.view_user"]}, + {"name": "Support", "url": "https://github.com/farridav/django-jazzmin/issues", "new_window": True}, + {"model": "auth.User"}, + {"app": "books"}, + ], + "usermenu_links": [ + {"name": "Support", "url": "https://github.com/farridav/django-jazzmin/issues", "new_window": True}, + {"model": "auth.user"} + ], + "show_sidebar": True, + "navigation_expanded": True, + "hide_apps": [], + "hide_models": ['auth.group'], + "order_with_respect_to": [], + "custom_links": { + }, + "icons": { + "auth": "fas fa-users-cog", + "auth.user": "fas fa-user", + "auth.Group": "fas fa-users", + }, + "default_icon_parents": "fas fa-chevron-circle-right", + "default_icon_children": "fas fa-circle", + "related_modal_active": False, + "custom_css": None, + "custom_js": None, + "use_google_fonts_cdn": True, + "show_ui_builder": False, + "changeform_format": "collapsible", + "language_chooser": True, +} diff --git a/config/conf/simple_jwt.py b/config/conf/simple_jwt.py new file mode 100644 index 0000000..38cfc07 --- /dev/null +++ b/config/conf/simple_jwt.py @@ -0,0 +1,27 @@ +from datetime import timedelta + +from django.conf import settings + + +SIMPLE_JWT = { + "ACCESS_TOKEN_LIFETIME": timedelta(days=2), + "REFRESH_TOKEN_LIFETIME": timedelta(days=60), + "ROTATE_REFRESH_TOKENS": True, + "BLACKLIST_AFTER_ROTATION": True, + "UPDATE_LAST_LOGIN": True, + + "ALGORITHM": "HS256", + "SIGNING_KEY": settings.SECRET_KEY, + + "AUTH_HEADER_TYPES": ("Bearer",), + "AUTH_HEADER_NAME": "HTTP_AUTHORIZATION", + "USER_ID_FIELD": "id", + "USER_ID_CLAIM": "user_id", + + "TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainPairSerializer", + "TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSerializer", + "TOKEN_VERIFY_SERIALIZER": "rest_framework_simplejwt.serializers.TokenVerifySerializer", + "TOKEN_BLACKLIST_SERIALIZER": "rest_framework_simplejwt.serializers.TokenBlacklistSerializer", + "SLIDING_TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainSlidingSerializer", + "SLIDING_TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSlidingSerializer", +} \ No newline at end of file diff --git a/config/settings/base.py b/config/settings/base.py index 7ddd5b6..68b0d3e 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -15,6 +15,7 @@ ALLOWED_HOSTS = env.list('ALLOWED_HOSTS') # APPS SHARED_APPS = [ 'django_tenants', + 'jazzmin', 'core.apps.customers', 'django.contrib.contenttypes', ] @@ -31,7 +32,12 @@ TENANT_APPS = [ 'core.apps.shared', ] -PACKAGES = [] +PACKAGES = [ + 'corsheaders', + 'rest_framework', + 'rest_framework_simplejwt', + 'drf_yasg', +] INSTALLED_APPS = SHARED_APPS + DJANGO_APPS + PACKAGES + TENANT_APPS @@ -41,6 +47,7 @@ MIDDLEWARE = [ 'django_tenants.middleware.main.TenantMainMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', + 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', @@ -117,3 +124,6 @@ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' TENANT_MODEL = "customers.Client" TENANT_DOMAIN_MODEL = "customers.Domain" + + +import config.conf \ No newline at end of file diff --git a/config/urls.py b/config/urls.py index 38aa099..5a5cc10 100644 --- a/config/urls.py +++ b/config/urls.py @@ -1,13 +1,38 @@ +# django from django.contrib import admin from django.urls import path from django.conf import settings from django.conf.urls.static import static +# rest framework +from rest_framework import permissions +# drf yasg +from drf_yasg.views import get_schema_view +from drf_yasg import openapi + +schema_view = get_schema_view( + openapi.Info( + title="Qurilish Boshqaruv API", + default_version='v1', + description="Qurilish boshqaruv api", + terms_of_service="https://www.google.com/policies/terms/", + contact=openapi.Contact(email="xoliqberdiyevbehruz12@gmail.com"), + license=openapi.License(name="Behruz's-Organization License"), + ), + public=False, + permission_classes=(permissions.IsAdminUser,), +) urlpatterns = [ path('admin/', admin.site.urls), ] +urlpatterns += [ + path('swagger/', schema_view.without_ui(cache_timeout=0), name='schema-json'), + path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'), + path('redoc/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'), +] + urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index a5ad1f5..b951e6f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,11 +1,36 @@ +amqp==5.3.1 asgiref==3.10.0 +billiard==4.2.3 +celery==5.5.3 click==8.3.1 +click-didyoumean==0.3.1 +click-plugins==1.1.1.2 +click-repl==0.3.0 Django==5.2 +django-cors-headers==4.9.0 django-environ==0.12.0 +django-filter==25.2 +django-jazzmin==3.0.1 django-tenants==3.9.0 +djangorestframework==3.16.1 +djangorestframework_simplejwt==5.5.1 +drf-yasg==1.21.11 gunicorn==23.0.0 h11==0.16.0 +inflection==0.5.1 +kombu==5.5.4 packaging==25.0 +prompt_toolkit==3.0.52 psycopg2-binary==2.9.11 +PyJWT==2.10.1 +python-dateutil==2.9.0.post0 +pytz==2025.2 +PyYAML==6.0.3 +redis==7.0.1 +six==1.17.0 sqlparse==0.5.3 +tzdata==2025.2 +uritemplate==4.2.0 uvicorn==0.38.0 +vine==5.1.0 +wcwidth==0.2.14