Fix setup tool when binding to external auth

We now query the external auth provider for the external service's identifier before adding the linking row into the database. This fixes the case where the external service resolves a different identifier for the same username.

Fixes #1477
This commit is contained in:
Joseph Schorr 2016-05-23 15:08:51 -04:00
parent d6b73a41de
commit 60bbca2185
6 changed files with 151 additions and 62 deletions

View file

@ -29,6 +29,48 @@ def get_federated_service_name(authentication_type):
LDAP_CERT_FILENAME = 'ldap.crt'
def get_users_handler(config, config_provider, override_config_dir):
""" Returns a users handler for the authentication configured in the given config object. """
authentication_type = config.get('AUTHENTICATION_TYPE', 'Database')
if authentication_type == 'Database':
return DatabaseUsers()
if authentication_type == 'LDAP':
ldap_uri = config.get('LDAP_URI', 'ldap://localhost')
base_dn = config.get('LDAP_BASE_DN')
admin_dn = config.get('LDAP_ADMIN_DN')
admin_passwd = config.get('LDAP_ADMIN_PASSWD')
user_rdn = config.get('LDAP_USER_RDN', [])
uid_attr = config.get('LDAP_UID_ATTR', 'uid')
email_attr = config.get('LDAP_EMAIL_ATTR', 'mail')
allow_tls_fallback = config.get('LDAP_ALLOW_INSECURE_FALLBACK', False)
tls_cert_path = None
if config_provider.volume_file_exists(LDAP_CERT_FILENAME):
with config_provider.get_volume_file(LDAP_CERT_FILENAME) as f:
tls_cert_path = f.name
return LDAPUsers(ldap_uri, base_dn, admin_dn, admin_passwd, user_rdn, uid_attr, email_attr,
tls_cert_path, allow_tls_fallback)
if authentication_type == 'JWT':
verify_url = config.get('JWT_VERIFY_ENDPOINT')
issuer = config.get('JWT_AUTH_ISSUER')
max_fresh_s = config.get('JWT_AUTH_MAX_FRESH_S', 300)
return ExternalJWTAuthN(verify_url, issuer, override_config_dir, config['HTTPCLIENT'],
max_fresh_s)
if authentication_type == 'Keystone':
auth_url = config.get('KEYSTONE_AUTH_URL')
keystone_admin_username = config.get('KEYSTONE_ADMIN_USERNAME')
keystone_admin_password = config.get('KEYSTONE_ADMIN_PASSWORD')
keystone_admin_tenant = config.get('KEYSTONE_ADMIN_TENANT')
return KeystoneUsers(auth_url, keystone_admin_username, keystone_admin_password,
keystone_admin_tenant)
raise RuntimeError('Unknown authentication type: %s' % authentication_type)
class UserAuthentication(object):
def __init__(self, app=None, config_provider=None, override_config_dir=None):
self.app_secret_key = None
@ -40,44 +82,7 @@ class UserAuthentication(object):
def init_app(self, app, config_provider, override_config_dir):
self.app_secret_key = app.config['SECRET_KEY']
authentication_type = app.config.get('AUTHENTICATION_TYPE', 'Database')
if authentication_type == 'Database':
users = DatabaseUsers()
elif authentication_type == 'LDAP':
ldap_uri = app.config.get('LDAP_URI', 'ldap://localhost')
base_dn = app.config.get('LDAP_BASE_DN')
admin_dn = app.config.get('LDAP_ADMIN_DN')
admin_passwd = app.config.get('LDAP_ADMIN_PASSWD')
user_rdn = app.config.get('LDAP_USER_RDN', [])
uid_attr = app.config.get('LDAP_UID_ATTR', 'uid')
email_attr = app.config.get('LDAP_EMAIL_ATTR', 'mail')
allow_tls_fallback = app.config.get('LDAP_ALLOW_INSECURE_FALLBACK', False)
tls_cert_path = None
if config_provider.volume_file_exists(LDAP_CERT_FILENAME):
with config_provider.get_volume_file(LDAP_CERT_FILENAME) as f:
tls_cert_path = f.name
users = LDAPUsers(ldap_uri, base_dn, admin_dn, admin_passwd, user_rdn, uid_attr, email_attr,
tls_cert_path, allow_tls_fallback)
elif authentication_type == 'JWT':
verify_url = app.config.get('JWT_VERIFY_ENDPOINT')
issuer = app.config.get('JWT_AUTH_ISSUER')
max_fresh_s = app.config.get('JWT_AUTH_MAX_FRESH_S', 300)
users = ExternalJWTAuthN(verify_url, issuer, override_config_dir,
app.config['HTTPCLIENT'], max_fresh_s)
elif authentication_type == 'Keystone':
auth_url = app.config.get('KEYSTONE_AUTH_URL')
keystone_admin_username = app.config.get('KEYSTONE_ADMIN_USERNAME')
keystone_admin_password = app.config.get('KEYSTONE_ADMIN_PASSWORD')
keystone_admin_tenant = app.config.get('KEYSTONE_ADMIN_TENANT')
users = KeystoneUsers(auth_url, keystone_admin_username, keystone_admin_password,
keystone_admin_tenant)
else:
raise RuntimeError('Unknown authentication type: %s' % authentication_type)
users = get_users_handler(app.config, config_provider, override_config_dir)
# register extension with app
app.extensions = getattr(app, 'extensions', {})