zmiany mariusza
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,16 @@
|
||||
"""
|
||||
ASGI config for izaac2backend project.
|
||||
|
||||
It exposes the ASGI callable as a module-level variable named ``application``.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/5.2/howto/deployment/asgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.asgi import get_asgi_application
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'izaac2backend.settings')
|
||||
|
||||
application = get_asgi_application()
|
||||
@@ -0,0 +1,306 @@
|
||||
"""
|
||||
Django settings for izaac2backend project.
|
||||
|
||||
Generated by 'django-admin startproject' using Django 5.2.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/5.2/topics/settings/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/5.2/ref/settings/
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
from datetime import timedelta
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
|
||||
# Custom user model
|
||||
AUTH_USER_MODEL = 'users.User'
|
||||
|
||||
# Frontend URL for password reset links
|
||||
FRONTEND_URL = 'http://localhost:5173' # Vite default port
|
||||
|
||||
# Email Configuration
|
||||
if DEBUG:
|
||||
# Development email settings (console backend)
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
||||
DEFAULT_FROM_EMAIL = 'noreply@izaac.com'
|
||||
else:
|
||||
# Production email settings (SMTP backend)
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||
EMAIL_HOST = 'smtp.gmail.com' # Or your SMTP server
|
||||
EMAIL_PORT = 587
|
||||
EMAIL_USE_TLS = True
|
||||
EMAIL_HOST_USER = '' # Your email address
|
||||
EMAIL_HOST_PASSWORD = '' # Your email password or app-specific password
|
||||
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = 'django-insecure-^+2p2e93g2_1h-@u&l&j+(9n&6z02-e$pirm6(@@(4$+-zyhxr'
|
||||
|
||||
|
||||
|
||||
ALLOWED_HOSTS = ["localhost", "127.0.0.1"]
|
||||
|
||||
CORS_ALLOWED_ORIGINS = [
|
||||
"http://localhost:5173",
|
||||
"http://127.0.0.1:5173",
|
||||
]
|
||||
|
||||
CORS_ALLOW_CREDENTIALS = True
|
||||
|
||||
CSRF_TRUSTED_ORIGINS = [
|
||||
"http://localhost:5173",
|
||||
"http://127.0.0.1:5173",
|
||||
]
|
||||
|
||||
REST_FRAMEWORK = {
|
||||
'DEFAULT_AUTHENTICATION_CLASSES': (
|
||||
'users.authentication.VersionedJWTAuthentication',
|
||||
),
|
||||
'DEFAULT_PERMISSION_CLASSES': (
|
||||
'rest_framework.permissions.IsAuthenticated',
|
||||
),
|
||||
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
|
||||
'DEFAULT_RENDERER_CLASSES': (
|
||||
'rest_framework.renderers.JSONRenderer',
|
||||
'rest_framework.renderers.BrowsableAPIRenderer',
|
||||
),
|
||||
|
||||
'DEFAULT_THROTTLE_CLASSES': [
|
||||
'rest_framework.throttling.ScopedRateThrottle',
|
||||
],
|
||||
'DEFAULT_THROTTLE_RATES': {
|
||||
'login': '5/min', # ⬅️ scope do TokenObtainPair
|
||||
'reset_password': '3/min',
|
||||
'avatar_upload': '3/minute',
|
||||
'avatar_get': '100/minute' # ⬅️ scope do resetu hasła
|
||||
},
|
||||
}
|
||||
|
||||
SIMPLE_JWT = {
|
||||
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=30),
|
||||
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
|
||||
'ROTATE_REFRESH_TOKENS': True,
|
||||
'BLACKLIST_AFTER_ROTATION': True,
|
||||
'UPDATE_LAST_LOGIN': False,
|
||||
|
||||
'ALGORITHM': 'HS256',
|
||||
'SIGNING_KEY': SECRET_KEY,
|
||||
'VERIFYING_KEY': None,
|
||||
'AUDIENCE': None,
|
||||
'ISSUER': None,
|
||||
'JWK_URL': None,
|
||||
'LEEWAY': 0,
|
||||
|
||||
'AUTH_HEADER_TYPES': ('Bearer',),
|
||||
'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',
|
||||
'USER_ID_FIELD': 'id',
|
||||
'USER_ID_CLAIM': 'user_id',
|
||||
'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule',
|
||||
|
||||
'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
|
||||
'TOKEN_TYPE_CLAIM': 'token_type',
|
||||
'TOKEN_USER_CLASS': 'rest_framework_simplejwt.models.TokenUser',
|
||||
|
||||
'JTI_CLAIM': 'jti',
|
||||
}
|
||||
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'rest_framework',
|
||||
'drf_spectacular',
|
||||
'corsheaders',
|
||||
'rest_framework_simplejwt',
|
||||
'rest_framework_simplejwt.token_blacklist',
|
||||
'core',
|
||||
'users',
|
||||
'content',
|
||||
'formulas',
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
'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',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
]
|
||||
|
||||
ROOT_URLCONF = 'izaac2backend.urls'
|
||||
|
||||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [],
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
'django.template.context_processors.request',
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
WSGI_APPLICATION = 'izaac2backend.wsgi.application'
|
||||
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/5.2/ref/settings/#databases
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': BASE_DIR / 'db.sqlite3',
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators
|
||||
|
||||
AUTH_PASSWORD_VALIDATORS = [
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/5.2/topics/i18n/
|
||||
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
|
||||
TIME_ZONE = 'UTC'
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
USE_TZ = True
|
||||
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/5.2/howto/static-files/
|
||||
|
||||
STATIC_URL = 'static/'
|
||||
|
||||
# Default primary key field type
|
||||
# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field
|
||||
|
||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||
|
||||
# Add Spectacular settings
|
||||
SPECTACULAR_SETTINGS = {
|
||||
'TITLE': 'Izaac API',
|
||||
'DESCRIPTION': '''
|
||||
API for Izaac platform - A content management system with user authentication.
|
||||
|
||||
## Authentication
|
||||
This API uses JWT (JSON Web Token) for authentication. To authenticate:
|
||||
1. Use the `/api/v1/users/login/` endpoint to get your access and refresh tokens
|
||||
2. Include the access token in the Authorization header: `Bearer <your_access_token>`
|
||||
3. When the access token expires, use the refresh token to get a new one via `/api/v1/users/refresh/`
|
||||
|
||||
## Rate Limiting
|
||||
API requests are limited to 100 requests per minute per IP address.
|
||||
''',
|
||||
'VERSION': '1.0.0',
|
||||
'SERVE_INCLUDE_SCHEMA': False,
|
||||
'SWAGGER_UI_SETTINGS': {
|
||||
'deepLinking': True,
|
||||
'persistAuthorization': True,
|
||||
'displayOperationId': True,
|
||||
'filter': True,
|
||||
'syntaxHighlight.activate': True,
|
||||
'syntaxHighlight.theme': 'monokai',
|
||||
},
|
||||
'COMPONENT_SPLIT_REQUEST': True,
|
||||
'TAGS': [
|
||||
{
|
||||
'name': 'users',
|
||||
'description': 'User management endpoints including authentication and user operations'
|
||||
},
|
||||
{
|
||||
'name': 'content',
|
||||
'description': 'Content management endpoints for posts, comments, and other content types'
|
||||
}
|
||||
],
|
||||
'SECURITY': [{'jwtAuth': []}],
|
||||
'SECURITY_DEFINITIONS': {
|
||||
'jwtAuth': {
|
||||
'type': 'http',
|
||||
'scheme': 'bearer',
|
||||
'bearerFormat': 'JWT',
|
||||
'description': 'JWT token obtained from the login endpoint'
|
||||
}
|
||||
},
|
||||
'SERVE_AUTHENTICATION': None, # Allow public access to documentation
|
||||
'SERVE_PERMISSIONS': ['rest_framework.permissions.AllowAny'], # Allow public access to documentation
|
||||
'APPEND_COMPONENTS': {
|
||||
'securitySchemes': {
|
||||
'jwtAuth': {
|
||||
'type': 'http',
|
||||
'scheme': 'bearer',
|
||||
'bearerFormat': 'JWT',
|
||||
'description': 'JWT token obtained from the login endpoint'
|
||||
}
|
||||
}
|
||||
},
|
||||
'PREPROCESSING_HOOKS': [],
|
||||
'POSTPROCESSING_HOOKS': [],
|
||||
'SORT_OPERATIONS': True,
|
||||
'SORT_OPERATION_PARAMETERS': True,
|
||||
'ENUM_NAME_OVERRIDES': {
|
||||
'StatusEnum': 'content.models.AbstractContent.STATUS_CHOICES'
|
||||
},
|
||||
'GENERATOR_CLASS': 'drf_spectacular.generators.SchemaGenerator',
|
||||
'GENERATOR_CLASS_KWARGS': {
|
||||
'servers': [
|
||||
{'url': 'http://localhost:8000', 'description': 'Local development server'},
|
||||
{'url': 'https://api.izaac.com', 'description': 'Production server'}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# Add CORS settings
|
||||
CORS_ALLOWED_ORIGINS = [
|
||||
"http://localhost:5173", # Vite default port
|
||||
"http://127.0.0.1:5173",
|
||||
]
|
||||
|
||||
CORS_ALLOW_CREDENTIALS = True
|
||||
|
||||
# Media files (Uploads)
|
||||
MEDIA_URL = '/media/'
|
||||
MEDIA_ROOT = BASE_DIR / 'media'
|
||||
|
||||
# Maximum upload size (5MB)
|
||||
MAX_UPLOAD_SIZE = 5 * 1024 * 1024 # 5MB in bytes
|
||||
@@ -0,0 +1,38 @@
|
||||
"""
|
||||
URL configuration for izaac2backend project.
|
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||
https://docs.djangoproject.com/en/5.2/topics/http/urls/
|
||||
Examples:
|
||||
Function views
|
||||
1. Add an import: from my_app import views
|
||||
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
||||
Class-based views
|
||||
1. Add an import: from other_app.views import Home
|
||||
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
||||
Including another URLconf
|
||||
1. Import the include() function: from django.urls import include, path
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
from django.contrib import admin
|
||||
from django.urls import path, include
|
||||
from django.conf import settings
|
||||
from django.conf.urls.static import static
|
||||
from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView, SpectacularRedocView
|
||||
from rest_framework.permissions import AllowAny
|
||||
|
||||
urlpatterns = [
|
||||
path('admin/', admin.site.urls),
|
||||
path('api/users/', include('users.urls')),
|
||||
path('api/content/', include('content.urls')),
|
||||
# path('api/v1/core/', include('core.urls')),
|
||||
|
||||
# API Documentation URLs
|
||||
path('api/schema/', SpectacularAPIView.as_view(permission_classes=[AllowAny]), name='schema'),
|
||||
path('api/docs/', SpectacularSwaggerView.as_view(url_name='schema', permission_classes=[AllowAny]), name='swagger-ui'),
|
||||
path('api/redoc/', SpectacularRedocView.as_view(url_name='schema', permission_classes=[AllowAny]), name='redoc'),
|
||||
path('api/', include('formulas.urls')),
|
||||
]
|
||||
|
||||
if settings.DEBUG:
|
||||
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
@@ -0,0 +1,16 @@
|
||||
"""
|
||||
WSGI config for izaac2backend project.
|
||||
|
||||
It exposes the WSGI callable as a module-level variable named ``application``.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/5.2/howto/deployment/wsgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'izaac2backend.settings')
|
||||
|
||||
application = get_wsgi_application()
|
||||
Reference in New Issue
Block a user