Skip to content

Commit

Permalink
added account creation and approval via email
Browse files Browse the repository at this point in the history
  • Loading branch information
fivan999 committed Feb 24, 2024
1 parent 8fc777e commit 62218d4
Show file tree
Hide file tree
Showing 28 changed files with 426 additions and 16 deletions.
15 changes: 14 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,17 @@ DJANGO_SECRET_KEY=secret
DJANGO_DEBUG=true
DJANGO_ALLOWED_HOSTS=127.0.0.1
DJANGO_INTERNAL_IPS=127.0.0.1
ELASTIC_PASSWORD=aboba
ALGOLIA_API_KEY=d83f046293d353948ce4a0c31ac5a10f
ALGOLIA_APPLICATION_ID=7KSTYUMEXE
CELERY_TASK_ALWAYS_EAGER=true
RABBITMQ_HOST=localhost
RABBITMQ_USER=guest
RABBITMQ_PASS=password
USER_IS_ACTIVE=true
USE_SMTP=true
EMAIL_HOST=example
EMAIL_PORT=example
EMAIL_USE_TLS=true
EMAIL_USER_SSL=false
EMAIL_HOST_USER=example
EMAIL_HOST_PASSWORD=example
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,5 @@ cython_debug/
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

sent_emails/
File renamed without changes.
9 changes: 9 additions & 0 deletions backend/cfehome/api/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import django.apps


class ApiConfig(django.apps.AppConfig):
"""баззовый класс прилложения api"""

default_auto_field = 'django.db.models.BigAutoField'
name = 'api'
verbose_name = 'апи'
7 changes: 7 additions & 0 deletions backend/cfehome/api/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import django.urls


urlpatterns = [
django.urls.path('', django.urls.include('products.urls')),
django.urls.re_path('auth/', django.urls.include('users.urls')),
]
11 changes: 11 additions & 0 deletions backend/cfehome/cfehome/celery.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import os

import celery

import django.conf


os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'cfehome.settings')
app = celery.Celery('cfehome', broker=django.conf.settings.CELERY_BROKER_URL)
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()
43 changes: 41 additions & 2 deletions backend/cfehome/cfehome/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@
'django.contrib.staticfiles',
'algoliasearch_django',
'rest_framework',
'rest_framework.authtoken',
'rest_framework_simplejwt',
'corsheaders',
'djoser',
'products.apps.ProductsConfig',
'users.apps.UsersConfig',
'search.apps.SearchConfig',
'api.apps.ApiConfig',
]

MIDDLEWARE = [
Expand All @@ -59,7 +60,7 @@
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'DIRS': [BASE_DIR / 'templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
Expand Down Expand Up @@ -117,6 +118,10 @@

AUTH_USER_MODEL = 'users.User'

USER_IS_ACTIVE = (
os.getenv('USER_IS_ACTIVE', default='true').lower().strip() in YES_OPTIONS
)

REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
Expand All @@ -141,3 +146,37 @@
'https://localhost:8111',
]
CORS_URLS_REGEX = r"^/api/.*$"

CELERY_TASK_ALWAYS_EAGER = (
os.getenv('CELERY_TASK_ALWAYS_EAGER', default='true').lower().strip()
in YES_OPTIONS
)

RABBITMQ_HOST = os.getenv('RABBITMQ_HOST', default='localhost')
RABBITMQ_USER = os.getenv('RABBITMQ_USER', default='guest')
RABBITMQ_PASS = os.getenv('RABBITMQ_PASS', default='password')
CELERY_BROKER_URL = (
f'amqp://{RABBITMQ_USER}:{RABBITMQ_PASS}@{RABBITMQ_HOST}:5672//'
)

if os.getenv('USE_SMTP', default='False').lower() in YES_OPTIONS:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = os.getenv('EMAIL_HOST')
EMAIL_PORT = os.getenv('EMAIL_PORT')
EMAIL_USE_TLS = (
os.getenv('EMAIL_USE_TLS', default='true').lower() in YES_OPTIONS
)
EMAIL_USE_SSL = (
os.getenv('EMAIL_USER_SSL', default='false').lower() in YES_OPTIONS
)
if EMAIL_USE_TLS:
EMAIL_USE_SSL = False
if EMAIL_USE_SSL:
EMAIL_USE_TLS = False
EMAIL_HOST_USER = os.getenv('EMAIL_HOST_USER')
EMAIL_HOST_PASSWORD = os.getenv('EMAIL_HOST_PASSWORD')
SERVER_EMAIL = EMAIL_HOST_USER
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
else:
EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
EMAIL_FILE_PATH = BASE_DIR / 'sent_emails'
10 changes: 9 additions & 1 deletion backend/cfehome/cfehome/test_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
'products.apps.ProductsConfig',
'users.apps.UsersConfig',
'search.apps.SearchConfig',
'api.apps.ApiConfig',
]

MIDDLEWARE = [
Expand All @@ -42,7 +43,7 @@
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'DIRS': [BASE_DIR / 'templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
Expand Down Expand Up @@ -124,3 +125,10 @@
'https://localhost:8111',
]
CORS_URLS_REGEX = r"^/api/.*$"

CELERY_TASK_ALWAYS_EAGER = True

USER_IS_ACTIVE = True

EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
EMAIL_FILE_PATH = BASE_DIR / 'sent_emails'
3 changes: 1 addition & 2 deletions backend/cfehome/cfehome/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@

urlpatterns = [
django.urls.path('admin/', django.contrib.admin.site.urls),
django.urls.path('api/', django.urls.include('products.urls')),
django.urls.path('api/auth/', django.urls.include('users.urls')),
django.urls.path('api/', django.urls.include('api.urls')),
]

if django.conf.settings.DEBUG:
Expand Down
5 changes: 4 additions & 1 deletion backend/cfehome/products/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
class ProductAdmin(django.contrib.admin.ModelAdmin):
"""отображение модели Product в админке"""

list_display = ('id', 'title')
list_display = (
'id',
'title',
)
list_display_links = ('id',)
list_editable = ('title',)
9 changes: 9 additions & 0 deletions backend/cfehome/templates/users/emails/activate_user.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{% autoescape off %}
Здравствуйте, {{ username }}
Чтобы активировать свой аккаунт, пожалуйста, пройдите по ссылке ниже:

{{ protocol }}://{{ domain }}{% url where_to uidb64=uid token=token %}

С уважением,
Администрация сайта bebrochka.ru
{% endautoescape %}
7 changes: 4 additions & 3 deletions backend/cfehome/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from tests.fixtures.auth import (
from backend.cfehome.tests.fixtures.users import (
create_simple_user1,
create_simple_user2,
create_superuser,
create_superuser
)

from tests.fixtures.products import (
create_private_product,
create_public_product,
create_public_product
)
3 changes: 2 additions & 1 deletion backend/cfehome/tests/fixtures/products.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import pytest
import tests.utils.utils

import django.urls

import tests.utils.utils


@pytest.fixture
def create_public_product(create_simple_user1) -> int:
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion backend/cfehome/tests/products/test_products.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import pytest
import rest_framework.test
import tests.utils.utils

import django.urls

import products.models
import tests.utils.utils


@pytest.mark.django_db
Expand Down
Empty file.
File renamed without changes.
16 changes: 15 additions & 1 deletion backend/cfehome/users/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,21 @@
class UserAdmin(django.contrib.auth.admin.UserAdmin):
"""отображение модели пользователя в админке"""

...
list_display = (
'pk',
'username',
'email',
'is_active',
'is_superuser',
)
list_display_links = (
'pk',
'username',
)
list_filter = (
'is_active',
'is_superuser',
)


django.contrib.admin.site.register(users.models.User, UserAdmin)
2 changes: 1 addition & 1 deletion backend/cfehome/users/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@


class UsersConfig(django.apps.AppConfig):
"""базовый класс приложения Users"""
"""базовый класс приложения Auth"""

default_auto_field = 'django.db.models.BigAutoField'
name = 'users'
Expand Down
19 changes: 19 additions & 0 deletions backend/cfehome/users/migrations/0003_alter_user_email.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 4.2 on 2024-02-24 19:15

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
('users', '0002_alter_user_options'),
]

operations = [
migrations.AlterField(
model_name='user',
name='email',
field=models.EmailField(
max_length=254, verbose_name='email address'
),
),
]
6 changes: 6 additions & 0 deletions backend/cfehome/users/models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import django.contrib.auth.models
import django.db.models
from django.utils.translation import gettext_lazy as _

import users.managers

Expand All @@ -8,6 +10,10 @@ class User(django.contrib.auth.models.AbstractUser):

objects = users.managers.UserManager()

email = django.db.models.EmailField(
verbose_name=_('email address'), unique=True
)

class Meta(django.contrib.auth.models.AbstractUser.Meta):
db_table = 'auth_user'
swappable = 'AUTH_USER_MODEL'
Expand Down
36 changes: 36 additions & 0 deletions backend/cfehome/users/permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import rest_framework.permissions

import django.http

import users.models


class IsAdminOrIsSelf(rest_framework.permissions.BasePermission):
"""
проверяем возможность пользователя смотреть,
редактировать и изменять пользователя
"""

methods = {
'PUT': 'change',
'PATCH': 'change',
'DELETE': 'delete',
'GET': 'view',
}

def has_object_permission(
self,
request: django.http.HttpRequest,
view: rest_framework.views.APIView,
obj: users.models.User,
):
user = request.user
if not user:
return False
if (
user.pk == obj.pk
or user.is_staff
and user.has_perm(f'users.{self.methods[request.method]}_user')
):
return True
return False
Loading

0 comments on commit 62218d4

Please sign in to comment.