diff --git a/kfet/auth/__init__.py b/kfet/auth/__init__.py index 63392684..00926030 100644 --- a/kfet/auth/__init__.py +++ b/kfet/auth/__init__.py @@ -1 +1,4 @@ default_app_config = 'kfet.auth.apps.KFetAuthConfig' + +KFET_GENERIC_USERNAME = 'kfet_genericteam' +KFET_GENERIC_TRIGRAMME = 'GNR' diff --git a/kfet/auth/apps.py b/kfet/auth/apps.py index ab791d18..03742843 100644 --- a/kfet/auth/apps.py +++ b/kfet/auth/apps.py @@ -1,4 +1,5 @@ from django.apps import AppConfig +from django.db.models.signals import post_migrate from django.utils.translation import ugettext_lazy as _ @@ -6,3 +7,7 @@ class KFetAuthConfig(AppConfig): name = 'kfet.auth' label = 'kfetauth' verbose_name = _("K-Fêt - Authentification et Autorisation") + + def ready(self): + from .utils import setup_kfet_generic_user + post_migrate.connect(setup_kfet_generic_user, sender=self) diff --git a/kfet/auth/backends.py b/kfet/auth/backends.py index fb9538d0..c972fb55 100644 --- a/kfet/auth/backends.py +++ b/kfet/auth/backends.py @@ -2,10 +2,13 @@ import hashlib -from django.contrib.auth.models import User, Permission -from gestioncof.models import CofProfile +from django.contrib.auth import get_user_model from kfet.models import Account, GenericTeamToken +from .utils import get_kfet_generic_user + +User = get_user_model() + class KFetBackend(object): def authenticate(self, request): @@ -29,18 +32,7 @@ class GenericTeamBackend(object): def authenticate(self, username=None, token=None): valid_token = GenericTeamToken.objects.get(token=token) if username == 'kfet_genericteam' and valid_token: - # Création du user s'il n'existe pas déjà - user, _ = User.objects.get_or_create(username='kfet_genericteam') - profile, _ = CofProfile.objects.get_or_create(user=user) - account, _ = Account.objects.get_or_create( - cofprofile=profile, - trigramme='GNR') - - # Ajoute la permission kfet.is_team à ce user - perm_is_team = Permission.objects.get(codename='is_team') - user.user_permissions.add(perm_is_team) - - return user + return get_kfet_generic_user() return None def get_user(self, user_id): diff --git a/kfet/auth/migrations/0001_initial.py b/kfet/auth/migrations/0001_initial.py index 30dfca70..061570a8 100644 --- a/kfet/auth/migrations/0001_initial.py +++ b/kfet/auth/migrations/0001_initial.py @@ -8,6 +8,9 @@ class Migration(migrations.Migration): dependencies = [ ('auth', '0006_require_contenttypes_0002'), + # Following dependency allows using Account model to set up the kfet + # generic user in post_migrate receiver. + ('kfet', '0058_delete_genericteamtoken'), ] operations = [ diff --git a/kfet/auth/tests.py b/kfet/auth/tests.py index 7f129a3f..47cc2376 100644 --- a/kfet/auth/tests.py +++ b/kfet/auth/tests.py @@ -4,6 +4,10 @@ from django.test import TestCase from django.contrib.auth.models import User, Group from kfet.forms import UserGroupForm +from kfet.models import Account + +from . import KFET_GENERIC_TRIGRAMME, KFET_GENERIC_USERNAME +from .utils import get_kfet_generic_user class UserGroupFormTests(TestCase): @@ -54,3 +58,15 @@ class UserGroupFormTests(TestCase): [repr(g) for g in [self.other_group] + self.kfet_groups], ordered=False, ) + + +class KFetGenericUserTests(TestCase): + + def test_exists(self): + """ + The account is set up when app is ready, so it should exist. + """ + generic = Account.objects.get_generic() + self.assertEqual(generic.trigramme, KFET_GENERIC_TRIGRAMME) + self.assertEqual(generic.user.username, KFET_GENERIC_USERNAME) + self.assertEqual(get_kfet_generic_user(), generic.user) diff --git a/kfet/auth/utils.py b/kfet/auth/utils.py new file mode 100644 index 00000000..78f31028 --- /dev/null +++ b/kfet/auth/utils.py @@ -0,0 +1,28 @@ +from django.contrib.auth import get_user_model +from django.contrib.auth.models import Permission + +from kfet.models import Account + +User = get_user_model() + + +def get_kfet_generic_user(): + """ + Return the user related to the kfet generic account. + """ + return Account.objects.get_generic().user + + +def setup_kfet_generic_user(**kwargs): + """ + First steps of setup of the kfet generic user are done in a migration, as + it is more robust against database schema changes. + Following steps cannot be done from migration. + """ + generic = get_kfet_generic_user() + generic.user_permissions.add( + Permission.objects.get( + content_type__app_label='kfet', + codename='is_team', + ) + ) diff --git a/kfet/migrations/0059_create_generic.py b/kfet/migrations/0059_create_generic.py new file mode 100644 index 00000000..4f04770c --- /dev/null +++ b/kfet/migrations/0059_create_generic.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + +from kfet.auth import KFET_GENERIC_TRIGRAMME, KFET_GENERIC_USERNAME + + +def setup_kfet_generic_user(apps, schema_editor): + """ + Setup models instances for the kfet generic account. + + Username and trigramme are retrieved from kfet.auth.__init__ module. + Other data are registered here. + + See also setup_kfet_generic_user from kfet.auth.utils module. + """ + User = apps.get_model('auth', 'User') + CofProfile = apps.get_model('gestioncof', 'CofProfile') + Account = apps.get_model('kfet', 'Account') + + user, _ = User.objects.update_or_create( + username=KFET_GENERIC_USERNAME, + defaults={ + 'first_name': 'Compte générique K-Fêt', + }, + ) + profile, _ = CofProfile.objects.update_or_create(user=user) + account, _ = Account.objects.update_or_create( + cofprofile=profile, + defaults={ + 'trigramme': KFET_GENERIC_TRIGRAMME, + }, + ) + + +class Migration(migrations.Migration): + + dependencies = [ + ('kfet', '0058_delete_genericteamtoken'), + ] + + operations = [ + migrations.RunPython(setup_kfet_generic_user), + ] diff --git a/kfet/models.py b/kfet/models.py index b06114d7..9aefb782 100644 --- a/kfet/models.py +++ b/kfet/models.py @@ -14,6 +14,7 @@ from datetime import date import re import hashlib +from .auth import KFET_GENERIC_TRIGRAMME from .auth.models import GenericTeamToken # noqa from .config import kfet_config @@ -35,6 +36,12 @@ class AccountManager(models.Manager): return super().get_queryset().select_related('cofprofile__user', 'negative') + def get_generic(self): + """ + Get the kfet generic account instance. + """ + return self.get(trigramme=KFET_GENERIC_TRIGRAMME) + class Account(models.Model): objects = AccountManager()