mirror of
https://github.com/ansible/awx.git
synced 2024-10-31 15:21:13 +03:00
Make use of 'current' apps so RBAC ImplicitRoleField can work during migrations
While a migration is taking place, we can't juse use normal model references like Role and RolePermission, nor can we use generic foreign keys without manually referring to the content type and object id fields.
This commit is contained in:
parent
682552d9b0
commit
7d2e660749
@ -17,10 +17,11 @@ from django.db.models.fields.related import (
|
||||
ReverseManyRelatedObjectsDescriptor,
|
||||
)
|
||||
from django.utils.encoding import smart_text
|
||||
from django.utils.timezone import now
|
||||
|
||||
# AWX
|
||||
from awx.main.models.rbac import RolePermission, Role, batch_role_ancestor_rebuilding
|
||||
|
||||
from awx.main.models.rbac import Role, batch_role_ancestor_rebuilding
|
||||
from awx.main.utils import get_current_apps
|
||||
|
||||
__all__ = ['AutoOneToOneField', 'ImplicitRoleField']
|
||||
|
||||
@ -65,8 +66,12 @@ def resolve_role_field(obj, field):
|
||||
else:
|
||||
return []
|
||||
|
||||
if obj is None:
|
||||
return []
|
||||
|
||||
if len(field_components) == 1:
|
||||
if type(obj) is not ImplicitRoleDescriptor and type(obj) is not Role:
|
||||
Role_ = get_current_apps().get_model('main', 'Role')
|
||||
if type(obj) is not ImplicitRoleDescriptor and type(obj) is not Role_:
|
||||
raise Exception(smart_text('{} refers to a {}, not an ImplicitRoleField or Role'.format(field, type(obj))))
|
||||
ret.append(obj)
|
||||
else:
|
||||
@ -174,7 +179,10 @@ class ImplicitRoleField(models.ForeignKey):
|
||||
role = getattr(instance, self.name, None)
|
||||
if role:
|
||||
return role
|
||||
role = Role.objects.create(
|
||||
Role_ = get_current_apps().get_model('main', 'Role')
|
||||
role = Role_.objects.create(
|
||||
created=now(),
|
||||
modified=now(),
|
||||
name=self.role_name,
|
||||
description=self.role_description
|
||||
)
|
||||
@ -186,9 +194,16 @@ class ImplicitRoleField(models.ForeignKey):
|
||||
role.save()
|
||||
|
||||
if self.permissions is not None:
|
||||
permissions = RolePermission(
|
||||
RolePermission_ = get_current_apps().get_model('main', 'RolePermission')
|
||||
ContentType = get_current_apps().get_model('contenttypes', "ContentType")
|
||||
instance_content_type = ContentType.objects.get_for_model(instance)
|
||||
|
||||
permissions = RolePermission_(
|
||||
created=now(),
|
||||
modified=now(),
|
||||
role=role,
|
||||
resource=instance,
|
||||
content_type=instance_content_type,
|
||||
object_id=instance.id,
|
||||
auto_generated=True
|
||||
)
|
||||
|
||||
@ -253,7 +268,20 @@ class ImplicitRoleField(models.ForeignKey):
|
||||
parent_roles = set()
|
||||
for path in paths:
|
||||
if path.startswith("singleton:"):
|
||||
parents = [Role.singleton(path[10:])]
|
||||
singleton_name = path[10:]
|
||||
Role_ = get_current_apps().get_model('main', 'Role')
|
||||
qs = Role_.objects.filter(singleton_name=singleton_name)
|
||||
if qs.count() >= 1:
|
||||
role = qs[0]
|
||||
else:
|
||||
role = Role_.objects.create(
|
||||
created=now(),
|
||||
modified=now(),
|
||||
singleton_name=singleton_name,
|
||||
name=singleton_name,
|
||||
description=singleton_name
|
||||
)
|
||||
parents = [role]
|
||||
else:
|
||||
parents = resolve_role_field(instance, path)
|
||||
for parent in parents:
|
||||
|
@ -12,6 +12,7 @@ class Migration(migrations.Migration):
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(rbac.init_rbac_migration),
|
||||
migrations.RunPython(rbac.migrate_users),
|
||||
migrations.RunPython(rbac.migrate_organization),
|
||||
migrations.RunPython(rbac.migrate_team),
|
||||
|
@ -5,7 +5,7 @@ from django.db.models import Q
|
||||
from django.utils.timezone import now
|
||||
|
||||
from collections import defaultdict
|
||||
from awx.main.utils import getattrd
|
||||
from awx.main.utils import getattrd, set_current_apps
|
||||
|
||||
import _old_access as old_access
|
||||
logger = logging.getLogger(__name__)
|
||||
@ -26,6 +26,10 @@ def log_migration(wrapped):
|
||||
return wrapped(*args, **kwargs)
|
||||
return wrapper
|
||||
|
||||
@log_migration
|
||||
def init_rbac_migration(apps, schema_editor):
|
||||
set_current_apps(apps)
|
||||
|
||||
@log_migration
|
||||
def migrate_users(apps, schema_editor):
|
||||
User = apps.get_model('auth', "User")
|
||||
|
@ -20,6 +20,7 @@ import tempfile
|
||||
from rest_framework.exceptions import ParseError, PermissionDenied
|
||||
from django.utils.encoding import smart_str
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.apps import apps
|
||||
|
||||
# PyCrypto
|
||||
from Crypto.Cipher import AES
|
||||
@ -30,7 +31,8 @@ __all__ = ['get_object_or_400', 'get_object_or_403', 'camelcase_to_underscore',
|
||||
'get_ansible_version', 'get_ssh_version', 'get_awx_version', 'update_scm_url',
|
||||
'get_type_for_model', 'get_model_for_type', 'to_python_boolean',
|
||||
'ignore_inventory_computed_fields', 'ignore_inventory_group_removal',
|
||||
'_inventory_updates', 'get_pk_from_dict', 'getattrd', 'NoDefaultProvided']
|
||||
'_inventory_updates', 'get_pk_from_dict', 'getattrd', 'NoDefaultProvided',
|
||||
'get_current_apps', 'set_current_apps']
|
||||
|
||||
|
||||
def get_object_or_400(klass, *args, **kwargs):
|
||||
@ -556,3 +558,11 @@ def getattrd(obj, name, default=NoDefaultProvided):
|
||||
return default
|
||||
raise
|
||||
|
||||
current_apps = apps
|
||||
def set_current_apps(apps):
|
||||
global current_apps
|
||||
current_apps = apps
|
||||
|
||||
def get_current_apps():
|
||||
global current_apps
|
||||
return current_apps
|
||||
|
Loading…
Reference in New Issue
Block a user