Skip to content
Open
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: 1 addition & 1 deletion api/admin.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from django.contrib import admin

# Register your models here.
# Register your models here.
2 changes: 1 addition & 1 deletion api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,4 @@ class Meta:
ordering = ('-pub_date',)

def __str__(self):
return self.text
return self.text
2 changes: 1 addition & 1 deletion api/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ def has_object_permission(self, request, view, obj):
or request.user.role == CustomUser.ROLE_MODERATOR
)

return request.method in permissions.SAFE_METHODS
return request.method in permissions.SAFE_METHODS
2 changes: 1 addition & 1 deletion api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ class CommentSerializer(serializers.ModelSerializer):

class Meta:
fields = ('id', 'text', 'author', 'pub_date')
model = Comment
model = Comment
2 changes: 1 addition & 1 deletion api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@

urlpatterns = [
path('v1/', include(router.urls)),
]
]
2 changes: 1 addition & 1 deletion api/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
def score_validator(value):
if not 1 <= value <= 10:
params = {'value': value, }
raise ValidationError('Оценка может быть от 1 до 10', params=params)
raise ValidationError('Оценка может быть от 1 до 10', params=params)
2 changes: 1 addition & 1 deletion api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ def perform_create(self, serializer):

def get_queryset(self):
review = get_object_or_404(Review, pk=self.kwargs.get('review_id'))
return review.comments.all()
return review.comments.all()
2 changes: 1 addition & 1 deletion api_users_auth/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def authenticate(self, request, username=None, password=None, **kwargs):
if user.check_password(password):
return user
return None

def get_user(self, user_id):
try:
return CustomUser.objects.get(pk=user_id)
Expand Down
10 changes: 3 additions & 7 deletions api_users_auth/models.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from django.contrib.auth.models import AbstractUser
from django.db import models
from rest_framework import permissions


class CustomUser(AbstractUser):
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username',]
REQUIRED_FIELDS = ['username', ]
ROLE_USER = 'user'
ROLE_MODERATOR = 'moderator'
ROLE_ADMIN = 'admin'
Expand All @@ -17,15 +17,14 @@ class CustomUser(AbstractUser):
choices=USERS_ROLE,
max_length=10,
verbose_name='Роль пользователя',
default='user'
default=ROLE_USER
)
email = models.EmailField('e-mail', unique=True, blank=False)
bio = models.TextField(
max_length=500,
blank=True,
null=True,
)
confirmation_code = models.TextField(null=True, default='')

@property
def is_admin(self):
Expand All @@ -42,9 +41,6 @@ class Meta:
ordering = ['id']





class ConfirmationCode(models.Model):
confirmation_code = models.CharField(max_length=32)
email = models.EmailField(max_length=254, unique=True)
Expand Down
41 changes: 1 addition & 40 deletions api_users_auth/permissions.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,5 @@
from rest_framework import permissions

from .models import CustomUser


class IsAuthorOrStaffOrReadOnly(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
return (request.method in permissions.SAFE_METHODS
or obj.author == request.user
or request.user.is_admin
or request.user.is_moderator)
"""

class IsAdminOrReadOnly(permissions.BasePermission):
def has_permission(self, request, view):
return (request.method in permissions.SAFE_METHODS
or request.user.is_authenticated
and request.user.is_admin
or request.user.is_superuser
)
"""

class IsSuperuser(permissions.BasePermission):

Expand All @@ -31,24 +12,4 @@ class IsAdminRole(permissions.BasePermission):
def has_permission(self, request, view):
if request.user.is_anonymous:
return request.user.is_staff
return (request.user.is_superuser
or request.user.is_admin
)

"""
def has_object_permission(self, request, view, obj):
return request.user.is_authenticated and request.user.is_admin

def has_permission(self, request, view):
return request.user.is_authenticated and request.user.is_admin

def has_delete_permission(self, request):
if request.user.is_admin:
return False

def has_object_permission(self, request, view, obj):
return (
request.method in permissions.SAFE_METHODS
or obj.author == request.user
)
"""
return (request.user.is_superuser or request.user.is_admin)
17 changes: 11 additions & 6 deletions api_users_auth/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,28 @@
class CustomUserSerializer(serializers.ModelSerializer):
username = serializers.CharField(
required=True,
validators=[validators.UniqueValidator(queryset=CustomUser.objects.all())]
validators=[validators.UniqueValidator(
queryset=CustomUser.objects.all()
)]
)

class Meta:
fields = ['first_name', 'last_name', 'username', 'bio', 'email', 'role']
fields = [
'first_name', 'last_name', 'username', 'bio', 'email', 'role'
]
model = CustomUser


class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
class TokenObtainPairSerializer(TokenObtainPairSerializer):
username_field = CustomUser.email

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['password'].required = False
self.fields['password'].required = False

def validate(self, attrs):
attrs['password'] = self.context['request'].data.get('confirmation_code')
password = self.context['request'].data.get('confirmation_code')
attrs['password'] = password
return super().validate(attrs)


Expand All @@ -39,7 +44,7 @@ class ConfirmationCodeSerializer(serializers.Serializer):
many=False,
read_only=True
)
code_date = serializers.DateTimeField()
code_date = serializers.DateTimeField()

class Meta:
fields = '__all__'
Expand Down
29 changes: 18 additions & 11 deletions api_users_auth/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,25 @@

from .views import UserViewSet, MyTokenObtainPairView, get_confirmation_code

API_VER = 'v1'


router = DefaultRouter()
router.register(r'users', UserViewSet, basename='users')
router_v1 = DefaultRouter()
router_v1.register(r'users', UserViewSet, basename='users')

urlpatterns = [
path(f'{API_VER}/', include(router.urls)),
path(f'{API_VER}/auth/email/', get_confirmation_code, name='get_confirmation_code'),
path(f'{API_VER}/auth/token/',
MyTokenObtainPairView.as_view(),
name='token_obtain_pair'
),
path('{API_VER}/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
path('v1/', include(router_v1.urls)),
path(
'v1/auth/email/',
get_confirmation_code,
name='get_confirmation_code'
),
path(
'v1/auth/token/',
MyTokenObtainPairView.as_view(),
name='token_obtain_pair'
),
path(
'v1/token/refresh/',
TokenRefreshView.as_view(),
name='token_refresh'
),
]
50 changes: 23 additions & 27 deletions api_users_auth/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@

from django.core.mail import send_mail
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import serializers, status, viewsets
from rest_framework import viewsets
from rest_framework.decorators import api_view, action
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework_simplejwt.views import TokenObtainPairView

from api_yamdb.settings import ADMIN_EMAIL
from .models import ConfirmationCode, CustomUser
from .permissions import IsAdminRole, IsAuthorOrStaffOrReadOnly, IsSuperuser
from .permissions import IsAdminRole, IsSuperuser
from .serializers import (ConfirmationCodeSerializer, CustomUserSerializer,
MyTokenObtainPairSerializer)
TokenObtainPairSerializer)


class HttpResponseUnauthorized(HttpResponse):
Expand All @@ -30,9 +30,9 @@ class UserViewSet(viewsets.ModelViewSet):
lookup_field = 'username'

@action(detail=False,
methods=['GET', 'PATCH'],
permission_classes = (IsAuthenticated,)
)
methods=['GET', 'PATCH'],
permission_classes=(IsAuthenticated,)
)
def me(self, request):
user = self.request.user
serializer = self.get_serializer(
Expand All @@ -46,30 +46,26 @@ def me(self, request):


class MyTokenObtainPairView(TokenObtainPairView):
serializer_class = MyTokenObtainPairSerializer
serializer_class = TokenObtainPairSerializer


@api_view(['POST'])
def get_confirmation_code(request):
print('request:', request)
serializer = ConfirmationCodeSerializer(data=request.data)
print('serializer = ', serializer)
if not serializer.is_valid():
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
serializer.is_valid(raise_exception=True)
user_email = serializer.validated_data['email']
#user = CustomUser.objects.get_or_create(username='username', user_email='email')
confirmation_code = str(uuid.uuid4())
if confirmation_code is not None:
send_mail(
'Your confirmation code',
confirmation_code,
'nemykin.eu@yandex.ru',
[user_email],
fail_silently=False,
)
ConfirmationCode.objects.create(
email=user_email,
confirmation_code=confirmation_code
)
return HttpResponse(f'Confirmation code was sent to your email')
return HttpResponseUnauthorized()
if confirmation_code is None:
return HttpResponseUnauthorized()
send_mail(
'Your confirmation code',
confirmation_code,
ADMIN_EMAIL,
[user_email],
fail_silently=False,
)
ConfirmationCode.objects.create(
email=user_email,
confirmation_code=confirmation_code
)
return HttpResponse('Confirmation code was sent to your email')
12 changes: 4 additions & 8 deletions api_yamdb/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,22 +128,18 @@
# Добавлено EugeneN
AUTH_USER_MODEL = 'api_users_auth.CustomUser'

# Добавлено EugeneN
#AUTHENTICATION_BACKENDS = ['core.authentication.EmailBackend']

AUTHENTICATION_BACKENDS = [
#'core.authentication.Emailbackend',
'django.core.mail.backends.console.EmailBackend',
#'api_users_auth.backends.EmailBackend'
#'django.contrib.auth.backends.ModelBackend',
]

# Добавлено EugeneN
# подключаем движок filebased.EmailBackend
EMAIL_BACKEND = "django.core.mail.backends.filebased.EmailBackend"
EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'

ADMIN_EMAIL = 'nemykin.eu@yandex.ru'

# указываем директорию, в которую будут складываться файлы писем
EMAIL_FILE_PATH = os.path.join(BASE_DIR, "sent_emails")
EMAIL_FILE_PATH = os.path.join(BASE_DIR, 'sent_emails')

REST_AUTH_SERIALIZERS = {
'USER_DETAILS_SERIALIZER': 'api_users_auth.serializers.CustomUserSerializer',
Expand Down
15 changes: 10 additions & 5 deletions api_yamdb/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
from rest_framework_simplejwt.views import (TokenObtainPairView,
TokenRefreshView)

#from allauth.account.views import confirm_email
#from django.conf.urls import url


urlpatterns = [
path('admin/', admin.site.urls),
Expand All @@ -16,8 +13,16 @@
TemplateView.as_view(template_name='redoc.html'),
name='redoc'
),
path('api/v1/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/v1/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
path(
'api/v1/token/',
TokenObtainPairView.as_view(),
name='token_obtain_pair'
),
path(
'api/v1/token/refresh/',
TokenRefreshView.as_view(),
name='token_refresh'
),
path('api/', include('api.urls')),
path('api/', include('titles.urls')),
]
2 changes: 1 addition & 1 deletion titles/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ class TitleFilter(filters.FilterSet):

class Meta:
model = Title
fields = ['name', 'category', 'genre', 'year']
fields = ['name', 'category', 'genre', 'year']
2 changes: 1 addition & 1 deletion titles/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ class TitleSerializer(serializers.ModelSerializer):

class Meta:
model = Title
fields = ('id', 'name', 'year', 'description', 'genre', 'category',)
fields = ('id', 'name', 'year', 'description', 'genre', 'category',)
2 changes: 1 addition & 1 deletion titles/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@

urlpatterns = [
path('v1/', include(router_v1.urls))
]
]
Loading