Working on permissions and groups generation

remotes/origin/enhancement/email-actions
Jesús Espino 2013-03-22 17:52:18 +01:00
parent e0e41c7c95
commit a36a130998
9 changed files with 53 additions and 150 deletions

View File

@ -1,65 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
# FIXME: move this file to base.
from greenmine.profile.models import Role
from greenmine.scrum.models import ProjectUserRole
def get_role(name):
"""
Helper method for a get role object
finding by name.
"""
return Role.objects.get(slug=name)
def has_perm(user, project, loc, perm, pur=None):
"""
Checks if a user has a concrete permission on
a project.
"""
if not pur:
try:
pur = ProjectUserRole.objects.get(project=project, user=user)
except ProjectUserRole.DoesNotExist:
return False
return getattr(pur.role, '%s_%s' % (loc.lower(), perm.lower()), False)
def has_perms(user, project, perms=[]):
"""
Check a group of permissions in a single call.
"""
if user.is_superuser:
return True
if project.owner == user:
return True
try:
pur, valid = ProjectUserRole.objects\
.get(project=project, user=user), True
except ProjectUserRole.DoesNotExist:
return False
for pitem in perms:
if len(pitem) != 2:
continue
loc, locperms = pitem
if not isinstance(locperms, (list, tuple)):
locperms = [locperms]
valid = False not in [has_perm(user, project, loc, locperm, pur=pur)
for locperm in locperms]
if not valid:
break
return valid

View File

@ -2,7 +2,7 @@
from django.db import models from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import Permission from django.contrib.auth.models import Permission, Group
class Profile(models.Model): class Profile(models.Model):
@ -26,5 +26,12 @@ class Role(models.Model):
permissions = models.ManyToManyField(Permission, permissions = models.ManyToManyField(Permission,
verbose_name=_('permissions'), blank=True) 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')
from . import sigdispatch from . import sigdispatch

View File

@ -0,0 +1,23 @@
from django.contrib.auth.models import Group
from greenmine.scrum.models import Project
class RoleGroupsService(object):
def replicate_role_on_all_projects(self, role):
for group in role.groups.all():
self._replicate_role_permissions_on_group(role, group)
for project in Project.objects.all():
self._replicate_role_on_project_if_needed(role, project)
def _replicate_role_permissions_on_group(self, role, group):
group.permissions.clear()
for permission in role.permissions.all():
group.permissions.add(permission)
group.save()
def _replicate_role_on_project_if_needed(self, role, project):
if project.groups.filter(role=role).count() == 0:
group = Group(name="p%d-r%d" % (project.pk, role.pk), role=role)
group.save()
role.groups.add(group)
self._replicate_role_permissions_on_group(role, group)

View File

@ -6,7 +6,8 @@ from django.db.models.signals import post_save
from django.dispatch import receiver from django.dispatch import receiver
from django.contrib.auth.models import User from django.contrib.auth.models import User
from .models import Profile from .models import Profile, Role
from .services import RoleGroupsService
@receiver(post_save, sender=User) @receiver(post_save, sender=User)
@ -16,3 +17,10 @@ def user_post_save(sender, instance, created, **kwargs):
""" """
if created and not Profile.objects.filter(user=instance).exists(): if created and not Profile.objects.filter(user=instance).exists():
Profile.objects.create(user=instance) Profile.objects.create(user=instance)
@receiver(post_save, sender=Role)
def role_post_save(sender, instance, created, **kwargs):
"""
Recalculate projects groups
"""
RoleGroupsService().replicate_role_on_all_projects(instance)

View File

@ -1,11 +1,13 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.contrib import admin from django.contrib import admin
from greenmine.scrum.models import Project, ProjectExtras, ProjectUserRole, \ from guardian.admin import GuardedModelAdmin
from greenmine.scrum.models import Project, ProjectExtras, \
Milestone, UserStory, Change, ChangeAttachment, Task Milestone, UserStory, Change, ChangeAttachment, Task
class ProjectAdmin(admin.ModelAdmin): class ProjectAdmin(GuardedModelAdmin):
list_display = ["name", "owner"] list_display = ["name", "owner"]
admin.site.register(Project, ProjectAdmin) admin.site.register(Project, ProjectAdmin)
@ -17,12 +19,6 @@ class ProjectExtrasAdmin(admin.ModelAdmin):
admin.site.register(ProjectExtras, ProjectExtrasAdmin) admin.site.register(ProjectExtras, ProjectExtrasAdmin)
class ProjectUserRoleAdmin(admin.ModelAdmin):
list_display = ["project", "user", "role"]
admin.site.register(ProjectUserRole, ProjectUserRoleAdmin)
class MilestoneAdmin(admin.ModelAdmin): class MilestoneAdmin(admin.ModelAdmin):
list_display = ["name", "project", "owner"] list_display = ["name", "project", "owner"]

View File

@ -3,7 +3,7 @@ from tastypie.resources import ModelResource
from tastypie.authentication import SessionAuthentication from tastypie.authentication import SessionAuthentication
from tastypie.authorization import DjangoAuthorization from tastypie.authorization import DjangoAuthorization
from greenmine.scrum.models import Project, ProjectUserRole, \ from greenmine.scrum.models import Project, \
Milestone, UserStory, Change, ChangeAttachment, Task Milestone, UserStory, Change, ChangeAttachment, Task
@ -15,14 +15,6 @@ class ProjectResource(ModelResource):
authorization = DjangoAuthorization() authorization = DjangoAuthorization()
class ProjectUserRoleResource(ModelResource):
class Meta:
queryset = ProjectUserRole.objects.all()
resource_name = 'projectuserrole'
authentication = SessionAuthentication()
authorization = DjangoAuthorization()
class MilestoneResource(ModelResource): class MilestoneResource(ModelResource):
class Meta: class Meta:
queryset = Milestone.objects.all() queryset = Milestone.objects.all()

View File

@ -23,11 +23,6 @@ class ProjectManager(models.Manager):
def get_by_natural_key(self, slug): def get_by_natural_key(self, slug):
return self.get(slug=slug) return self.get(slug=slug)
def can_view(self, user):
queryset = ProjectUserRole.objects.filter(user=user)\
.values_list('project', flat=True)
return Project.objects.filter(pk__in=queryset)
class ProjectExtras(models.Model): class ProjectExtras(models.Model):
task_parser_re = models.CharField(max_length=1000, blank=True, null=True, default=None) task_parser_re = models.CharField(max_length=1000, blank=True, null=True, default=None)
@ -60,12 +55,10 @@ class Project(models.Model):
modified_date = models.DateTimeField(auto_now_add=True) modified_date = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey("auth.User", related_name="projects") owner = models.ForeignKey("auth.User", related_name="projects")
participants = models.ManyToManyField('auth.User', groups = models.ManyToManyField('auth.Group',
related_name="projects_participant", related_name="projects",
through="ProjectUserRole",
null=True, null=True,
blank=True) blank=True)
public = models.BooleanField(default=True) public = models.BooleanField(default=True)
markup = models.CharField(max_length=10, choices=MARKUP_TYPE, default='md') markup = models.CharField(max_length=10, choices=MARKUP_TYPE, default='md')
extras = models.OneToOneField("ProjectExtras", related_name="project", null=True, default=None) extras = models.OneToOneField("ProjectExtras", related_name="project", null=True, default=None)
@ -143,8 +136,7 @@ class Project(models.Model):
@property @property
def all_participants(self): def all_participants(self):
qs = ProjectUserRole.objects.filter(project=self) return User.objects.filter(group__in=self.groups)
return User.objects.filter(id__in=qs.values_list('user__pk', flat=True))
@property @property
def default_milestone(self): def default_milestone(self):
@ -161,44 +153,6 @@ class Project(models.Model):
super(Project, self).save(*args, **kwargs) super(Project, self).save(*args, **kwargs)
def add_user(self, user, role):
from greenmine.base import permissions
return ProjectUserRole.objects.create(
project=self,
user=user,
role=permissions.get_role(role),
)
class ProjectUserRole(models.Model):
project = models.ForeignKey("Project", related_name="user_roles")
user = models.ForeignKey("auth.User", related_name="user_roles")
role = models.ForeignKey("profile.Role", related_name="user_roles")
mail_milestone_created = models.BooleanField(default=True)
mail_milestone_modified = models.BooleanField(default=False)
mail_milestone_deleted = models.BooleanField(default=False)
mail_userstory_created = models.BooleanField(default=True)
mail_userstory_modified = models.BooleanField(default=False)
mail_userstory_deleted = models.BooleanField(default=False)
mail_task_created = models.BooleanField(default=True)
mail_task_assigned = models.BooleanField(default=False)
mail_task_deleted = models.BooleanField(default=False)
mail_question_created = models.BooleanField(default=False)
mail_question_assigned = models.BooleanField(default=True)
mail_question_deleted = models.BooleanField(default=False)
mail_document_created = models.BooleanField(default=True)
mail_document_deleted = models.BooleanField(default=False)
mail_wiki_created = models.BooleanField(default=False)
mail_wiki_modified = models.BooleanField(default=False)
mail_wiki_deleted = models.BooleanField(default=False)
def __repr__(self):
return u"<Project-User-Relation-%s>" % (self.id)
class Meta:
unique_together = ('project', 'user')
class MilestoneManager(models.Manager): class MilestoneManager(models.Manager):
def get_by_natural_key(self, name, project): def get_by_natural_key(self, name, project):
@ -317,8 +271,10 @@ class UserStory(models.Model):
client_requirement = models.BooleanField(default=False) client_requirement = models.BooleanField(default=False)
team_requirement = models.BooleanField(default=False) team_requirement = models.BooleanField(default=False)
order = models.PositiveSmallIntegerField("Order")
class Meta: class Meta:
ordering = ['order']
unique_together = ('ref', 'project') unique_together = ('ref', 'project')
def __repr__(self): def __repr__(self):

View File

@ -7,7 +7,6 @@ from django.template.loader import render_to_string
from django.contrib.auth.models import User from django.contrib.auth.models import User
from greenmine.scrum.models import ProjectUserRole
from greenmine.base import signals from greenmine.base import signals
from greenmine.base.utils.auth import set_token from greenmine.base.utils.auth import set_token
from greenmine.base.mail.tasks import send_mail, send_bulk_mail from greenmine.base.mail.tasks import send_mail, send_bulk_mail
@ -38,11 +37,7 @@ def mail_recovery_password(sender, user, **kwargs):
@receiver(signals.mail_milestone_created) @receiver(signals.mail_milestone_created)
def mail_milestone_created(sender, milestone, user, **kwargs): def mail_milestone_created(sender, milestone, user, **kwargs):
participants_ids = ProjectUserRole.objects\ participants = milestone.project.all_participants()
.filter(user=user, mail_milestone_created=True, project=milestone.project)\
.values_list('user__pk', flat=True)
participants = User.objects.filter(pk__in=participants_ids)
emails_list = [] emails_list = []
subject = ugettext("Greenmine: sprint created") subject = ugettext("Greenmine: sprint created")
@ -61,11 +56,7 @@ def mail_milestone_created(sender, milestone, user, **kwargs):
@receiver(signals.mail_userstory_created) @receiver(signals.mail_userstory_created)
def mail_userstory_created(sender, us, user, **kwargs): def mail_userstory_created(sender, us, user, **kwargs):
participants_ids = ProjectUserRole.objects\ participants = us.milestone.project.all_participants()
.filter(user=user, mail_userstory_created=True, project=us.project)\
.values_list('user__pk', flat=True)
participants = User.objects.filter(pk__in=participants_ids)
emails_list = [] emails_list = []
subject = ugettext("Greenmine: user story created") subject = ugettext("Greenmine: user story created")
@ -85,11 +76,7 @@ def mail_userstory_created(sender, us, user, **kwargs):
@receiver(signals.mail_task_created) @receiver(signals.mail_task_created)
def mail_task_created(sender, task, user, **kwargs): def mail_task_created(sender, task, user, **kwargs):
participants_ids = ProjectUserRole.objects\ participants = task.us.milestone.project.all_participants()
.filter(user=user, mail_task_created=True, project=task.project)\
.values_list('user__pk', flat=True)
participants = User.objects.filter(pk__in=participants_ids)
emails_list = [] emails_list = []
subject = ugettext("Greenmine: task created") subject = ugettext("Greenmine: task created")

View File

@ -16,7 +16,6 @@ from wiki.api import *
v1_api = Api(api_name='gm') v1_api = Api(api_name='gm')
v1_api.register(ProjectResource()) v1_api.register(ProjectResource())
v1_api.register(ProjectUserRoleResource())
v1_api.register(MilestoneResource()) v1_api.register(MilestoneResource())
v1_api.register(UserStoryResource()) v1_api.register(UserStoryResource())
v1_api.register(ChangeResource()) v1_api.register(ChangeResource())