From 33ac8a96685c77a8ca84cfff0d71b4def51776e1 Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Fri, 16 Mar 2018 10:40:08 -0400 Subject: [PATCH] System wide toggle for org admin user/team abilities --- awx/api/conf.py | 2 +- awx/main/access.py | 23 +++++++++++++++++------ awx/main/conf.py | 26 +++++++++++++++++++++++--- awx/settings/defaults.py | 4 +++- 4 files changed, 44 insertions(+), 11 deletions(-) diff --git a/awx/api/conf.py b/awx/api/conf.py index 3fcfb13584..b91cdae254 100644 --- a/awx/api/conf.py +++ b/awx/api/conf.py @@ -35,7 +35,7 @@ register( register( 'OAUTH2_PROVIDER', field_class=OAuth2ProviderField, - default={'ACCESS_TOKEN_EXPIRE_SECONDS': 315360000000, + default={'ACCESS_TOKEN_EXPIRE_SECONDS': 315360000000, 'AUTHORIZATION_CODE_EXPIRE_SECONDS': 600}, label=_('OAuth 2 Timeout Settings'), help_text=_('Dictionary for customizing OAuth 2 timeouts, available items are ' diff --git a/awx/main/access.py b/awx/main/access.py index 28991af3e0..c32462c78d 100644 --- a/awx/main/access.py +++ b/awx/main/access.py @@ -505,7 +505,9 @@ class UserAccess(BaseAccess): return False if self.user.is_superuser: return True - return Organization.accessible_objects(self.user, 'admin_role').exists() + if settings.ORGS_CAN_CREATE_USERS: + return Organization.accessible_objects(self.user, 'admin_role').exists() + return False def can_change(self, obj, data): if data is not None and ('is_superuser' in data or 'is_system_auditor' in data): @@ -1078,7 +1080,9 @@ class TeamAccess(BaseAccess): def can_add(self, data): if not data: # So the browseable API will work return Organization.accessible_objects(self.user, 'admin_role').exists() - return self.check_related('organization', Organization, data) + if settings.ORGS_CAN_ASSIGN_USERS_TEAM: + return self.check_related('organization', Organization, data) + return False def can_change(self, obj, data): # Prevent moving a team to a different organization. @@ -1105,8 +1109,13 @@ class TeamAccess(BaseAccess): role_access = RoleAccess(self.user) return role_access.can_attach(sub_obj, obj, 'member_role.parents', *args, **kwargs) - return super(TeamAccess, self).can_attach(obj, sub_obj, relationship, - *args, **kwargs) + if self.user.is_superuser: + return True + + if settings.ORGS_CAN_ASSIGN_USERS_TEAM: + return super(TeamAccess, self).can_attach(obj, sub_obj, relationship, + *args, **kwargs) + return False def can_unattach(self, obj, sub_obj, relationship, *args, **kwargs): if isinstance(sub_obj, Role): @@ -1114,8 +1123,10 @@ class TeamAccess(BaseAccess): role_access = RoleAccess(self.user) return role_access.can_unattach(sub_obj, obj, 'member_role.parents', *args, **kwargs) - return super(TeamAccess, self).can_unattach(obj, sub_obj, relationship, - *args, **kwargs) + if settings.ORGS_CAN_ASSIGN_USERS_TEAM: + return super(TeamAccess, self).can_unattach(obj, sub_obj, relationship, + *args, **kwargs) + return False class ProjectAccess(BaseAccess): diff --git a/awx/main/conf.py b/awx/main/conf.py index f68ee6688c..79aeb5397f 100644 --- a/awx/main/conf.py +++ b/awx/main/conf.py @@ -43,6 +43,29 @@ register( category_slug='system', ) +register( + 'ORGS_CAN_CREATE_USERS', + field_class=fields.BooleanField, + label=_('Organization Admins can create users.'), + help_text=_('Enable Organizations to create users. You may want to ' + 'disable this if you populate your users from some external source ' + 'like LDAP or SAML.'), + category=_('System'), + category_slug='system', +) + +register( + 'ORGS_CAN_ASSIGN_USERS_TEAM', + field_class=fields.BooleanField, + label=_('Organization Admins can assign users to teams.'), + help_text=_('Enable Organizations to assign users to teams. You may want to ' + 'disable this if you populate your users from some external source ' + 'like LDAP or SAML. This will prevent team assignments for ' + 'Organization and Team admins.'), + category=_('System'), + category_slug='system', +) + register( 'TOWER_ADMIN_ALERTS', field_class=fields.BooleanField, @@ -90,7 +113,6 @@ register( category_slug='system', ) - def _load_default_license_from_file(): try: license_file = os.environ.get('AWX_LICENSE_FILE', '/etc/tower/license') @@ -102,7 +124,6 @@ def _load_default_license_from_file(): logger.warning('Could not read license from "%s".', license_file, exc_info=True) return {} - register( 'LICENSE', field_class=fields.DictField, @@ -484,7 +505,6 @@ register( category_slug='logging', ) - def logging_validate(serializer, attrs): if not serializer.instance or \ not hasattr(serializer.instance, 'LOG_AGGREGATOR_HOST') or \ diff --git a/awx/settings/defaults.py b/awx/settings/defaults.py index 3449c934c5..77af490dbe 100644 --- a/awx/settings/defaults.py +++ b/awx/settings/defaults.py @@ -340,7 +340,7 @@ AUTHENTICATION_BACKENDS = ( OAUTH2_PROVIDER_APPLICATION_MODEL = 'main.OAuth2Application' OAUTH2_PROVIDER_ACCESS_TOKEN_MODEL = 'main.OAuth2AccessToken' -OAUTH2_PROVIDER = {'ACCESS_TOKEN_EXPIRE_SECONDS': 31536000000, +OAUTH2_PROVIDER = {'ACCESS_TOKEN_EXPIRE_SECONDS': 31536000000, 'AUTHORIZATION_CODE_EXPIRE_SECONDS': 600} # LDAP server (default to None to skip using LDAP authentication). @@ -945,6 +945,8 @@ FACT_CACHE_PORT = 6564 # Note: This setting may be overridden by database settings. ORG_ADMINS_CAN_SEE_ALL_USERS = True +ORGS_CAN_CREATE_USERS = True +ORGS_CAN_ASSIGN_USERS_TEAM = True # Note: This setting may be overridden by database settings. TOWER_ADMIN_ALERTS = True