Как реализовать Django SSO с пользовательской моделью и разрешением объекта (EX / django-guardian) в нескольких проектах - PullRequest
0 голосов
/ 12 апреля 2019

Я пытался найти и изучить некоторую информацию в Google, но не смог найти хорошее решение.

У меня есть несколько проектов Django, и я хочу создать пользовательскую информацию хранилища проектов "Member", в которой реализована функция единого входа (SSO) (например, " django-simple-sso "). Затем мне нужно классифицировать разрешение пользователя, я изучаю пакет « django-guardian », который, возможно, может помочь мне получить разрешение объекта.

Я делаю ниже, чтобы создать собственную модель в проекте "Member". Затем я просто публикую код, который добавляю / меняю.

# setting.py of "Member" project

INSTALLED_APPS = [    
    'users',
    'guardian'
]

AUTHENTICATION_BACKENDS = (
    'guardian.backends.ObjectPermissionBackend',
)

Я добавляю приложение, которое вызывало пользователей в проекте с именем «Member».

# admin.py in the users app of Member project.

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .forms import CustomUserCreationForm, CustomUserChangeForm
from .models import CustomUser

class CustomUserAdmin(UserAdmin):
    add_form = CustomUserCreationForm
    form = CustomUserChangeForm
    model = CustomUser
    list_display = ('email', 'is_staff', 'is_active', 'employee_account', 'location', 'chinese_name', 'english_name', 'extension', 'last_login', 'date_joined')
    list_filter = ('email', 'is_staff', 'is_active', 'employee_account', 'location', 'chinese_name', 'english_name', 'extension', 'last_login', 'date_joined')
    fieldsets = (
        (None, {'fields': ('employee_account', 'password')}),
        ('Permissions', {'fields': ('is_staff', 'is_active')}),
    )
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('employee_account', 'password1', 'password2', 'is_staff', 'is_active')}
        ),
    )
    search_fields = ('employee_account',)
    ordering = ('employee_account',)

admin.site.register(CustomUser, CustomUserAdmin)
# apps.py in the users app of Member project.  

from django.apps import AppConfig

class UsersConfig(AppConfig):
    name = 'users'
# forms.py in the users app of Member project.

from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import CustomUser

class CustomUserCreationForm(UserCreationForm):

    class Meta(UserCreationForm):
        model = CustomUser
        fields = ('employee_account',)


class CustomUserChangeForm(UserChangeForm):

    class Meta:
        model = CustomUser
        fields = ('employee_account',)
# manager.py in the users app of Member project.

from django.contrib.auth.base_user import BaseUserManager
from django.utils.translation import ugettext_lazy as _


class CustomUserManager(BaseUserManager):
    """
    Custom user model manager where email is the unique identifiers
    for authentication instead of usernames.
    """
    def create_user(self, email, password, **extra_fields):
        """
        Create and save a User with the given email and password.
        """
        if not email:
            raise ValueError(_('The Email must be set'))
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save()
        return user

    def create_superuser(self, email, password, **extra_fields):
        """
        Create and save a SuperUser with the given email and password.
        """
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        extra_fields.setdefault('is_active', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError(_('Superuser must have is_staff=True.'))
        if extra_fields.get('is_superuser') is not True:
            raise ValueError(_('Superuser must have is_superuser=True.'))
        return self.create_user(email, password, **extra_fields)
# models.py in the users app of Member project

from django.db import models
from django.db import models
from django.contrib.auth.models import AbstractBaseUser
from django.contrib.auth.models import PermissionsMixin
from django.utils.translation import gettext_lazy as _
from django.utils import timezone
from .managers import CustomUserManager


class CustomUser(AbstractBaseUser, PermissionsMixin):
    employee_account = models.CharField(max_length=100, unique=True)
    location = models.CharField(max_length=50)
    chinese_name = models.CharField(max_length=30)
    english_name = models.CharField(max_length=30)
    extension = models.CharField(max_length=30)
    email = models.EmailField(max_length=125)
    is_staff = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    date_joined = models.DateTimeField(default=timezone.now)

    USERNAME_FIELD = 'employee_account'
    REQUIRED_FIELDS = ['location','chinese_name','english_name','extension', 'email']

    objects = CustomUserManager()

    def __str__(self):
        return self.employee_account

Затем я использую оболочку django, чтобы добавить пользователя и назначить разрешение.


>>> from django.contrib.auth.models import  Group

>>> from users.models import CustomUser

>>> jack = CustomUser.objects.create_user('123456789@gamil.com', '123456789')

>>> admins = Group.objects.create(name='admins')

>>> jack.has_perm('change_group', admins)
False

>>> from guardian.models import UserObjectPermission

>>> UserObjectPermission.objects.assign_perm('change_group', jack, obj=admins)

<UserObjectPermission: admins |  | change_group>

>>> jack.has_perm('change_group', admins)
True

>>> jack.has_perm('change_group')
False

После этого я создаю книжное приложение в другом проекте с именем book_web.

# model.py in the book app of book_web project

from django.db import models

class Book(models.Model):

    sn = models.CharField(max_length=200) 
    book = models.CharField(max_length=100) 
    author = models.CharField(max_length=100) 
    price = models.PositiveIntegerField(null=True, blank=True)
    number = models.PositiveIntegerField(null=True, blank=True)

1. Кажется, что работают ненормально, когда наберите эту команду UserObjectPermission.objects.assign_perm('change_group', jack, obj=admins). Я обнаружил, что в ответе не отображается имя пользователя, которое отличается от django-guardian пример кода.

2. Я не знаю, как назначить разрешение объекта Book в проекте Member, таком как пример кода django-guardian. Потому что в проекте Member нет модели, аналогичной модели Book.

У кого-нибудь есть подобный опыт по этому поводу?

Если у вас есть другой пакет рекомендаций для реализации этой функции, можете поделиться своим опытом. Спасибо за ваш ответ.

...