18 |
18 |
import os
|
19 |
19 |
from collections import namedtuple
|
20 |
20 |
|
|
21 |
from django.apps import apps
|
21 |
22 |
from django.conf import settings
|
22 |
23 |
from django.contrib.auth import get_user_model
|
23 |
24 |
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
|
... | ... | |
314 |
315 |
"target": self.target.natural_key_json(),
|
315 |
316 |
}
|
316 |
317 |
|
|
318 |
@classmethod
|
|
319 |
def from_str(cls, s, instance=None):
|
|
320 |
'''Build permission from a string of the form [ou_slug? app_label.model_operation].
|
|
321 |
|
|
322 |
The optional ou_slug is used to created OU scoped permissions.
|
|
323 |
An optional instance argument can be used to create a permission on an instance.
|
|
324 |
'''
|
|
325 |
ou_slug = None
|
|
326 |
s = s.strip()
|
|
327 |
if ' ' in s:
|
|
328 |
ou_slug, permission = s.split()
|
|
329 |
else:
|
|
330 |
permission = s
|
|
331 |
app_label, operation_model = permission.split('.', 1)
|
|
332 |
operation, model = operation_model.split('_')
|
|
333 |
app = apps.get_app_config(app_label)
|
|
334 |
model_class = app.get_model(model)
|
|
335 |
|
|
336 |
if instance is None:
|
|
337 |
permission, _ = Permission.objects.get_or_create(
|
|
338 |
operation=Operation.objects.get(slug=operation),
|
|
339 |
ou=OrganizationalUnit.objects.get(slug=ou_slug) if ou_slug else None,
|
|
340 |
target_ct=ContentType.objects.get_for_model(ContentType),
|
|
341 |
target_id=ContentType.objects.get_for_model(model_class).pk,
|
|
342 |
)
|
|
343 |
else:
|
|
344 |
assert isinstance(instance, model_class), f'{instance} is not an instance of {model_class}'
|
|
345 |
permission, _ = Permission.objects.get_or_create(
|
|
346 |
operation=Operation.objects.get(slug=operation),
|
|
347 |
ou=OrganizationalUnit.objects.get(slug=ou_slug) if ou_slug else None,
|
|
348 |
target_ct=ContentType.objects.get_for_model(instance),
|
|
349 |
target_id=instance.pk,
|
|
350 |
)
|
|
351 |
return permission
|
|
352 |
|
317 |
353 |
def __str__(self):
|
318 |
354 |
ct = ContentType.objects.get_for_id(self.target_ct_id)
|
319 |
355 |
ct_ct = ContentType.objects.get_for_model(ContentType)
|
320 |
|
-
|