1 '''
2 Created on Aug 3, 2010
3
4 @author: jnaous
5 '''
6 from django.db import models
7 from django.contrib.auth.models import User
8 from django.contrib.contenttypes.models import ContentType
9 from django.db.models import F, Count
10 from expedient.clearinghouse.project.models import Project
11 from expedient.common.permissions.models import ObjectPermission, Permittee,\
12 PermissionOwnership
13 from expedient.common.messaging.models import DatedMessage
14
16 """Manager for L{ProjectRole} instances."""
17
19 """Get a C{User} query set for users that have role C{role_name} in
20 project C{project}
21
22 @param role_name: Name of the project role.
23 @type role_name: C{str}.
24 @param project: project instance.
25 @type project: L{Project}.
26 @return: all users with that role in the project
27 @rtype: C{QuerySet} of C{User} objects.
28 """
29 user_ids = set(Permittee.objects.filter(
30 projectrole__name=role_name,
31 projectrole__project=project).values_list(
32 "pk", flat=True))
33 return User.objects.filter(pk__in=user_ids)
34
36 """filter for all roles the permittee can fully delegate in a project
37
38 @param permittee: object to check for delegatable roles.
39 @type permittee: L{Permittee} or C{django.db.models.Model}
40 @param project: the project to filter roles for
41 @type project: L{Project}
42 @return: all project roles the permittee can delegate.
43 @rtype: C{QuerySet} of C{ProjectRole}s.
44 """
45 permittee = Permittee.objects.get_as_permittee(permittee)
46
47
48 obj_perms_ids = list(ObjectPermission.objects.exclude(
49 permissionownership__can_delegate=True,
50 permissionownership__permittee=permittee,
51 ).filter(projectrole__project=project).values_list("pk", flat=True))
52
53
54
55 return self.exclude(
56 obj_permissions__pk__in=obj_perms_ids).filter(
57 project=project)
58
60 """Filter roles that have the permission C{perm_name} for C{target}.
61
62 @param perm_name: The name of the permission to filter the roles for.
63 @type perm_name: C{str}.
64 @param target: The object that is the target of the permission.
65 @type target: instance of C{Model}. Note this cannot be a C{class}.
66 @return: Only project roles that have the permission for the target.
67 @rtype: C{QuerySet} for C{ProjectRole}.
68
69 """
70
71 return self.filter(
72 obj_permissions__permission__name=perm_name,
73 obj_permissions__object_type=\
74 ContentType.objects.get_for_model(target.__class__),
75 obj_permissions__object_id=target.pk,
76 ).distinct()
77
79 """Groups object permissions together for easier fine-grained management.
80 This role is local to a project.
81
82 @cvar objects: a L{ProjectRoleManager}.
83
84 @ivar name: The name of the role. Doesn't needs to be unique within a
85 project.
86 @type name: str, max length=100
87 @ivar description: Information about the role.
88 @type description: TextField
89 @ivar project: The project for this role.
90 @type project: L{Project}
91 @ivar obj_permissions: object permissions that this roles groups.
92 @type obj_permissions: C{ManyToManyField} to L{ObjectPermission}.
93 @ivar permittees: Set of permittees that have this role.
94 @type permittees: C{ManyToManyField} to L{Permittee}.
95 """
96
97 objects = ProjectRoleManager()
98
99 name = models.CharField(
100 max_length=100,
101 help_text="Enter the name of the role. This should be unique within "
102 "the project.")
103 description = models.TextField(blank=True, default="",
104 help_text="The role's description should help users know what the "
105 "role is meant for and what capabilities the role gives.")
106 project = models.ForeignKey(Project)
107 obj_permissions = models.ManyToManyField(
108 ObjectPermission, verbose_name="Role's permissions",
109 help_text="Select the permissions that users who have role "
110 "should have."
111 )
112 permittees = models.ManyToManyField(Permittee)
113
118
121
123 """Give the role to a permittee. This combines the permittee's
124 permissions.
125
126 @param permittee: object to give the role to.
127 @type permittee: object or L{Permittee} instance.
128 @keyword giver: The giver of all the permissions in the roles. If
129 not C{None}, the giver will be checked for authorization to
130 delegate the permission.
131 @type giver: Model instance or L{Permittee}
132 @keyword can_delegate: Should the permittee be able to give the
133 permissions in the role to others? Default False.
134 @type can_delegate: C{bool}.
135 """
136
137 permittee = Permittee.objects.get_as_permittee(permittee)
138 self.permittees.add(permittee)
139 for obj_perm in self.obj_permissions.all():
140 obj_perm.give_to(
141 permittee, giver=giver, can_delegate=can_delegate)
142
147
166
167 - def add_permission(self, obj_permission, giver=None, can_delegate=False):
168 """Add the object permission to the role and to all permittees who
169 have this role.
170
171 @param obj_permission: The object permission to add.
172 @type obj_permission: L{ObjectPermission}.
173 @keyword giver: The giver of the permission in the roles. If
174 not C{None}, the giver will be checked for authorization to
175 delegate the permission.
176 @type giver: Model instance or L{Permittee}
177 @keyword can_delegate: Should the permittees with this role be able
178 to give the permission to others?
179 @type can_delegate: C{bool}.
180 """
181
182 for p in self.permittees.all():
183 obj_permission.give_to(p, giver=giver, can_delegate=can_delegate)
184 self.obj_permissions.add(obj_permission)
185
202
204 """A request for a project role"""
205
206 requester = models.ForeignKey(
207 User, help_text="User requesting the role.",
208 related_name="role_requests_made")
209 requested_role = models.ForeignKey(
210 ProjectRole, help_text="Choose a role to request.")
211 giver = models.ForeignKey(
212 User, help_text="Choose a user to make a request to.",
213 related_name="role_requests_received")
214 message = models.TextField(
215 blank=True, default="",
216 help_text="Add a personalized message to the request.")
217
229
238