import logging import os from keystoneclient.v2_0 import client as kclient from keystoneclient.exceptions import AuthorizationFailure as KeystoneAuthorizationFailure from keystoneclient.exceptions import Unauthorized as KeystoneUnauthorized from data.users.federated import FederatedUsers, VerifiedCredentials logger = logging.getLogger(__name__) DEFAULT_TIMEOUT = 10 # seconds class KeystoneUsers(FederatedUsers): """ Delegates authentication to OpenStack Keystone. """ def __init__(self, auth_url, admin_username, admin_password, admin_tenant, timeout=None): super(KeystoneUsers, self).__init__('keystone') self.auth_url = auth_url self.admin_username = admin_username self.admin_password = admin_password self.admin_tenant = admin_tenant self.timeout = timeout or DEFAULT_TIMEOUT self.debug = os.environ.get('USERS_DEBUG') == '1' def verify_credentials(self, username_or_email, password): try: keystone_client = kclient.Client(username=username_or_email, password=password, auth_url=self.auth_url, timeout=self.timeout, debug=self.debug) user_id = keystone_client.user_id except KeystoneAuthorizationFailure as kaf: logger.exception('Keystone auth failure for user: %s', username_or_email) return (None, kaf.message or 'Invalid username or password') except KeystoneUnauthorized as kut: logger.exception('Keystone unauthorized for user: %s', username_or_email) return (None, kut.message or 'Invalid username or password') try: admin_client = kclient.Client(username=self.admin_username, password=self.admin_password, tenant_name=self.admin_tenant, auth_url=self.auth_url, timeout=self.timeout, debug=self.debug) user = admin_client.users.get(user_id) except KeystoneUnauthorized as kut: logger.exception('Keystone unauthorized admin') return (None, 'Keystone admin credentials are invalid: %s' % kut.message) return (VerifiedCredentials(username=username_or_email, email=user.email), None)