Как сделать страницу регистрации доступной только для вошедших в систему сотрудников в Django allauth?

Я очень новичок в Django.

Я использовал allauth, чтобы сделать проверку электронной почты и систему управления пользователями простой.

Я хочу систему, в которой только администраторы (штатные пользователи) могут регистрировать пользователей.

Но сейчас страница регистрации доступна только для не вошедших пользователей.

Как сделать страницу регистрации доступной только для вошедших пользователей в Django allauth?

Я надеюсь, вы имеете в виду, что хотите, чтобы только сотрудники могли создавать учетные записи пользователей и ограничить регистрацию для обычных пользователей, вы можете просто сделать это, создав представление user_create и проверив, имеет ли аутентифицированный пользователь роль "staff", чтобы использовать представление и удалив регистрацию из urls.py, также вы можете сделать это с помощью панели администратора Django, если вы уже разрешили сотрудникам использовать ее

Вы можете создать декоратор для проверки того, является ли пользователь администратором. Например, в файле под названием "decorators.py":

from functools import wraps
from django.http import HttpResponseRedirect

def admin_zone(view_func):
    def _decorator(request, *args, **kwargs):
        if request.user.is_staff:
            return view_func(request, *args, **kwargs)
        else:
            return HttpResponseRedirect('/') #If the user is not an admint, return him where you want...
    return wraps(view_func)(_decorator)

Для использования декоратора в урлах ваших аккаунтов вам понадобится сторонний плагин django-decorator-include https://github.com/twidi/django-decorator-include. Установите его:

pip install django-decorator-include

Теперь вы можете использовать свой декоратор из urls.py:

from django.contrib import admin
from django.urls import path
from .decorators import admin_zone
from decorator_include import decorator_include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('accounts/', decorator_include(admin_zone, 'allauth.urls')),
]

Итак, вы добавляете декоратор "admin_zone" ко всем урлам внутри "allauth.urls".

Я нашел некоторое решение или "обходной путь" для этого. Я не знаю, насколько оно хорошо или плохо, но, по крайней мере, оно работает так, как ожидалось.

Первый: Установите значение False в settings.py, чтобы пользователи не перенаправлялись автоматически в зависимости от того, вошли они в систему или нет. Это сделает форму регистрации и входа доступной для всех пользователей, независимо от того, вошли они в систему или нет.

ACCOUNT_AUTHENTICATED_LOGIN_REDIRECTS = False

**Второе: **Поместите в шаблон простую логику типа {% if user.is_staff %}, чтобы определить, кому можно показывать форму, а кому нет. Другие пользователи, посещающие страницу регистрации, не будут перенаправлены автоматически, но они увидят другую страницу. Вот пример:

{% extends "base.html" %}
{% load i18n %}
{% block head_title %}{% trans "Signup" %}{% endblock %}
{% block content %}
<br>THIS IS A CUSTOM TEMPLATE</br>
{% if user.is_authenticated and user.is_staff %}
<h1>{% trans "Sign Up" %}</h1>
<p>{% blocktrans %}Already have an account? Then please <a href="{{ login_url }}">sign in</a>.{% endblocktrans %}</p>
<form class="signup" id="signup_form" method="post" action="{% url 'account_signup' %}">
  {% csrf_token %}
  {{ form.as_p }}
  {% if redirect_field_value %}
  <input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
  {% endif %}
  <button type="submit">{% trans "Sign Up" %} &raquo;</button>
</form>
{% else %}
Only admins are allowed to register new users
{% endif %}
{% endblock %}

Третье: Затем немного измените функцию form_valid на SignUpview так, чтобы даже если пользователям удастся сделать форму и разместить регистрацию на странице, она не будет разрешена.

Вы просто добавляете эти две строки, чтобы функция выдавала ошибку, если пользователь не является сотрудником.

if not self.request.user.is_staff: # ADDED LINE 1: Check if User is staff
    raise Exception("Error: user is not staff") # ADDED LINE 2: Raise Exception

Вот как выглядит CustomSignupView:

from allauth.account.views import SignupView

from django.utils.decorators import method_decorator
from django.views.decorators.debug import sensitive_post_parameters

from allauth.exceptions import ImmediateHttpResponse

from allauth.account import app_settings

from allauth.account.utils import (
    complete_signup
)

INTERNAL_RESET_SESSION_KEY = "_password_reset_key"


sensitive_post_parameters_m = method_decorator(
    sensitive_post_parameters("oldpassword", "password", "password1", "password2")
)

class AccountSignupView(SignupView):

    def form_valid(self, form):
        # By assigning the User to a property on the view, we allow subclasses
        # of SignupView to access the newly created User instance
        if not self.request.user.is_staff: # ADDED LINE 1: Check if User is staff
            raise Exception("Error: user is not staff") # ADDED LINE 2: Raise Exception
        self.user = form.save(self.request)
        try:
            return complete_signup(
                self.request,
                self.user,
                app_settings.EMAIL_VERIFICATION,
                self.get_success_url(),
            )
        except ImmediateHttpResponse as e:
            return e.response

account_signup_view = AccountSignupView.as_view()

И вы, вероятно, знаете, что этот путь нужно указать и в urls.py перед путем к include(allauth.urls). У меня allauth был на уровне проекта, поэтому урлы находятся в urls.py.

path("accounts/signup/", view=views.account_signup_view)

Я не знаю, насколько безопасно или хорошо это решение, но, по крайней мере, оно не позволяет всем пользователям использовать форму регистрации и разрешает только штатным пользователям. Если вы нажмете CTRL + клик на классе или функции, или посетите его страницу на GitHub, вы сможете найти его исходный код, изучить, как он работает, скопировать, вставить и изменить его.

from django.contrib.auth.mixins import UserPassesTestMixin

Создайте свои представления здесь.

class AccountSignupView(UserPassesTestMixin, SignupView):

template_name = "users/signup.html"

def test_func(self):
    return self.request.user.is_staff

Use the built in django UserPassesTestMixin to achieve this 
Вернуться на верх