mirror of
https://github.com/ansible/awx.git
synced 2026-01-10 15:32:07 -03:30
Expand scope of enterprise user types.
This commit is contained in:
parent
8061667ace
commit
70cccb0e57
@ -98,6 +98,20 @@ def user_is_system_auditor(user, tf):
|
||||
|
||||
User.add_to_class('is_system_auditor', user_is_system_auditor)
|
||||
|
||||
|
||||
def user_is_in_enterprise_category(user, category):
|
||||
ret = (category,) in user.enterprise_auth.all().values_list('provider') and not user.has_usable_password()
|
||||
# NOTE: this if-else block ensures existing enterprise users are still able to
|
||||
# log in. Remove it in a future release
|
||||
if category == 'radius':
|
||||
ret = ret or not user.has_usable_password()
|
||||
elif category == 'saml':
|
||||
ret = ret or user.social_auth.all()
|
||||
return ret
|
||||
|
||||
|
||||
User.add_to_class('is_in_enterprise_category', user_is_in_enterprise_category)
|
||||
|
||||
# Import signal handlers only after models have been defined.
|
||||
import awx.main.signals # noqa
|
||||
|
||||
|
||||
@ -126,23 +126,25 @@ class LDAPBackend(BaseLDAPBackend):
|
||||
return set()
|
||||
|
||||
|
||||
def _decorate_enterprise_user(user, provider):
|
||||
user.set_unusable_password()
|
||||
user.save()
|
||||
enterprise_auth = UserEnterpriseAuth(user=user, provider=provider)
|
||||
enterprise_auth.save()
|
||||
return enterprise_auth
|
||||
|
||||
|
||||
def _get_or_set_enterprise_user(username, password, provider):
|
||||
created = False
|
||||
try:
|
||||
user = User.objects.all().prefetch_related('enterprise_auth').get(username=username)
|
||||
except User.DoesNotExist:
|
||||
user = User(username=username)
|
||||
user.set_unusable_password()
|
||||
user.save()
|
||||
enterprise_auth = UserEnterpriseAuth(user=user, provider=provider)
|
||||
enterprise_auth.save()
|
||||
enterprise_auth = _decorate_enterprise_user(user, provider)
|
||||
logger.debug("Created enterprise user %s via %s backend." %
|
||||
(username, enterprise_auth.get_provider_display()))
|
||||
created = True
|
||||
# NOTE: remove has_usable_password logic in a future release.
|
||||
if created or\
|
||||
not user.has_usable_password() or\
|
||||
(provider,) in user.enterprise_auth.all().values_list('provider') and not user.has_usable_password():
|
||||
if created or user.is_in_enterprise_category(provider):
|
||||
return user
|
||||
logger.warn("Enterprise user %s already defined in Tower." % username)
|
||||
|
||||
@ -258,7 +260,17 @@ class SAMLAuth(BaseSAMLAuth):
|
||||
if not feature_enabled('enterprise_auth'):
|
||||
logger.error("Unable to authenticate, license does not support SAML authentication")
|
||||
return None
|
||||
return super(SAMLAuth, self).authenticate(*args, **kwargs)
|
||||
created = False
|
||||
try:
|
||||
user = User.objects.get(username=kwargs.get('username', ''))
|
||||
if user and not user.is_in_enterprise_category('saml'):
|
||||
return None
|
||||
except User.DoesNotExist:
|
||||
created = True
|
||||
user = super(SAMLAuth, self).authenticate(*args, **kwargs)
|
||||
if user and created:
|
||||
_decorate_enterprise_user(user, 'saml')
|
||||
return user
|
||||
|
||||
def get_user(self, user_id):
|
||||
if not all([django_settings.SOCIAL_AUTH_SAML_SP_ENTITY_ID, django_settings.SOCIAL_AUTH_SAML_SP_PUBLIC_CERT,
|
||||
|
||||
19
awx/sso/migrations/0002_expand_provider_options.py
Normal file
19
awx/sso/migrations/0002_expand_provider_options.py
Normal file
@ -0,0 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('sso', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='userenterpriseauth',
|
||||
name='provider',
|
||||
field=models.CharField(max_length=32, choices=[(b'radius', 'RADIUS'), (b'tacacs+', 'TACACS+'), (b'saml', 'SAML')]),
|
||||
),
|
||||
]
|
||||
@ -13,6 +13,7 @@ class UserEnterpriseAuth(models.Model):
|
||||
PROVIDER_CHOICES = (
|
||||
('radius', _('RADIUS')),
|
||||
('tacacs+', _('TACACS+')),
|
||||
('saml', _('SAML')),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
|
||||
@ -16,9 +16,9 @@ On the other hand, the rest of authentication methods use the same types of logi
|
||||
Tower will try authenticating against each enabled authentication method *in the specified order*, meaning if the same username and password is valid in multiple enabled auth methods (For example, both LDAP and TACACS+), Tower will only use the first positive match (In the above example, log a user in via LDAP and skip TACACS+).
|
||||
|
||||
## Notes:
|
||||
* RADIUS users and TACACS+ users are categorized as 'Enterprise' users. The following rules apply to Enterprise users:
|
||||
* SAML users, RADIUS users and TACACS+ users are categorized as 'Enterprise' users. The following rules apply to Enterprise users:
|
||||
|
||||
* Enterprise users can only be created via the first successful login attempt from remote authentication backend.
|
||||
* Enterprise users cannot be created/authenticated if non-enterprise users with the same name has already been created in Tower.
|
||||
* Tower passwords of Enterprise users should always be empty and cannot be set by any user if there are enterprise backends enabled.
|
||||
* If enterprise backends (RADIUS and TACACS+ for now) are disabled, an Enterprise user can be converted to a normal Tower user by setting password field. But this operation is irreversible (The converted Tower user can no longer be treated as Enterprise user)
|
||||
* If enterprise backends are disabled, an Enterprise user can be converted to a normal Tower user by setting password field. But this operation is irreversible (The converted Tower user can no longer be treated as Enterprise user)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user