mirror of
https://github.com/ansible/awx.git
synced 2026-03-19 18:07:33 -02:30
Added UserResource
This commit is contained in:
@@ -249,4 +249,32 @@ class Migration(migrations.Migration):
|
|||||||
name='resource',
|
name='resource',
|
||||||
field=awx.main.fields.ImplicitResourceField(related_name='+', to='main.Resource', null=b'True'),
|
field=awx.main.fields.ImplicitResourceField(related_name='+', to='main.Resource', null=b'True'),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='UserResource',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||||
|
('created', models.DateTimeField(default=None, editable=False)),
|
||||||
|
('modified', models.DateTimeField(default=None, editable=False)),
|
||||||
|
('description', models.TextField(default=b'', blank=True)),
|
||||||
|
('active', models.BooleanField(default=True, editable=False)),
|
||||||
|
('name', models.CharField(max_length=512)),
|
||||||
|
('admin_role', awx.main.fields.ImplicitRoleField(related_name='+', to='main.Role', null=b'True')),
|
||||||
|
('created_by', models.ForeignKey(related_name="{u'class': 'userresource', u'app_label': 'main'}(class)s_created+", on_delete=django.db.models.deletion.SET_NULL, default=None, editable=False, to=settings.AUTH_USER_MODEL, null=True)),
|
||||||
|
('modified_by', models.ForeignKey(related_name="{u'class': 'userresource', u'app_label': 'main'}(class)s_modified+", on_delete=django.db.models.deletion.SET_NULL, default=None, editable=False, to=settings.AUTH_USER_MODEL, null=True)),
|
||||||
|
('resource', awx.main.fields.ImplicitResourceField(related_name='+', to='main.Resource', null=b'True')),
|
||||||
|
('tags', taggit.managers.TaggableManager(to='taggit.Tag', through='taggit.TaggedItem', blank=True, help_text='A comma-separated list of tags.', verbose_name='Tags')),
|
||||||
|
('user', awx.main.fields.AutoOneToOneField(related_name='resource', editable=False, to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'main_rbac_user_resource',
|
||||||
|
'verbose_name': 'user_resource',
|
||||||
|
'verbose_name_plural': 'user_resources',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.AlterUniqueTogether(
|
||||||
|
name='userresource',
|
||||||
|
unique_together=set([('user', 'admin_role')]),
|
||||||
|
),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -5,7 +5,12 @@ def migrate_users(apps, schema_editor):
|
|||||||
migrations = list()
|
migrations = list()
|
||||||
User = apps.get_model('auth', "User")
|
User = apps.get_model('auth', "User")
|
||||||
Role = apps.get_model('main', "Role")
|
Role = apps.get_model('main', "Role")
|
||||||
|
UserResource = apps.get_model('main', "UserResource")
|
||||||
|
|
||||||
for user in User.objects.all():
|
for user in User.objects.all():
|
||||||
|
ur = UserResource.objects.create(user=user)
|
||||||
|
ur.admin_role.members.add(user)
|
||||||
|
|
||||||
if user.is_superuser:
|
if user.is_superuser:
|
||||||
Role.singleton('System Administrator').members.add(user)
|
Role.singleton('System Administrator').members.add(user)
|
||||||
migrations.append(user)
|
migrations.append(user)
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ from awx.main.models.activity_stream import * # noqa
|
|||||||
from awx.main.models.ha import * # noqa
|
from awx.main.models.ha import * # noqa
|
||||||
from awx.main.models.configuration import * # noqa
|
from awx.main.models.configuration import * # noqa
|
||||||
from awx.main.models.rbac import * # noqa
|
from awx.main.models.rbac import * # noqa
|
||||||
|
from awx.main.models.user import * # noqa
|
||||||
from awx.main.models.mixins import * # noqa
|
from awx.main.models.mixins import * # noqa
|
||||||
|
|
||||||
# Monkeypatch Django serializer to ignore django-taggit fields (which break
|
# Monkeypatch Django serializer to ignore django-taggit fields (which break
|
||||||
|
|||||||
30
awx/main/models/user.py
Normal file
30
awx/main/models/user.py
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# Copyright (c) 2015 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.db import models
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from awx.main.models.base import CommonModelNameNotUnique
|
||||||
|
from awx.main.models.mixins import ResourceMixin
|
||||||
|
from awx.main.fields import AutoOneToOneField, ImplicitRoleField
|
||||||
|
|
||||||
|
|
||||||
|
class UserResource(CommonModelNameNotUnique, ResourceMixin):
|
||||||
|
class Meta:
|
||||||
|
app_label = 'main'
|
||||||
|
verbose_name = _('user_resource')
|
||||||
|
verbose_name_plural = _('user_resources')
|
||||||
|
unique_together = [('user', 'admin_role'),]
|
||||||
|
db_table = 'main_rbac_user_resource'
|
||||||
|
|
||||||
|
user = AutoOneToOneField(
|
||||||
|
'auth.User',
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
related_name='resource',
|
||||||
|
editable=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
admin_role = ImplicitRoleField(
|
||||||
|
role_name='User Administrator',
|
||||||
|
permissions = {'all': True},
|
||||||
|
)
|
||||||
@@ -147,6 +147,34 @@ def sync_user_to_team_members_role(sender, reverse, model, instance, pk_set, act
|
|||||||
instance.member_role.members.remove(user)
|
instance.member_role.members.remove(user)
|
||||||
|
|
||||||
|
|
||||||
|
def sync_user_to_org_members_role(sender, reverse, model, instance, pk_set, action, **kwargs):
|
||||||
|
'When a user is added or removed from Organization.users, ensure that is reflected in Organization.member_role'
|
||||||
|
if action == 'post_add' or action == 'pre_remove':
|
||||||
|
if reverse:
|
||||||
|
for org in Organization.objects.filter(id__in=pk_set).all():
|
||||||
|
if action == 'post_add':
|
||||||
|
org.member_role.members.add(instance)
|
||||||
|
org.admin_role.children.add(instance.resource.admin_role)
|
||||||
|
if action == 'pre_remove':
|
||||||
|
org.member_role.members.remove(instance)
|
||||||
|
org.admin_role.children.remove(instance.resource.admin_role)
|
||||||
|
else:
|
||||||
|
for user in User.objects.filter(id__in=pk_set).all():
|
||||||
|
if action == 'post_add':
|
||||||
|
instance.member_role.members.add(user)
|
||||||
|
instance.admin_role.children.add(user.resource.admin_role)
|
||||||
|
if action == 'pre_remove':
|
||||||
|
instance.member_role.members.remove(user)
|
||||||
|
instance.admin_role.children.remove(user.resource.admin_role)
|
||||||
|
|
||||||
|
def create_user_resource(sender, **kwargs):
|
||||||
|
instance = kwargs['instance']
|
||||||
|
try:
|
||||||
|
UserResource.objects.get(user=instance)
|
||||||
|
except UserResource.DoesNotExist:
|
||||||
|
ur = UserResource.objects.create(user=instance)
|
||||||
|
ur.admin_role.members.add(instance)
|
||||||
|
|
||||||
pre_save.connect(store_initial_active_state, sender=Host)
|
pre_save.connect(store_initial_active_state, sender=Host)
|
||||||
post_save.connect(emit_update_inventory_on_created_or_deleted, sender=Host)
|
post_save.connect(emit_update_inventory_on_created_or_deleted, sender=Host)
|
||||||
post_delete.connect(emit_update_inventory_on_created_or_deleted, sender=Host)
|
post_delete.connect(emit_update_inventory_on_created_or_deleted, sender=Host)
|
||||||
@@ -168,7 +196,8 @@ post_save.connect(emit_ad_hoc_command_event_detail, sender=AdHocCommandEvent)
|
|||||||
m2m_changed.connect(rebuild_role_ancestor_list, Role.parents.through)
|
m2m_changed.connect(rebuild_role_ancestor_list, Role.parents.through)
|
||||||
post_save.connect(sync_superuser_status_to_rbac, sender=User)
|
post_save.connect(sync_superuser_status_to_rbac, sender=User)
|
||||||
m2m_changed.connect(sync_user_to_team_members_role, Team.users.through)
|
m2m_changed.connect(sync_user_to_team_members_role, Team.users.through)
|
||||||
#m2m_changed.connect(rebuild_group_parent_roles, Group.parents.through)
|
post_save.connect(create_user_resource, sender=User)
|
||||||
|
m2m_changed.connect(sync_user_to_org_members_role, Organization.users.through)
|
||||||
|
|
||||||
# Migrate hosts, groups to parent group(s) whenever a group is deleted or
|
# Migrate hosts, groups to parent group(s) whenever a group is deleted or
|
||||||
# marked as inactive.
|
# marked as inactive.
|
||||||
|
|||||||
15
awx/main/tests/functional/test_rbac_userresource.py
Normal file
15
awx/main/tests/functional/test_rbac_userresource.py
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_user_resource_org_admin(user, organization):
|
||||||
|
admin = user('orgadmin')
|
||||||
|
member = user('orgmember')
|
||||||
|
|
||||||
|
member.organizations.add(organization)
|
||||||
|
assert not member.resource.accessible_by(admin, {'write':True})
|
||||||
|
|
||||||
|
organization.admin_role.members.add(admin)
|
||||||
|
assert member.resource.accessible_by(admin, {'write':True})
|
||||||
|
|
||||||
|
organization.admin_role.members.remove(admin)
|
||||||
|
assert not member.resource.accessible_by(admin, {'write':True})
|
||||||
Reference in New Issue
Block a user