Skip to content
Snippets Groups Projects
Commit c91dcf27 authored by jan.bednarik's avatar jan.bednarik
Browse files

Copy users app from another project as base for this

parent ac4a72f0
No related branches found
No related tags found
No related merge requests found
from django.contrib import admin
from django.contrib.auth import admin as auth_admin
from django.contrib.auth import get_user_model
from .models import Team
User = get_user_model()
@admin.register(User)
class UserAdmin(auth_admin.UserAdmin):
fieldsets = (("User", {"fields": ("teams",)}),) + auth_admin.UserAdmin.fieldsets
def has_add_permission(self, request):
return False
@admin.register(Team)
class TeamAdmin(admin.ModelAdmin):
def has_add_permission(self, request):
# TODO when auto sync is done, disable manual add
return True
from django.apps import AppConfig
from django.utils.translation import gettext_lazy as _
class UsersConfig(AppConfig):
name = "nominace.users"
verbose_name = _("Users")
def ready(self):
try:
import nominace.users.signals
except ImportError:
pass
from mozilla_django_oidc.auth import OIDCAuthenticationBackend
class CustomOIDCAuthenticationBackend(OIDCAuthenticationBackend):
"""
Custom OIDC Authentication Backend.
Instead of `email` uses claim `sub` (as `username`) to identify users. Which
allows for email change.
"""
def get_username(self, claims):
return claims.get("sub")
def filter_users_by_claims(self, claims):
username = self.get_username(claims)
if not username:
return self.UserModel.objects.none()
return self.UserModel.objects.filter(username=username)
def create_user(self, claims):
username = self.get_username(claims)
first_name = claims.get("given_name", "")
last_name = claims.get("family_name", "")
email = claims.get("email", "")
return self.UserModel.objects.create_user(
username=username, first_name=first_name, last_name=last_name, email=email
)
def update_user(self, user, claims):
user.first_name = claims.get("given_name", "")
user.last_name = claims.get("family_name", "")
user.email = claims.get("email", "")
user.save()
return user
import django.contrib.auth.models
import django.contrib.auth.validators
import django.utils.timezone
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [("auth", "0008_alter_user_username_max_length")]
operations = [
migrations.CreateModel(
name="User",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("password", models.CharField(max_length=128, verbose_name="password")),
(
"last_login",
models.DateTimeField(
blank=True, null=True, verbose_name="last login"
),
),
(
"is_superuser",
models.BooleanField(
default=False,
help_text="Designates that this user has all permissions without explicitly assigning them.",
verbose_name="superuser status",
),
),
(
"username",
models.CharField(
error_messages={
"unique": "A user with that username already exists."
},
help_text="Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.",
max_length=150,
unique=True,
validators=[
django.contrib.auth.validators.UnicodeUsernameValidator()
],
verbose_name="username",
),
),
(
"first_name",
models.CharField(
blank=True, max_length=30, verbose_name="first name"
),
),
(
"last_name",
models.CharField(
blank=True, max_length=150, verbose_name="last name"
),
),
(
"email",
models.EmailField(
blank=True, max_length=254, verbose_name="email address"
),
),
(
"is_staff",
models.BooleanField(
default=False,
help_text="Designates whether the user can log into this admin site.",
verbose_name="staff status",
),
),
(
"is_active",
models.BooleanField(
default=True,
help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.",
verbose_name="active",
),
),
(
"date_joined",
models.DateTimeField(
default=django.utils.timezone.now, verbose_name="date joined"
),
),
(
"name",
models.CharField(
blank=True, max_length=255, verbose_name="Name of User"
),
),
(
"groups",
models.ManyToManyField(
blank=True,
help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.",
related_name="user_set",
related_query_name="user",
to="auth.Group",
verbose_name="groups",
),
),
(
"user_permissions",
models.ManyToManyField(
blank=True,
help_text="Specific permissions for this user.",
related_name="user_set",
related_query_name="user",
to="auth.Permission",
verbose_name="user permissions",
),
),
],
options={
"verbose_name_plural": "users",
"verbose_name": "user",
"abstract": False,
},
managers=[("objects", django.contrib.auth.models.UserManager())],
)
]
# Generated by Django 3.0.2 on 2020-01-29 14:35
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [("users", "0001_initial")]
operations = [migrations.RemoveField(model_name="user", name="name")]
# Generated by Django 3.0.2 on 2020-01-29 20:39
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [("users", "0002_remove_user_name")]
operations = [
migrations.CreateModel(
name="Team",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("name", models.CharField(max_length=1000)),
],
options={"ordering": ["name"]},
),
migrations.AddField(
model_name="user",
name="teams",
field=models.ManyToManyField(to="users.Team"),
),
]
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.urls import reverse
class User(AbstractUser):
teams = models.ManyToManyField("Team")
def get_absolute_url(self):
return reverse("users:detail", kwargs={"username": self.username})
class Team(models.Model):
name = models.CharField(max_length=1000)
class Meta:
ordering = ["name"]
def __str__(self):
return self.name
......@@ -12,4 +12,4 @@ line_length = 88
multi_line_output = 3
default_sectiont = "THIRDPARTY"
include_trailing_comma = true
known_third_party =setuptools
known_third_party =django,factory,faker,mozilla_django_oidc,pytest,setuptools
from typing import Any, Sequence
from django.contrib.auth import get_user_model
from factory import DjangoModelFactory, Faker, post_generation
from pirates.models import Team
class UserFactory(DjangoModelFactory):
username = Faker("user_name")
email = Faker("email")
@post_generation
def password(self, create: bool, extracted: Sequence[Any], **kwargs):
password = Faker(
"password",
length=42,
special_chars=True,
digits=True,
upper_case=True,
lower_case=True,
).generate(extra_kwargs={})
self.set_password(password)
class Meta:
model = get_user_model()
django_get_or_create = ["username"]
class TeamFactory(DjangoModelFactory):
name = Faker("company")
class Meta:
model = Team
import pytest
from django.contrib.auth import get_user_model
from faker import Faker
from pirates.auth import CustomOIDCAuthenticationBackend
pytestmark = pytest.mark.django_db
fake = Faker()
@pytest.fixture
def backend():
return CustomOIDCAuthenticationBackend()
def test_auth_backend__get_username(backend):
sub = fake.user_name()
claims = {"sub": sub}
assert backend.get_username(claims) == sub
def test_auth_backend__filter_users_by_claims__missing_sub_in_claims(backend):
claims = {}
users = backend.filter_users_by_claims(claims)
assert users.exists() is False
def test_auth_backend__filter_users_by_claims__unknown_user(backend):
claims = {"sub": fake.user_name()}
users = backend.filter_users_by_claims(claims)
assert users.exists() is False
def test_auth_backend__filter_users_by_claims__known_user(backend, user):
claims = {"sub": user.username}
users = backend.filter_users_by_claims(claims)
assert list(users) == [user]
def test_auth_backend__create_user(backend):
claims = {
"sub": fake.user_name(),
"given_name": fake.first_name(),
"family_name": fake.last_name(),
"email": fake.email(),
}
user = backend.create_user(claims)
assert user.username == claims["sub"]
assert user.first_name == claims["given_name"]
assert user.last_name == claims["family_name"]
assert user.email == claims["email"]
assert get_user_model().objects.get() == user
def test_auth_backend__update_user(backend, user):
claims = {
"sub": user.username,
"given_name": fake.first_name(),
"family_name": fake.last_name(),
"email": fake.email(),
}
assert user.first_name != claims["given_name"]
assert user.last_name != claims["family_name"]
assert user.email != claims["email"]
updated_user = backend.update_user(user, claims)
assert updated_user.username == user.username
assert updated_user.first_name == claims["given_name"]
assert updated_user.last_name == claims["family_name"]
assert updated_user.email == claims["email"]
assert get_user_model().objects.get() == updated_user
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment