mirror of
https://github.com/ansible/awx.git
synced 2026-03-11 06:29:31 -02:30
Merge branch 'migration' into explicit-implicit-parents
This commit is contained in:
@@ -312,8 +312,15 @@ class InventoryAccess(BaseAccess):
|
|||||||
return qs.select_related('created_by', 'modified_by', 'organization').all()
|
return qs.select_related('created_by', 'modified_by', 'organization').all()
|
||||||
|
|
||||||
def can_read(self, obj):
|
def can_read(self, obj):
|
||||||
|
if self.user.is_superuser:
|
||||||
|
return True
|
||||||
return obj.accessible_by(self.user, {'read': True})
|
return obj.accessible_by(self.user, {'read': True})
|
||||||
|
|
||||||
|
def can_use(self, obj):
|
||||||
|
if self.user.is_superuser:
|
||||||
|
return True
|
||||||
|
return obj.accessible_by(self.user, {'use': True})
|
||||||
|
|
||||||
def can_add(self, data):
|
def can_add(self, data):
|
||||||
# If no data is specified, just checking for generic add permission?
|
# If no data is specified, just checking for generic add permission?
|
||||||
if not data:
|
if not data:
|
||||||
@@ -551,6 +558,11 @@ class CredentialAccess(BaseAccess):
|
|||||||
# Access enforced in our view where we have context enough to make a decision
|
# Access enforced in our view where we have context enough to make a decision
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def can_use(self, obj):
|
||||||
|
if self.user.is_superuser:
|
||||||
|
return True
|
||||||
|
return obj.accessible_by(self.user, {'use': True})
|
||||||
|
|
||||||
def can_change(self, obj, data):
|
def can_change(self, obj, data):
|
||||||
if self.user.is_superuser:
|
if self.user.is_superuser:
|
||||||
return True
|
return True
|
||||||
@@ -770,6 +782,11 @@ class JobTemplateAccess(BaseAccess):
|
|||||||
return False
|
return False
|
||||||
if obj.project is None:
|
if obj.project is None:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
# Given explicit execute access to this JobTemplate
|
||||||
|
if obj.accessible_by(self.user, {'execute':True}):
|
||||||
|
return True
|
||||||
|
|
||||||
# If the user has admin access to the project they can start a job
|
# If the user has admin access to the project they can start a job
|
||||||
if obj.project.accessible_by(self.user, ALL_PERMISSIONS):
|
if obj.project.accessible_by(self.user, ALL_PERMISSIONS):
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -167,6 +167,11 @@ class Migration(migrations.Migration):
|
|||||||
name='updater_role',
|
name='updater_role',
|
||||||
field=awx.main.fields.ImplicitRoleField(related_name='+', role_description=b'May update the inventory', parent_role=None, to='main.Role', role_name=b'Inventory Updater', null=b'True', permissions={b'read': True, b'update': True}),
|
field=awx.main.fields.ImplicitRoleField(related_name='+', role_description=b'May update the inventory', parent_role=None, to='main.Role', role_name=b'Inventory Updater', null=b'True', permissions={b'read': True, b'update': True}),
|
||||||
),
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='inventory',
|
||||||
|
name='usage_role',
|
||||||
|
field=awx.main.fields.ImplicitRoleField(related_name='+', role_description=b'May use this inventory, but not read sensitive portions or modify it', parent_role=None, to='main.Role', role_name=b'Inventory User', null=b'True', permissions={b'use': True}),
|
||||||
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='jobtemplate',
|
model_name='jobtemplate',
|
||||||
name='admin_role',
|
name='admin_role',
|
||||||
|
|||||||
@@ -113,6 +113,11 @@ class Inventory(CommonModel, ResourceMixin):
|
|||||||
role_description='May update the inventory',
|
role_description='May update the inventory',
|
||||||
permissions = {'read': True, 'update': True}
|
permissions = {'read': True, 'update': True}
|
||||||
)
|
)
|
||||||
|
usage_role = ImplicitRoleField(
|
||||||
|
role_name='Inventory User',
|
||||||
|
role_description='May use this inventory, but not read sensitive portions or modify it',
|
||||||
|
permissions = {'use': True}
|
||||||
|
)
|
||||||
executor_role = ImplicitRoleField(
|
executor_role = ImplicitRoleField(
|
||||||
role_name='Inventory Executor',
|
role_name='Inventory Executor',
|
||||||
role_description='May execute jobs against this inventory',
|
role_description='May execute jobs against this inventory',
|
||||||
|
|||||||
47
awx/main/tests/functional/test_rbac_job_start.py
Normal file
47
awx/main/tests/functional/test_rbac_job_start.py
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from awx.main.models.inventory import Inventory
|
||||||
|
from awx.main.models.credential import Credential
|
||||||
|
from awx.main.models.jobs import JobTemplate
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def machine_credential():
|
||||||
|
return Credential.objects.create(name='machine-cred', kind='ssh', username='test_user', password='pas4word')
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
@pytest.mark.job_permissions
|
||||||
|
def test_admin_executing_permissions(deploy_jobtemplate, inventory, machine_credential, user):
|
||||||
|
|
||||||
|
admin_user = user('admin-user', True)
|
||||||
|
|
||||||
|
assert admin_user.can_access(Inventory, 'use', inventory)
|
||||||
|
assert admin_user.can_access(Inventory, 'run_ad_hoc_commands', inventory) # for ad_hoc
|
||||||
|
assert admin_user.can_access(JobTemplate, 'start', deploy_jobtemplate)
|
||||||
|
assert admin_user.can_access(Credential, 'use', machine_credential)
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
@pytest.mark.job_permissions
|
||||||
|
def test_job_template_start_access(deploy_jobtemplate, user):
|
||||||
|
|
||||||
|
common_user = user('test-user', False)
|
||||||
|
deploy_jobtemplate.executor_role.members.add(common_user)
|
||||||
|
|
||||||
|
assert common_user.can_access(JobTemplate, 'start', deploy_jobtemplate)
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
@pytest.mark.job_permissions
|
||||||
|
def test_credential_use_access(machine_credential, user):
|
||||||
|
|
||||||
|
common_user = user('test-user', False)
|
||||||
|
machine_credential.usage_role.members.add(common_user)
|
||||||
|
|
||||||
|
assert common_user.can_access(Credential, 'use', machine_credential)
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
@pytest.mark.job_permissions
|
||||||
|
def test_inventory_use_access(inventory, user):
|
||||||
|
|
||||||
|
common_user = user('test-user', False)
|
||||||
|
inventory.usage_role.members.add(common_user)
|
||||||
|
|
||||||
|
assert common_user.can_access(Inventory, 'use', inventory)
|
||||||
@@ -29,7 +29,8 @@ export default
|
|||||||
awTipPlacement: "top",
|
awTipPlacement: "top",
|
||||||
},
|
},
|
||||||
status: {
|
status: {
|
||||||
label: 'Status',
|
label: '',
|
||||||
|
searchLabel: 'Status',
|
||||||
columnClass: 'col-lg-1 col-md-2 col-sm-2 col-xs-2',
|
columnClass: 'col-lg-1 col-md-2 col-sm-2 col-xs-2',
|
||||||
awToolTip: "{{ job.status_tip }}",
|
awToolTip: "{{ job.status_tip }}",
|
||||||
awTipPlacement: "top",
|
awTipPlacement: "top",
|
||||||
|
|||||||
Reference in New Issue
Block a user