diff --git a/access_controller/auth.py b/access_controller/auth.py new file mode 100644 index 0000000..be707e1 --- /dev/null +++ b/access_controller/auth.py @@ -0,0 +1,19 @@ +from django.contrib.auth.backends import ModelBackend +from django.contrib.auth.models import User + + +class EmailAuthBackend(ModelBackend): + def authenticate(self, request, username=None, password=None, **kwargs): + try: + user = User.objects.get(email=username) + if user.check_password(password): + return user + return None + except User.DoesNotExist: + return None + + def get_user(self, user_id): + try: + return User.objects.get(pk=user_id) + except User.DoesNotExist: + return None diff --git a/access_controller/settings.py b/access_controller/settings.py index 480cfbd..8b4ec96 100644 --- a/access_controller/settings.py +++ b/access_controller/settings.py @@ -135,6 +135,12 @@ ACCOUNT_ACTIVATION_DAYS = 7 LOGIN_REDIRECT_URL = '/' LOGOUT_REDIRECT_URL = '/' + +# Название_приложения.Название_файла.Название_класса_обработчика +AUTHENTICATION_BACKENDS = [ + 'access_controller.auth.EmailAuthBackend', +] + # Logging system # https://docs.djangoproject.com/en/3.1/topics/logging/ LOGGING = { diff --git a/access_controller/urls.py b/access_controller/urls.py index 45781bf..b91e747 100644 --- a/access_controller/urls.py +++ b/access_controller/urls.py @@ -14,17 +14,18 @@ Including another URLconf 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin +from django.contrib.auth.forms import AuthenticationForm from django.contrib.auth.views import LoginView from django.contrib.auth import views as auth_views from django.urls import path, include -from main.views import main_page, profile_page, CustomRegistrationView +from main.views import main_page, profile_page, CustomRegistrationView, CustomLoginView urlpatterns = [ path('admin/', admin.site.urls, name='admin'), path('', main_page, name='index'), path('accounts/profile/', profile_page, name='profile'), path('accounts/register/', CustomRegistrationView.as_view(), name='registration'), - path('accounts/login/', LoginView.as_view(extra_context={}), name='login'), # TODO add extra context + path('accounts/login/', CustomLoginView.as_view(extra_context={}), name='login',), # TODO add extra context path('accounts/', include('django.contrib.auth.urls')), path('accounts/', include('django_registration.backends.activation.urls')), path('accounts/login/', include('django.contrib.auth.urls')), diff --git a/main/extra_func.py b/main/extra_func.py index 9e0a564..3ce296a 100644 --- a/main/extra_func.py +++ b/main/extra_func.py @@ -26,6 +26,12 @@ class ZendeskAdmin: email = os.getenv('ACCESS_CONTROLLER_API_EMAIL') token = os.getenv('ACCESS_CONTROLLER_API_TOKEN') password = os.getenv('ACCESS_CONTROLLER_API_PASSWORD') + _instance=None + + def __new__(cls, *args, **kwargs): + if cls._instance is None: + cls._instance = super().__new__(cls) + return cls._instance def __init__(self): self.create_admin() @@ -73,10 +79,7 @@ class ZendeskAdmin: def get_user_image(self, email: str) -> str: """ - Функция **get_user_image** возвращает аватар пользователя - - :param user_image: Аватар пользователя - :type user_image: :class:`img` + Функция **get_user_image** возвращает url-ссылку на аватар пользователя """ user = self.admin.users.search(email).values[0] return user.photo['content_url'] if user.photo else None @@ -86,7 +89,7 @@ class ZendeskAdmin: def get_user_org(self, email: str) -> str: user = self.admin.users.search(email).values[0] - return user.organization.name + return user.organization.name def create_admin(self) -> None: """ @@ -140,7 +143,7 @@ def check_user_exist(email: str) -> bool: return ZendeskAdmin().check_user(email) -def get_user_organization(email: str) -> bool: +def get_user_organization(email: str) -> str: """ Функция возвращает организацию пользователя diff --git a/main/forms.py b/main/forms.py index 6a058bb..e33e1ae 100644 --- a/main/forms.py +++ b/main/forms.py @@ -1,4 +1,5 @@ from django import forms +from django.contrib.auth.forms import AuthenticationForm from django_registration.forms import RegistrationFormUniqueEmail @@ -6,11 +7,7 @@ class CustomRegistrationForm(RegistrationFormUniqueEmail): """ Форма для регистрации :class:`django_registration.forms.RegistrationFormUniqueEmail` с добавлением bootstrap-класса 'form-control' - - :param password_zen: Поле для ввода пароля от Zendesk - :type password_zen: :class:`django.forms.CharField` """ - def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) for visible in self.visible_fields(): @@ -24,3 +21,21 @@ class CustomRegistrationForm(RegistrationFormUniqueEmail): class Meta(RegistrationFormUniqueEmail.Meta): fields = RegistrationFormUniqueEmail.Meta.fields + + +class CustomAuthenticationForm(AuthenticationForm): + """ + Форма для авторизации :class:`django.contrib.auth.forms.AuthenticationForm` + с изменением поля username на email + """ + username = forms.CharField( + label="Электронная почта", + widget=forms.EmailInput(), + ) + error_messages = { + 'invalid_login': + "Пожалуйста, введите правильные электронную почту и пароль. Оба поля " + "могут быть чувствительны к регистру." + , + 'inactive': "Аккаунт не активен.", + } diff --git a/main/views.py b/main/views.py index a73017f..8fb892a 100644 --- a/main/views.py +++ b/main/views.py @@ -1,18 +1,17 @@ +import logging + from django.contrib.auth.decorators import login_required from django.contrib.auth.forms import PasswordResetForm from django.contrib.auth.models import User from django.contrib.auth.tokens import default_token_generator +from django.contrib.auth.views import LoginView from django.shortcuts import render from django.urls import reverse_lazy -from django_registration.backends.one_step.views import RegistrationView +from django_registration.views import RegistrationView from access_controller.settings import EMAIL_HOST_USER from main.extra_func import check_user_exist, update_profile, get_user_organization -from main.forms import CustomRegistrationForm -from django_registration.views import RegistrationView -from django.contrib.auth.decorators import login_required -import logging - +from main.forms import CustomRegistrationForm, CustomAuthenticationForm class CustomRegistrationView(RegistrationView): @@ -89,3 +88,10 @@ def main_page(request): logger = logging.getLogger('main.index') logger.info('Index page opened') return render(request, 'pages/index.html') + + +class CustomLoginView(LoginView): + """ + Отображение страницы авторизации пользователя + """ + form_class = CustomAuthenticationForm