Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Main #6

Merged
merged 2 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,5 @@ GitHub.sublime-settings

# private_key.pem
# public_key.pem

db.sqlite3
2 changes: 1 addition & 1 deletion apps/blog/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class HomePageView(TemplateView):
template_name = "blog/home.html"

def get(self, request):
if request.user and request.user.is_authenticated:
if request.user is not None and request.user.is_authenticated:
posts = Post.objects.exclude(author=request.user)
else:
posts = Post.objects.all()
Expand Down
File renamed without changes.
Empty file.
28 changes: 28 additions & 0 deletions apps/shared/management/commands/createadmin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import os

from dotenv import load_dotenv
load_dotenv()

from django.contrib.auth import get_user_model
from django.core.management.base import BaseCommand


ADMIN_USERNAME = str(os.getenv("ADMIN_USERNAME"))
ADMIN_PASSWORD = str(os.getenv("ADMIN_PASSWORD"))
ADMIN_EMAIL = str(os.getenv("ADMIN_PASSWORD"))


class Command(BaseCommand):
def handle(self, *args, **options):
User = get_user_model()
self.create_superuser(User, ADMIN_USERNAME, ADMIN_EMAIL, ADMIN_PASSWORD)
def create_superuser(self, User, username, email, password):
if not User.objects.filter(username=username).exists():
User.objects.create_superuser(username, email, password)
self.stdout.write(
self.style.SUCCESS(f"Superuser {username} created successfully.")
)
else:
self.stdout.write(
self.style.ERROR(f"Superuser {username} already exists.")
)
15 changes: 13 additions & 2 deletions apps/users/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,36 @@

class LoginForm(forms.Form):
username = forms.CharField(
max_length=28,
max_length=150,
widget=forms.TextInput(
attrs={"placeholder": "Username...", "class": "form-control rounded-4"}
),
error_messages={
"required": "Username is required!",
'max_length': "Username is too lang, max length is 150 charecters."
}
)
password = forms.CharField(
max_length=60,
widget=forms.PasswordInput(
attrs={"placeholder": "Password...", "class": "form-control rounded-4"}
),
error_messages={
"required": "Password is required!",
"max_length": "Password is to long, max length is 60 charecters."
}
)


class RegisterForm(forms.ModelForm):
password1 = forms.CharField(
label="Password",
max_length=28,
widget=forms.PasswordInput(attrs={"id": "password", "type": "password"}),

)
password2 = forms.CharField(
label="Password (Confirm)",
max_length=28,
widget=forms.PasswordInput(attrs={"id": "password", "type": "password"}),
)
Expand All @@ -39,7 +50,7 @@ def save(self, commit=True):
user.set_password(password1)
user.save()
else:
raise ValidationError("Password must be match")
return ValidationError("Passwords must be match!")

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
Expand Down
29 changes: 20 additions & 9 deletions apps/users/middleware.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from rest_framework_simplejwt.tokens import AccessToken
from rest_framework_simplejwt.tokens import AccessToken, TokenError
from django.utils.deprecation import MiddlewareMixin
from django.contrib.auth import get_user_model
from django.contrib.auth.models import AnonymousUser
from django.core.cache import cache


User = get_user_model()
Expand All @@ -10,11 +12,20 @@ class JWTAuthMiddleware(MiddlewareMixin):
def process_request(self, request):
access_token = request.COOKIES.get("access_token")

if access_token:
try:
token = AccessToken(access_token)
user_id = token['user_id']
request.user = User.objects.get(id=user_id)
except Exception as e:
request.user = None

if not access_token:
request.user = AnonymousUser()

cached_user = cache.get(access_token)
if cached_user:
request.user = cached_user
return

try:
token = AccessToken(access_token)
user_id = token['user_id']
user = User.objects.get(id=user_id)

cache.set(access_token, user, timeout=60 * 15)
request.user = user
except (TokenError, User.DoesNotExist):
request.user = AnonymousUser()
7 changes: 4 additions & 3 deletions apps/users/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ def get(self, request):

def post(self, request):

form = RegisterForm(request.POST, request.FILES)
form = RegisterForm(request.POST)

if form.is_valid():
form.save()
messages.success(request, "User succesfully registered")
return redirect(reverse("users:login"))

messages.warning(request, "Error registered!")
messages.warning(request, "Invalid registration fields!")
return render(request, "auth/register.html", {"form": form})


Expand All @@ -43,6 +43,7 @@ def post(self, request):
if form.is_valid():
username = form.cleaned_data.get("username")
password = form.cleaned_data.get("password")

user = authenticate(username=username, password=password)

if user is not None:
Expand All @@ -58,7 +59,7 @@ def post(self, request):
response.set_cookie("access_token", access_token, httponly=True)
response.set_cookie("refresh_token", refresh_token, httponly=True)

messages.info(request, f"You are logged in as { username }")
messages.success(request, f"You are logged in as { username }")
return response

else:
Expand Down
1 change: 1 addition & 0 deletions core/config/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@
"rest_framework",
"rest_framework_simplejwt",
"rest_framework_simplejwt.token_blacklist",

]
8 changes: 5 additions & 3 deletions core/config/jwt.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

from datetime import timedelta

from dotenv import load_dotenv
load_dotenv()

with open(str(os.getenv("PRIVATE_KEY_PATH", "security_settings/private_key.pem")), "r") as f:
with open(str(os.getenv("PRIVATE_KEY_PATH")), "r") as f:
PRIVATE_KEY = f.read()

with open(str(os.getenv("PUBLIC_KEY_PATH", "security_settings/public_key.pem")), "r") as f:
with open(str(os.getenv("PUBLIC_KEY_PATH")), "r") as f:
PUBLIC_KEY = f.read()


Expand All @@ -32,6 +34,6 @@
"TOKEN_TYPE_CLAIM": "token_type",
"JTI_CLAIM": "jti",
"SLIDING_TOKEN_REFRESH_EXP_CLAIM": "refresh_exp",
"SLIDING_TOKEN_LIFETIME": timedelta(minutes=5),
"SLIDING_TOKEN_LIFETIME": timedelta(seconds=1),
"SLIDING_TOKEN_REFRESH_LIFETIME": timedelta(days=1),
}
103 changes: 103 additions & 0 deletions core/settings/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import os

from pathlib import Path

from core.config import * # noqa

from dotenv import load_dotenv
load_dotenv()

BASE_DIR = Path(__file__).resolve().parent.parent.parent

SECRET_KEY = str(os.getenv("SECRET_KEY"))

DEBUG = bool(os.getenv("DEBUG", True))

ALLOWED_HOSTS = str(os.getenv("ALLOWED_HOSTS")).split(",")


INSTALLED_APPS = DEFAULT_APPS + PROJECT_APPS + THIRD_PARTY_APPS


MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"apps.users.middleware.JWTAuthMiddleware",
]

ROOT_URLCONF = "core.urls"


TEMPLATES_DIRS = ["templates"]

TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": TEMPLATES_DIRS,
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]


WSGI_APPLICATION = "core.wsgi.application"

DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
}
}


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",
},
]

LANGUAGE_CODE = "en"

TIME_ZONE = "Asia/Tashkent"

USE_I18N = True
# USE_L10N = True

USE_TZ = True

LOGIN_URL = "/users/login/"
LOGIN_REDIRECT_URL = "/"

STATIC_URL = "static/"
STATIC_ROOT = BASE_DIR / "staticfiles"
STATICFILES_DIRS = [BASE_DIR / "static"]

MEDIA_URL = "media/"
MEDIA_ROOT = BASE_DIR / "media/"

DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

AUTH_USER_MODEL = "users.User"

SITE_ID = 1
3 changes: 3 additions & 0 deletions core/settings/development.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .base import * # noqa

EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
28 changes: 28 additions & 0 deletions core/settings/production.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import os

from .base import * # noqa

EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
EMAIL_HOST = "'smtp.google.com'"
EMAIL_PORT = 587
EMAIL_HOST_USER = os.getenv("EMAIL_HOST_USER")
EMAIL_HOST_PASSWORD = os.getenv("EMAIL_HOST_PASSWORD")
EMAIL_USE_TLS = True

DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": str(os.getenv("POSTGRES_NAME")),
"USER": str(os.getenv("POSTGRES_USER")),
"PASSWORD": str(os.getenv("POSTGRES_PASSWORD")),
"HOST": str(os.getenv("POSTGRES_HOST")),
"PORT": int(os.getenv("POSTGRES_PORT"))
}
}

# CACHES = {
# "default": {
# "BACKEND": "django.core.cache.backends.redis.RedisCache",
# "LOCATION": os.getenv("REDIS_CACHE_URL"),
# },
# }
File renamed without changes.
2 changes: 1 addition & 1 deletion core/urls.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.conf.urls import handler400, handler403, handler404, handler500 # noqa
from django.conf.urls.static import static
from . import settings
from django.conf import settings

from django.contrib import admin
from django.urls import path, include
Expand Down
Binary file removed db.sqlite3
Binary file not shown.
8 changes: 7 additions & 1 deletion manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@
import os
import sys

from dotenv import load_dotenv
load_dotenv()

def main():
"""Run administrative tasks."""
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "core.settings")

os.environ.setdefault("DJANGO_SETTINGS_MODULE", os.getenv(
"DJANGO_SETTINGS_MODULE", "core.settings.development"
))

try:
from django.core.management import execute_from_command_line
except ImportError as exc:
Expand Down
Binary file not shown.
Loading
Loading