Рубрики
Без рубрики

Настройка API отдыха Django с пользовательской моделью пользователя и тестами

Подготовьтесь к изменениям, построение для гибкости. Помечено Python, Django, безопасность.

В этой короткой серии статей я хотел бы поделиться тем, как реализовать гранулированные, контроль доступа на основе ролей ресурсов в Django. Мы построим API для отдыха, которая возвращает 401-е годы (несанкционированные) для неавторизованных пользователей, 404S для аутентифицированных пользователей, не разрешенных для просмотра данных ресурсов, и 403s (запрещенных) для пользователей, уполномоченных для просмотра ресурсов, но запрещено выполнять заданные действия.

Мы будем использовать ваниль Джанго без дополнительных рамок или зависимостей во всем. Это не значит, что вы не должны использовать публично доступные пакеты, но придерживаясь чистого Django – хороший выбор, когда вы хотите изучать вещи и когда вам нужна самая гибкость. Помните, однако, что аутентификация пользователя – это одно место, где вы не хотите беспорядок: чем больше пишет код, лучший тестовый люкс, который вам понадобится!

В этой части один мы настроим проект Django и приложение для нашего API для отдыха. Мы добавим пользовательскую модель пользователей и простые тесты. Вы можете найти сопроводительный код В этом репозитории Отказ

Создание проекта и приложения

Для начала давайте создадим новую папку и виртуальную среду. Я использую Пьенв Виртуальский Создать виртуальную среду:

$ mkdir django-rbac && cd django-rbac
$ pyenv virtualenv 3.8.1 django-rbac-3.8.1
$ pyenv local django-rbac.3.8.1

Давайте установим Django и создать проект под названием rbac. :

# django-rbac/
$ printf "django==3.1.7\n" > requirements.txt
$ pip install -r requirements.txt
$ django-admin startproject rbac .

Модифицировать settings.py Так что он содержит только приложения и HedmostWares, нам нужно:

# rbac/settings.py
INSTALLED_APPS = [
    'rbac.core',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
]

Мы создадим rbac.Core приложение вскоре ниже. Мы используем Django’s Система аутентификации Для аутентификации пользователей, который требует от нас, чтобы включить django.contrib.auth приложение и django.contrib.auth.middleware. Аутентификация Moddleware промежуточное ПО. Нам тоже нужно django.contrib.sessions приложение и Sessionmiddleware для управления пользовательскими сессиями. Мы также включаем Commonmiddleware и SecurityMiddleware Даже если не строго требуется.

Наши взгляды и модели будут жить под Core приложение. Давайте создадим такое приложение и переместите его под rbac. :

$ python manage.py startapp core
$ mv core rbac/

Я перемещаю приложение под проектом, чтобы все осталось в одном месте. Я не ожидаю, что добавлять какие-либо дополнительные приложения, так как несколько приложений могут привести к проблемам дальше вниз по дороге.

Давайте модифицируем Apps.py В приложении использовать имя rbac.Core вместо основной :

# rbac/core/apps.py
class CoreConfig(AppConfig):
    name = 'rbac.core'

Теперь давайте построим все для нашей первой конечной точки Получить/ Отказ Вот простой вид для приложения:

# rbac/core/views.py
from django.http import HttpResponse


def index(request):
    return HttpResponse("Hello, world. You're at the core index.")

Установите URL, чтобы указать на вид:

# rbac/core/urls.py
from django.urls import path

from rbac.core import views

urlpatterns = [
    path('', views.index)
]

Установка URL в проекте, чтобы указать на наше новое приложение:

# rbac/urls.py
from django.urls import include, path

urlpatterns = [
    path('', include('rbac.core.urls')),
]

Проект и приложение теперь установлены. Прежде чем двигаться дальше, давайте создадим пользовательскую модель для пользователей.

Пользовательская модель пользователя

В Django всегда хорошая идея создать пользовательскую модель для пользователей. Трудно изменить модель пользователя позже, и это не так много работы, чтобы катить собственную модель. Пользовательская модель дает наибольшую гибкость позже.

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

# rbac/settings.py
AUTHENTICATION_BACKENDS = ['django.contrib.auth.backends.ModelBackend']
AUTH_USER_MODEL = 'core.User'

Теперь мы создаем нашу пользовательскую модель пользователей в Models.py Определение Пользователь и Усманагеру :

# rbac/core/models.py
import uuid

from django.db import models
from django.contrib.auth.models import (
    AbstractBaseUser, BaseUserManager
)

class UserManager(BaseUserManager):
    def create_user(self, email, name, password=None):
        """
        Create and save a user with the given email, name and password.
        """
        if not email:
            raise ValueError('Users must have an email address')

        user = self.model(
            email=self.normalize_email(email),
            name=name
        )

        user.set_password(password)
        user.save()
        return user

class User(AbstractBaseUser):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    email = models.EmailField(
        verbose_name='email address',
        max_length=255,
        unique=True,
    )

    name = models.CharField(max_length=32, blank=False, null=False)
    is_active = models.BooleanField(default=True)

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['name']

    def __str__(self):
        return self.email

Я не буду пытаться объяснить это подробно, как вы можете найти полный пример здесь В документации Django. Наше Пользователь имеет поля Эл. адрес и имя . Поле Email Должен быть уникальным, и мы используем это как наше имя пользователя. Мы используем UUID в качестве первичного ключа во всех моделях, которые мы создаем. Мы также создаем наших собственных Упреждающий что мы можем использовать для создания новых пользователей как User.Objects.create_user (Email = Email ,,,) Отказ

Теперь давайте создадим нашу первую миграцию для создания модели пользователя в базе данных:

$ python manage.py makemigrations

На данный момент вы можете настроить вашу базу данных. Мы будем использовать sqlite3. В этой статье для простоты. Посмотреть Эта статья Как настроить Django, чтобы использовать базу данных Postgres и как настроить простую конечную точку для проверки здоровья.

Попробуйте это

Давайте запустим наш сервер:

$ python manage.py runserver

Откройте вкладку «Другой терминал» и сделайте запрос на свой сервер в http://localhost: 8000 :

$ curl http://localhost:8000
Hello, world. You're at the core index.

Создание сервисного слоя

Мы создаем сервисный слой, чтобы добавить развязку между просмотрами и моделями, как предложено В этой статье Отказ Такой развязный слой помогает хранить модели Lean и все деловую логику в одном месте. Услуги также очень полезны для тестирования, так как мы можем создавать ресурсы с услугами аналогичным образом, поскольку реальные пользователи будут делать.

Давайте создадим услуги для создания пользователей и поиск пользователей:

# rbac/core/services.py
import typing

from rbac.core.models import User

def create_user(email: str, name: str, password: str) -> User:
    return User.objects.create_user(email=email, name=name, password=password)

def find_user_by_email(email: str) -> typing.Optional[User]:
    try:
        return User.objects.get(email=email)
    except User.DoesNotExist:
        return None

Добавление тестов

Теперь мы можем сделать Очень важно предмет Мы знаем, что каждый разработчик должен делать и добавлять тесты для нашего проекта. Давайте сначала установим pteest и pytest-django :

$ printf "pytest\npytest-django\n" > requirements-dev.txt
$ pip install -r requirements-dev.txt

Настроить Pytest.ini :

# pytest.ini
[pytest]
DJANGO_SETTINGS_MODULE = rbac.settings

Давайте создадим простой тест для создания пользователя:

# tests/test_services.py
import pytest

from rbac.core.services import create_user, find_user_by_email

@pytest.mark.django_db
def test_create_user():
    email = "test@example.com"
    name = "Jane Doe"
    password = "some-clever-password"

    user = create_user(email=email, name=name, password=password)

    assert user.email == email

    found_user = find_user_by_email(email=email)

    assert found_user == user

Теперь вы можете запустить тест и увидеть его пройти:

$ pytest

Заключение

Который завершает часть 1. В следующих частях мы будем добавлять представления и тесты для входа в систему пользователей, предотвращая ненужные пользователи, которые появляются ресурсы, и, наконец, добавляя гранулированные роли контроль доступа. Увидимся!

Оригинал: “https://dev.to/ksaaskil/setting-up-django-rest-api-with-custom-user-model-and-tests-5b8f”