diff --git a/greenmine/base/admin.py b/greenmine/base/admin.py index 4027d384..76fbeeb3 100644 --- a/greenmine/base/admin.py +++ b/greenmine/base/admin.py @@ -1,4 +1,21 @@ from django.contrib import admin from django.contrib.auth.models import Group +from greenmine.base.models import Role + admin.site.unregister(Group) + +class RoleAdmin(admin.ModelAdmin): + list_display = ["name"] + filter_horizontal = ('permissions',) + + def formfield_for_manytomany(self, db_field, request=None, **kwargs): + if db_field.name == 'permissions': + qs = kwargs.get('queryset', db_field.rel.to.objects) + # Avoid a major performance hit resolving permission names which + # triggers a content_type load: + kwargs['queryset'] = qs.select_related('content_type') + return super(RoleAdmin, self).formfield_for_manytomany( + db_field, request=request, **kwargs) + +admin.site.register(Role, RoleAdmin) diff --git a/greenmine/profile/fixtures/initial_data.json b/greenmine/base/fixtures/initial_data.json similarity index 100% rename from greenmine/profile/fixtures/initial_data.json rename to greenmine/base/fixtures/initial_data.json diff --git a/greenmine/base/models.py b/greenmine/base/models.py index fa76129c..c45aae35 100644 --- a/greenmine/base/models.py +++ b/greenmine/base/models.py @@ -1,13 +1,21 @@ # -*- coding: utf-8 -*- from django.db.models import signals -from django.dispatch import receiver +from django.db import models +from django.db.models.signals import post_save, m2m_changed from django.utils.timezone import now +from django.dispatch import receiver +from django.utils.translation import ugettext_lazy as _ + +from django.contrib.auth.models import UserManager, AbstractUser, Group from greenmine.scrum.models import Project, UserStory, Task import uuid +from greenmine.scrum.models import Project + + # Centralized uuid attachment and ref generation @receiver(signals.pre_save) @@ -37,3 +45,53 @@ def attach_unique_reference(sender, instance, **kwargs): instance.ref = project.last_us_ref project.save() + + +class User(AbstractUser): + color = models.CharField(max_length=9) + description = models.TextField(blank=True) + photo = models.FileField(upload_to="files/msg", max_length=500, null=True, + blank=True) + + default_language = models.CharField(max_length=20, null=True, blank=True, + default=None) + default_timezone = models.CharField(max_length=20, null=True, blank=True, + default=None) + token = models.CharField(max_length=200, unique=True, null=True, + blank=True, default=None) + colorize_tags = models.BooleanField(default=False) + objects = UserManager + +class Role(models.Model): + name = models.CharField(max_length=200) + slug = models.SlugField(max_length=250, unique=True, blank=True) + permissions = models.ManyToManyField('auth.Permission', + verbose_name=_('permissions'), blank=True) + + def __unicode__(self): + return unicode(self.name) + +if not hasattr(Group, 'role'): + field = models.ForeignKey(Role, blank=False, null=False, related_name='groups') + field.contribute_to_class(Group, 'role') + +if not hasattr(Group, 'project'): + field = models.ForeignKey(Project, blank=False, null=False, related_name='groups') + field.contribute_to_class(Group, 'project') + + +@receiver(post_save, sender=Role) +def role_post_save(sender, instance, **kwargs): + """ + Recalculate projects groups + """ + from greenmine.base.services import RoleGroupsService + RoleGroupsService().replicate_role_on_all_projects(instance) + +@receiver(m2m_changed, sender=Role.permissions.through) +def role_m2m_changed(sender, instance, **kwargs): + """ + Recalculate projects groups + """ + from greenmine.base.services import RoleGroupsService + RoleGroupsService().replicate_role_on_all_projects(instance) diff --git a/greenmine/base/serializers.py b/greenmine/base/serializers.py index 3f78e600..b6dfce87 100644 --- a/greenmine/base/serializers.py +++ b/greenmine/base/serializers.py @@ -1,5 +1,6 @@ from rest_framework import serializers + class UserLogged(object): def __init__(self, token, username, first_name, last_name, email, last_login): self.token = token diff --git a/greenmine/profile/services.py b/greenmine/base/services.py similarity index 96% rename from greenmine/profile/services.py rename to greenmine/base/services.py index 6df20e05..9a69d922 100644 --- a/greenmine/profile/services.py +++ b/greenmine/base/services.py @@ -1,7 +1,8 @@ from django.contrib.auth.models import Group from greenmine.scrum.models import Project -from greenmine.profile.models import Role +from greenmine.base.models import Role + class RoleGroupsService(object): def replicate_role_on_all_projects(self, role): diff --git a/greenmine/base/tests.py b/greenmine/base/tests.py index dbc19e59..5bd80057 100644 --- a/greenmine/base/tests.py +++ b/greenmine/base/tests.py @@ -86,7 +86,7 @@ class UserMailTests(TestCase): # pre test self.assertTrue(self.user2.is_active) - self.assertEqual(self.user2.get_profile().token, None) + self.assertEqual(self.user2.token, None) response = self.client.get(url, follow=True) self.assertEqual(response.status_code, 200) @@ -102,9 +102,9 @@ class UserMailTests(TestCase): self.user2 = User.objects.get(pk=self.user2.pk) self.assertTrue(self.user2.is_active) self.assertFalse(self.user2.has_usable_password()) - self.assertNotEqual(self.user2.get_profile().token, None) + self.assertNotEqual(self.user2.token, None) - url = reverse('password-recovery', args=[self.user2.get_profile().token]) + url = reverse('password-recovery', args=[self.user2.token]) post_params = { 'password': '123123', diff --git a/greenmine/base/utils/auth.py b/greenmine/base/utils/auth.py index 2791fef9..beaae24a 100644 --- a/greenmine/base/utils/auth.py +++ b/greenmine/base/utils/auth.py @@ -9,9 +9,6 @@ def set_token(user): """ token = unicode(uuid.uuid4()) - profile = user.get_profile() - profile.token = token - + user.token = token user.save() - profile.save() return token diff --git a/greenmine/dashboard.py b/greenmine/dashboard.py index 7045ce88..c8762d80 100644 --- a/greenmine/dashboard.py +++ b/greenmine/dashboard.py @@ -26,7 +26,7 @@ class CustomIndexDashboard(Dashboard): _('Administration'), column=1, collapsible=False, - models=('django.contrib.*', 'greenmine.profile.*',), + models=('django.contrib.*', 'greenmine.base.*',), ), ) diff --git a/greenmine/profile/__init__.py b/greenmine/profile/__init__.py deleted file mode 100644 index faaaf799..00000000 --- a/greenmine/profile/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- - - diff --git a/greenmine/profile/admin.py b/greenmine/profile/admin.py deleted file mode 100644 index 2cce23c8..00000000 --- a/greenmine/profile/admin.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -from django.contrib import admin - -from greenmine.profile.models import Profile, Role - - -class ProfileAdmin(admin.ModelAdmin): - list_display = ["user"] - -admin.site.register(Profile, ProfileAdmin) - - -class RoleAdmin(admin.ModelAdmin): - list_display = ["name"] - filter_horizontal = ('permissions',) - - def formfield_for_manytomany(self, db_field, request=None, **kwargs): - if db_field.name == 'permissions': - qs = kwargs.get('queryset', db_field.rel.to.objects) - # Avoid a major performance hit resolving permission names which - # triggers a content_type load: - kwargs['queryset'] = qs.select_related('content_type') - return super(RoleAdmin, self).formfield_for_manytomany( - db_field, request=request, **kwargs) - -admin.site.register(Role, RoleAdmin) diff --git a/greenmine/profile/api.py b/greenmine/profile/api.py deleted file mode 100644 index 3ddde24c..00000000 --- a/greenmine/profile/api.py +++ /dev/null @@ -1,14 +0,0 @@ -# myapp/api.py -from tastypie.resources import ModelResource -from tastypie.authentication import SessionAuthentication -from tastypie.authorization import DjangoAuthorization - -from greenmine.profile.models import Profile - - -class ProfileResource(ModelResource): - class Meta: - queryset = Profile.objects.all() - resource_name = 'profile' - authentication = SessionAuthentication() - authorization = DjangoAuthorization() diff --git a/greenmine/profile/models.py b/greenmine/profile/models.py deleted file mode 100644 index b80762d7..00000000 --- a/greenmine/profile/models.py +++ /dev/null @@ -1,66 +0,0 @@ -# -*- coding: utf-8 -*- - -from django.db import models -from django.db.models.signals import post_save, m2m_changed -from django.dispatch import receiver -from django.utils.translation import ugettext_lazy as _ -from django.contrib.auth.models import User, Group - -from greenmine.scrum.models import Project - -class Profile(models.Model): - user = models.OneToOneField("auth.User", related_name='profile') - description = models.TextField(blank=True) - photo = models.FileField(upload_to="files/msg", max_length=500, null=True, - blank=True) - - default_language = models.CharField(max_length=20, null=True, blank=True, - default=None) - default_timezone = models.CharField(max_length=20, null=True, blank=True, - default=None) - token = models.CharField(max_length=200, unique=True, null=True, - blank=True, default=None) - colorize_tags = models.BooleanField(default=False) - - -class Role(models.Model): - name = models.CharField(max_length=200) - slug = models.SlugField(max_length=250, unique=True, blank=True) - permissions = models.ManyToManyField('auth.Permission', - verbose_name=_('permissions'), blank=True) - - def __unicode__(self): - return unicode(self.name) - -if not hasattr(Group, 'role'): - field = models.ForeignKey(Role, blank=False, null=False, related_name='groups') - field.contribute_to_class(Group, 'role') - -if not hasattr(Group, 'project'): - field = models.ForeignKey(Project, blank=False, null=False, related_name='groups') - field.contribute_to_class(Group, 'project') - - -@receiver(post_save, sender=User) -def user_post_save(sender, instance, created, **kwargs): - """ - Create void user profile if instance is a new user. - """ - if created and not Profile.objects.filter(user=instance).exists(): - Profile.objects.create(user=instance) - -@receiver(post_save, sender=Role) -def role_post_save(sender, instance, **kwargs): - """ - Recalculate projects groups - """ - from greenmine.profile.services import RoleGroupsService - RoleGroupsService().replicate_role_on_all_projects(instance) - -@receiver(m2m_changed, sender=Role.permissions.through) -def role_m2m_changed(sender, instance, **kwargs): - """ - Recalculate projects groups - """ - from greenmine.profile.services import RoleGroupsService - RoleGroupsService().replicate_role_on_all_projects(instance) diff --git a/greenmine/scrum/models.py b/greenmine/scrum/models.py index 8ad3a48f..0e4705b5 100644 --- a/greenmine/scrum/models.py +++ b/greenmine/scrum/models.py @@ -402,7 +402,7 @@ class Issue(models.Model): @receiver(models.signals.post_save, sender=Project, dispatch_uid="project_post_save") def project_post_save(sender, instance, created, **kwargs): - from greenmine.profile.services import RoleGroupsService + from greenmine.base.services import RoleGroupsService if not created: return diff --git a/greenmine/scrum/sigdispatch.py b/greenmine/scrum/sigdispatch.py index 111aa57d..070bec6b 100644 --- a/greenmine/scrum/sigdispatch.py +++ b/greenmine/scrum/sigdispatch.py @@ -10,7 +10,7 @@ from greenmine.base import signals from greenmine.base.utils.auth import set_token from greenmine.base.mail.tasks import send_mail, send_bulk_mail from greenmine.scrum.models import Project -from greenmine.profile.services import RoleGroupsService +from greenmine.base.services import RoleGroupsService @receiver(signals.mail_new_user) diff --git a/greenmine/settings/common.py b/greenmine/settings/common.py index 9c2bbd4d..0c4b27c5 100644 --- a/greenmine/settings/common.py +++ b/greenmine/settings/common.py @@ -204,7 +204,6 @@ INSTALLED_APPS = [ 'greenmine.base', 'greenmine.base.mail', - 'greenmine.profile', 'greenmine.scrum', 'greenmine.wiki', 'greenmine.documents', @@ -292,7 +291,7 @@ LOGGING = { } -AUTH_PROFILE_MODULE = 'profile.Profile' +AUTH_USER_MODEL = 'greenmine.base.User' FORMAT_MODULE_PATH = 'greenmine.base.formats' DATE_INPUT_FORMATS = ( '%Y-%m-%d', '%m/%d/%Y', '%d/%m/%Y', '%b %d %Y',