import logging

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__)

class KeystoneUsers(FederatedUsers):
  """ Delegates authentication to OpenStack Keystone. """
  def __init__(self, auth_url, admin_username, admin_password, admin_tenant):
    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

  def verify_credentials(self, username_or_email, password):
    try:
      keystone_client = kclient.Client(username=username_or_email, password=password,
                                       auth_url=self.auth_url)
      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)
      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)
