New Abac permission model: Who is only a UserAlias object or None

An ABAC permission can now only be set on a user or on anybody.

  Axiom (unformal notation):
        p_RBAC(role, Y, Z)
            equiv.
        p_ABAC(None, Y, Z, abac_rule: PredicateRole(role))

  IBAC: p_ABAC(user, X, Y, no_rule)
  RBAC: p_ABAC(None, Y, Z, abac_rule: PredicateRole(role))
  ABAC: p_ABAC(None/user, Y, Z, abac_rule: what_you_want)

  p_ABAC(user, Y, Z, rule: PredicateRole(role)) means that user may be
  granted the access if it has the role.
This commit is contained in:
Mikaël Ates 2011-09-02 18:48:13 +02:00
parent 4abdb74719
commit 48d06b7c48
1 changed files with 22 additions and 14 deletions

View File

@ -255,14 +255,31 @@ class AcsPermission(models.Model):
class AcsAbacPermission(models.Model):
content_type_who = models.ForeignKey(ContentType, related_name = "who_abac", blank=True, null=True)
'''
Who is only a User
When a request is treated:
If who is a role. If there is a matching RBAC rule, the decision is True.
If there is an ABAC rule set on anybody with a unique predicate role on
that role, the decission is True.
Else a new rule is returned made of permissions set on anybody.
Axiom:
p_RBAC(role, Y, Z)
equiv.
p_ABAC(Anybody, Y, Z, rule: PredicateRole(role))
p_ABAC(user, Y, Z, rule: PredicateRole(role)) means that user may be
granted the access if it has the role.
More powerful than using p_RBAC
Should depreciate AcsPermission and RBAC only processing.
'''
who = models.ForeignKey(UserAlias, related_name = "who_abac", blank=True, null=True)
content_type_what = models.ForeignKey(ContentType, related_name = "what_abac")
content_type_how = models.ForeignKey(ContentType, related_name = "how_abac")
object_id_who = models.PositiveIntegerField(blank=True, null=True)
object_id_what = models.PositiveIntegerField()
object_id_how = models.PositiveIntegerField()
who = generic.GenericForeignKey(ct_field='content_type_who',
fk_field='object_id_who')
what = generic.GenericForeignKey(ct_field='content_type_what',
fk_field='object_id_what')
how = generic.GenericForeignKey(ct_field='content_type_how',
@ -294,19 +311,13 @@ class AcsAbacPermission(models.Model):
def save(self, *args, **kwargs):
p = None
t_who = None
if self.who:
if not isinstance(self.who, (UserAlias, Role)):
raise Exception('What is %s, not a User or a Role') \
%ContentType.objects.get_for_model(self.what)
t_who = ContentType.objects.get_for_model(self.who)
t_what = ContentType.objects.get_for_model(self.what)
t_how = ContentType.objects.get_for_model(self.how)
'''We check here the unicity, not redundant with unique_together'''
try:
if self.who:
p = AcsAbacPermission.objects.get(rule=self.rule,
content_type_who__pk=t_who.id,
object_id_who=self.who.id,
who=self.who,
content_type_what__pk=t_what.id,
object_id_what=self.what.id,
content_type_how__pk=t_how.id,
@ -328,9 +339,6 @@ class AcsAbacPermission(models.Model):
if not isinstance(self.how, (Action, Activity)):
raise Exception('How is %s, not an Action or an Activity') \
%ContentType.objects.get_for_model(self.how)
if self.who:
self.content_type_who = ContentType.objects.get_for_model(self.who)
self.object_id_who = self.who.id
self.content_type_what = ContentType.objects.get_for_model(self.what)
self.object_id_what = self.what.id
self.content_type_how = ContentType.objects.get_for_model(self.how)