def assert_admin(self, context):
        if not context['is_admin']:
            try:
                user_token_ref = self.token_api.get_token(
                    context=context, token_id=context['token_id'])
            except exception.TokenNotFound as e:
                raise exception.Unauthorized(e)

            creds = user_token_ref['metadata'].copy()

            try:
                creds['user_id'] = user_token_ref['user'].get('id')
            except AttributeError:
                logging.debug('Invalid user')
                raise exception.Unauthorized()

            try:
                creds['tenant_id'] = user_token_ref['tenant'].get('id')
            except AttributeError:
                logging.debug('Invalid tenant')
                raise exception.Unauthorized()

            # NOTE(vish): this is pretty inefficient
            creds['roles'] = [self.identity_api.get_role(context, role)['name']
                              for role in creds.get('roles', [])]
            # Accept either is_admin or the admin role
            self.policy_api.enforce(context, creds, 'admin_required', {})
Example #2
0
def check_output(*popenargs, **kwargs):
    r"""Run command with arguments and return its output as a byte string.

    If the exit code was non-zero it raises a CalledProcessError.  The
    CalledProcessError object will have the return code in the returncode
    attribute and output in the output attribute.

    The arguments are the same as for the Popen constructor.  Example:

    >>> check_output(["ls", "-l", "/dev/null"])
    'crw-rw-rw- 1 root root 1, 3 Oct 18  2007 /dev/null\n'

    The stdout argument is not allowed as it is used internally.
    To capture standard error in the result, use stderr=STDOUT.

    >>> check_output(["/bin/sh", "-c",
    ...               "ls -l non_existent_file ; exit 0"],
    ...              stderr=STDOUT)
    'ls: non_existent_file: No such file or directory\n'
    """
    if 'stdout' in kwargs:
        raise ValueError('stdout argument not allowed, it will be overridden.')
    logging.debug(' '.join(popenargs[0]))
    process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
    output, unused_err = process.communicate()
    retcode = process.poll()
    if retcode:
        cmd = kwargs.get("args")
        if cmd is None:
            cmd = popenargs[0]
        raise subprocess.CalledProcessError(retcode, cmd)
    return output
Example #3
0
    def assert_admin(self, context):
        if not context["is_admin"]:
            try:
                user_token_ref = self.token_api.get_token(context=context, token_id=context["token_id"])
            except exception.TokenNotFound:
                raise exception.Unauthorized()

            creds = user_token_ref["metadata"].copy()

            try:
                creds["user_id"] = user_token_ref["user"].get("id")
            except AttributeError:
                logging.debug("Invalid user")
                raise exception.Unauthorized()

            try:
                creds["tenant_id"] = user_token_ref["tenant"].get("id")
            except AttributeError:
                logging.debug("Invalid tenant")
                raise exception.Unauthorized()

            # NOTE(vish): this is pretty inefficient
            creds["roles"] = [self.identity_api.get_role(context, role)["name"] for role in creds.get("roles", [])]
            # Accept either is_admin or the admin role
            self.policy_api.enforce(context, creds, "admin_required", {})
Example #4
0
def check_output(*popenargs, **kwargs):
  r"""Run command with arguments and return its output as a byte string.

  If the exit code was non-zero it raises a CalledProcessError.  The
  CalledProcessError object will have the return code in the returncode
  attribute and output in the output attribute.

  The arguments are the same as for the Popen constructor.  Example:

  >>> check_output(["ls", "-l", "/dev/null"])
  'crw-rw-rw- 1 root root 1, 3 Oct 18  2007 /dev/null\n'

  The stdout argument is not allowed as it is used internally.
  To capture standard error in the result, use stderr=STDOUT.

  >>> check_output(["/bin/sh", "-c",
  ...               "ls -l non_existent_file ; exit 0"],
  ...              stderr=STDOUT)
  'ls: non_existent_file: No such file or directory\n'
  """
  if 'stdout' in kwargs:
    raise ValueError('stdout argument not allowed, it will be overridden.')
  logging.debug(' '.join(popenargs[0]))
  process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
  output, unused_err = process.communicate()
  retcode = process.poll()
  if retcode:
    cmd = kwargs.get("args")
    if cmd is None:
      cmd = popenargs[0]
    raise subprocess.CalledProcessError(retcode, cmd)
  return output
Example #5
0
    def set_user_password(self, context, user_id, user):
        token_id = context.get('token_id')
        original_password = user.get('original_password')

        token_ref = self.token_api.get_token(token_id)
        user_id_from_token = token_ref['user']['id']

        if user_id_from_token != user_id:
            raise exception.Forbidden('Token belongs to another user')
        if original_password is None:
            raise exception.ValidationError(target='user',
                                            attribute='original password')

        try:
            user_ref = self.identity_api.authenticate(
                user_id=user_id_from_token, password=original_password)
            if not user_ref.get('enabled', True):
                # NOTE(dolph): why can't you set a disabled user's password?
                raise exception.Unauthorized('User is disabled')
        except AssertionError:
            raise exception.Unauthorized()

        update_dict = {'password': user['password'], 'id': user_id}

        admin_context = copy.copy(context)
        admin_context['is_admin'] = True
        super(UserController, self).set_user_password(admin_context, user_id,
                                                      update_dict)

        token_id = uuid.uuid4().hex
        new_token_ref = copy.copy(token_ref)
        new_token_ref['id'] = token_id
        self.token_api.create_token(token_id, new_token_ref)
        logging.debug('TOKEN_REF %s', new_token_ref)
        return {'access': {'token': new_token_ref}}
Example #6
0
    def assert_admin(self, context):
        if not context['is_admin']:
            try:
                user_token_ref = self.token_api.get_token(
                    context=context, token_id=context['token_id'])
            except exception.TokenNotFound:
                raise exception.Unauthorized()

            creds = user_token_ref['metadata'].copy()

            try:
                creds['user_id'] = user_token_ref['user'].get('id')
            except AttributeError:
                logging.debug('Invalid user')
                raise exception.Unauthorized()

            try:
                creds['tenant_id'] = user_token_ref['tenant'].get('id')
            except AttributeError:
                logging.debug('Invalid tenant')
                raise exception.Unauthorized()

            # NOTE(vish): this is pretty inefficient
            creds['roles'] = [
                self.identity_api.get_role(context, role)['name']
                for role in creds.get('roles', [])
            ]
            # Accept either is_admin or the admin role
            self.policy_api.enforce(context, creds, 'admin_required', {})
Example #7
0
 def _calc_signature_2(self, params, verb, server_string, path):
     """Generate AWS signature version 2 string."""
     logging.debug('using _calc_signature_2')
     string_to_sign = '%s\n%s\n%s\n' % (verb, server_string, path)
     if self.hmac_256:
         current_hmac = self.hmac_256
         params['SignatureMethod'] = 'HmacSHA256'
     else:
         current_hmac = self.hmac
         params['SignatureMethod'] = 'HmacSHA1'
     keys = params.keys()
     keys.sort()
     pairs = []
     for key in keys:
         val = self._get_utf8_value(params[key])
         val = urllib.quote(val, safe='-_~')
         pairs.append(urllib.quote(key, safe='') + '=' + val)
     qs = '&'.join(pairs)
     logging.debug('query string: %s', qs)
     string_to_sign += qs
     logging.debug('string_to_sign: %s', string_to_sign)
     current_hmac.update(string_to_sign)
     b64 = base64.b64encode(current_hmac.digest())
     logging.debug('len(b64)=%d', len(b64))
     logging.debug('base64 encoded digest: %s', b64)
     return b64
Example #8
0
    def set_user_password(self, context, user_id, user):
        token_id = context.get("token_id")
        original_password = user.get("original_password")

        token_ref = self.token_api.get_token(token_id)
        user_id_from_token = token_ref["user"]["id"]

        if user_id_from_token != user_id:
            raise exception.Forbidden("Token belongs to another user")
        if original_password is None:
            raise exception.ValidationError(target="user", attribute="original password")

        try:
            user_ref = self.identity_api.authenticate(user_id=user_id_from_token, password=original_password)
            if not user_ref.get("enabled", True):
                # NOTE(dolph): why can't you set a disabled user's password?
                raise exception.Unauthorized("User is disabled")
        except AssertionError:
            raise exception.Unauthorized()

        update_dict = {"password": user["password"], "id": user_id}

        admin_context = copy.copy(context)
        admin_context["is_admin"] = True
        super(UserController, self).set_user_password(admin_context, user_id, update_dict)

        token_id = uuid.uuid4().hex
        new_token_ref = copy.copy(token_ref)
        new_token_ref["id"] = token_id
        self.token_api.create_token(token_id, new_token_ref)
        logging.debug("TOKEN_REF %s", new_token_ref)
        return {"access": {"token": new_token_ref}}
Example #9
0
def import_class(import_str):
    """Returns a class from a string including module and class."""
    mod_str, _sep, class_str = import_str.rpartition('.')
    try:
        __import__(mod_str)
        return getattr(sys.modules[mod_str], class_str)
    except (ImportError, ValueError, AttributeError), exc:
        logging.debug('Inner Exception: %s', exc)
        raise
Example #10
0
def import_class(import_str):
    """Returns a class from a string including module and class."""
    mod_str, _sep, class_str = import_str.rpartition('.')
    try:
        __import__(mod_str)
        return getattr(sys.modules[mod_str], class_str)
    except (ImportError, ValueError, AttributeError), exc:
        logging.debug('Inner Exception: %s', exc)
        raise
  def test_authenticate_scoped(self):
    # NOTE(termie): the docs arbitrarily changed and inserted a 'u' in front
    #               of one of the user ids, but none of the others
    raise exc.SkipTest('The docs have arbitrarily changed.')
    client = self.client(self.app)
    post_data = json.dumps(
        {'auth': {'passwordCredentials': {'username': self.user_123['id'],
                                          'password': self.user_123['password'],
                                          },
                  'tenantName': self.tenant_345['name']}})

    resp = client.post('/v2.0/tokens', body=post_data)
    data = json.loads(resp.body)
    logging.debug('KEYS: %s', data['access'].keys())
    self.assert_('expires' in data['access']['token'])
    self.assertDeepEquals(self.auth_response['access']['user'],
                          data['access']['user'])
Example #12
0
    def set_user_password(self, context, user_id, user):
        token_id = context.get('token_id')
        original_password = user.get('original_password')

        token_ref = self.token_api.get_token(context=context,
                                             token_id=token_id)
        user_id_from_token = token_ref['user']['id']

        if user_id_from_token != user_id:
            raise exception.Forbidden('Token belongs to another user')
        if original_password is None:
            raise exception.ValidationError(target='user',
                                            attribute='original password')

        try:
            user_ref = self.identity_api.authenticate(
                context=context,
                user_id=user_id_from_token,
                password=original_password)[0]
            if not user_ref.get('enabled', True):
                # NOTE(dolph): why can't you set a disabled user's password?
                raise exception.Unauthorized('User is disabled')
        except AssertionError:
            raise exception.Unauthorized()

        update_dict = {'password': user['password'], 'id': user_id}

        admin_context = copy.copy(context)
        admin_context['is_admin'] = True
        super(UserController, self).set_user_password(admin_context,
                                                      user_id,
                                                      update_dict)

        token_id = uuid.uuid4().hex
        new_token_ref = copy.copy(token_ref)
        new_token_ref['id'] = token_id
        self.token_api.create_token(context=context, token_id=token_id,
                                    data=new_token_ref)
        logging.debug('TOKEN_REF %s', new_token_ref)
        return {'access': {'token': new_token_ref}}
Example #13
0
    def set_user_password(self, context, user_id, user):
        token_id = context.get('token_id')
        original_password = user.get('original_password')

        token_ref = self.token_api.get_token(context=context,
                                             token_id=token_id)
        user_id_from_token = token_ref['user']['id']

        if user_id_from_token != user_id or original_password is None:
            raise exception.Forbidden()

        try:
            user_ref = self.identity_api.authenticate(
                context=context,
                user_id=user_id_from_token,
                password=original_password)[0]
            if not user_ref.get('enabled', True):
                raise exception.Unauthorized()
        except AssertionError:
            raise exception.Unauthorized()

        update_dict = {'password': user['password'], 'id': user_id}

        admin_context = copy.copy(context)
        admin_context['is_admin'] = True
        self.user_controller.set_user_password(admin_context,
                                               user_id,
                                               update_dict)

        token_id = uuid.uuid4().hex
        new_token_ref = copy.copy(token_ref)
        new_token_ref['id'] = token_id
        self.token_api.create_token(context=context, token_id=token_id,
                                    data=new_token_ref)
        logging.debug('TOKEN_REF %s', new_token_ref)
        return {'access': {'token': new_token_ref}}
Example #14
0
    def authenticate(self, context, auth=None):
        """Authenticate credentials and return a token.

        Accept auth as a dict that looks like::

            {
                "auth":{
                    "passwordCredentials":{
                        "username":"******",
                        "password":"******"
                    },
                    "tenantName":"customer-x"
                }
            }

        In this case, tenant is optional, if not provided the token will be
        considered "unscoped" and can later be used to get a scoped token.

        Alternatively, this call accepts auth with only a token and tenant
        that will return a token that is scoped to that tenant.
        """

        token_id = uuid.uuid4().hex
        if 'passwordCredentials' in auth:
            username = auth['passwordCredentials'].get('username', '')
            password = auth['passwordCredentials'].get('password', '')
            tenant_name = auth.get('tenantName', None)

            user_id = auth['passwordCredentials'].get('userId', None)
            if username:
                user_ref = self.identity_api.get_user_by_name(
                        context=context, user_name=username)
                if user_ref:
                    user_id = user_ref['id']

            # more compat
            tenant_id = auth.get('tenantId', None)
            if tenant_name:
                tenant_ref = self.identity_api.get_tenant_by_name(
                        context=context, tenant_name=tenant_name)
                if tenant_ref:
                    tenant_id = tenant_ref['id']

            try:
                auth_info = self.identity_api.authenticate(context=context,
                                                           user_id=user_id,
                                                           password=password,
                                                           tenant_id=tenant_id)
                (user_ref, tenant_ref, metadata_ref) = auth_info

                # If the user is disabled don't allow them to authenticate
                if not user_ref.get('enabled', True):
                    LOG.warning('User %s is disabled' % user_id)
                    raise exception.Unauthorized()
            except AssertionError as e:
                raise exception.Unauthorized(e.message)

            token_ref = self.token_api.create_token(
                    context, token_id, dict(id=token_id,
                                            user=user_ref,
                                            tenant=tenant_ref,
                                            metadata=metadata_ref))
            if tenant_ref:
                catalog_ref = self.catalog_api.get_catalog(
                        context=context,
                        user_id=user_ref['id'],
                        tenant_id=tenant_ref['id'],
                        metadata=metadata_ref)
            else:
                catalog_ref = {}

        elif 'token' in auth:
            token = auth['token'].get('id', None)

            tenant_name = auth.get('tenantName')

            # more compat
            if tenant_name:
                tenant_ref = self.identity_api.get_tenant_by_name(
                        context=context, tenant_name=tenant_name)
                tenant_id = tenant_ref['id']
            else:
                tenant_id = auth.get('tenantId', None)

            try:
                old_token_ref = self.token_api.get_token(context=context,
                                                         token_id=token)
            except exception.NotFound:
                raise exception.Unauthorized()

            user_ref = old_token_ref['user']

            # If the user is disabled don't allow them to authenticate
            current_user_ref = self.identity_api.get_user(
                                                    context=context,
                                                    user_id=user_ref['id'])
            if not current_user_ref.get('enabled', True):
                LOG.warning('User %s is disabled' % user_ref['id'])
                raise exception.Unauthorized()

            tenants = self.identity_api.get_tenants_for_user(context,
                                                             user_ref['id'])
            if tenant_id:
                assert tenant_id in tenants

            tenant_ref = self.identity_api.get_tenant(context=context,
                                                      tenant_id=tenant_id)
            if tenant_ref:
                metadata_ref = self.identity_api.get_metadata(
                        context=context,
                        user_id=user_ref['id'],
                        tenant_id=tenant_ref['id'])
                catalog_ref = self.catalog_api.get_catalog(
                        context=context,
                        user_id=user_ref['id'],
                        tenant_id=tenant_ref['id'],
                        metadata=metadata_ref)
            else:
                metadata_ref = {}
                catalog_ref = {}

            token_ref = self.token_api.create_token(
                    context, token_id, dict(id=token_id,
                                            user=user_ref,
                                            tenant=tenant_ref,
                                            metadata=metadata_ref))

        # TODO(termie): optimize this call at some point and put it into the
        #               the return for metadata
        # fill out the roles in the metadata
        roles_ref = []
        for role_id in metadata_ref.get('roles', []):
            roles_ref.append(self.identity_api.get_role(context, role_id))
        logging.debug('TOKEN_REF %s', token_ref)
        return self._format_authenticate(token_ref, roles_ref, catalog_ref)
Example #15
0
    def authenticate(self, context, auth=None):
        """Authenticate credentials and return a token.

        Accept auth as a dict that looks like::

            {
                "auth":{
                    "passwordCredentials":{
                        "username":"******",
                        "password":"******"
                    },
                    "tenantName":"customer-x"
                }
            }

        In this case, tenant is optional, if not provided the token will be
        considered "unscoped" and can later be used to get a scoped token.

        Alternatively, this call accepts auth with only a token and tenant
        that will return a token that is scoped to that tenant.
        """

        token_id = uuid.uuid4().hex
        if 'passwordCredentials' in auth:
            username = auth['passwordCredentials'].get('username', '')
            if len(username) > CONF.max_param_size:
                raise exception.ValidationSizeError(attribute='username',
                                                    size=CONF.max_param_size)
            password = auth['passwordCredentials'].get('password', '')
            max_pw_size = utils.MAX_PASSWORD_LENGTH
            if len(password) > max_pw_size:
                raise exception.ValidationSizeError(attribute='password',
                                                    size=max_pw_size)
            tenant_name = auth.get('tenantName', None)
            if tenant_name and len(tenant_name) > CONF.max_param_size:
                raise exception.ValidationSizeError(attribute='tenantName',
                                                    size=CONF.max_param_size)
            user_id = auth['passwordCredentials'].get('userId', None)
            if user_id and len(user_id) > CONF.max_param_size:
                raise exception.ValidationSizeError(attribute='userId',
                                                    size=CONF.max_param_size)
            if username:
                user_ref = self.identity_api.get_user_by_name(
                    context=context, user_name=username)
                if user_ref:
                    user_id = user_ref['id']

            # more compat
            tenant_id = auth.get('tenantId', None)
            if tenant_id and len(tenant_id) > CONF.max_param_size:
                raise exception.ValidationSizeError(attribute='tenantId',
                                                    size=CONF.max_param_size)
            if tenant_name:
                tenant_ref = self.identity_api.get_tenant_by_name(
                    context=context, tenant_name=tenant_name)
                if tenant_ref:
                    tenant_id = tenant_ref['id']

            try:
                auth_info = self.identity_api.authenticate(context=context,
                                                           user_id=user_id,
                                                           password=password,
                                                           tenant_id=tenant_id)
                (user_ref, tenant_ref, metadata_ref) = auth_info

                # If the user is disabled don't allow them to authenticate
                if not user_ref.get('enabled', True):
                    LOG.warning('User %s is disabled' % user_id)
                    raise exception.Unauthorized()

                # If the tenant is disabled don't allow them to authenticate
                if tenant_ref and not tenant_ref.get('enabled', True):
                    LOG.warning('Tenant %s is disabled' % tenant_id)
                    raise exception.Unauthorized()
            except AssertionError as e:
                raise exception.Unauthorized(e.message)

            token_ref = self.token_api.create_token(
                context, token_id,
                dict(id=token_id,
                     user=user_ref,
                     tenant=tenant_ref,
                     metadata=metadata_ref))
            if tenant_ref:
                catalog_ref = self.catalog_api.get_catalog(
                    context=context,
                    user_id=user_ref['id'],
                    tenant_id=tenant_ref['id'],
                    metadata=metadata_ref)
            else:
                catalog_ref = {}

        elif 'token' in auth:
            token = auth['token'].get('id', None)
            if len(token) > CONF.max_param_size:
                raise exception.ValidationSizeError(attribute='token',
                                                    size=CONF.max_param_size)
            tenant_name = auth.get('tenantName')
            if tenant_name and len(tenant_name) > CONF.max_param_size:
                raise exception.ValidationSizeError(attribute='tenantName',
                                                    size=CONF.max_param_size)
            # more compat
            if tenant_name:
                tenant_ref = self.identity_api.get_tenant_by_name(
                    context=context, tenant_name=tenant_name)
                tenant_id = tenant_ref['id']
            else:
                tenant_id = auth.get('tenantId', None)

            try:
                old_token_ref = self.token_api.get_token(context=context,
                                                         token_id=token)
            except exception.NotFound:
                raise exception.Unauthorized()

            user_ref = old_token_ref['user']

            # If the user is disabled don't allow them to authenticate
            current_user_ref = self.identity_api.get_user(
                context=context, user_id=user_ref['id'])
            if not current_user_ref.get('enabled', True):
                LOG.warning('User %s is disabled' % user_ref['id'])
                raise exception.Unauthorized()

            tenants = self.identity_api.get_tenants_for_user(
                context, user_ref['id'])
            if tenant_id:
                assert tenant_id in tenants

            tenant_ref = self.identity_api.get_tenant(context=context,
                                                      tenant_id=tenant_id)

            # If the tenant is disabled don't allow them to authenticate
            if tenant_ref and not tenant_ref.get('enabled', True):
                LOG.warning('Tenant %s is disabled' % tenant_id)
                raise exception.Unauthorized()

            if tenant_ref:
                metadata_ref = self.identity_api.get_metadata(
                    context=context,
                    user_id=user_ref['id'],
                    tenant_id=tenant_ref['id'])
                catalog_ref = self.catalog_api.get_catalog(
                    context=context,
                    user_id=user_ref['id'],
                    tenant_id=tenant_ref['id'],
                    metadata=metadata_ref)
            else:
                metadata_ref = {}
                catalog_ref = {}

            token_ref = self.token_api.create_token(
                context, token_id,
                dict(id=token_id,
                     user=user_ref,
                     tenant=tenant_ref,
                     metadata=metadata_ref,
                     expires=old_token_ref['expires']))

        # TODO(termie): optimize this call at some point and put it into the
        #               the return for metadata
        # fill out the roles in the metadata
        roles_ref = []
        for role_id in metadata_ref.get('roles', []):
            roles_ref.append(self.identity_api.get_role(context, role_id))
        logging.debug('TOKEN_REF %s', token_ref)
        return self._format_authenticate(token_ref, roles_ref, catalog_ref)
Example #16
0
    def authenticate(self, context, auth=None):
        """Authenticate credentials and return a token.

        Accept auth as a dict that looks like::

            {
                "auth":{
                    "passwordCredentials":{
                        "username":"******",
                        "password":"******"
                    },
                    "tenantName":"customer-x"
                }
            }

        In this case, tenant is optional, if not provided the token will be
        considered "unscoped" and can later be used to get a scoped token.

        Alternatively, this call accepts auth with only a token and tenant
        that will return a token that is scoped to that tenant.
        """

        token_id = uuid.uuid4().hex
        if 'passwordCredentials' in auth:
            username = auth['passwordCredentials'].get('username', '')
            password = auth['passwordCredentials'].get('password', '')
            tenant_name = auth.get('tenantName', None)

            if username:
                user_ref = self.identity_api.get_user_by_name(
                    context=context, user_name=username)
                user_id = user_ref['id']
            else:
                user_id = auth['passwordCredentials'].get('userId', None)

            # more compat
            if tenant_name:
                tenant_ref = self.identity_api.get_tenant_by_name(
                    context=context, tenant_name=tenant_name)
                tenant_id = tenant_ref['id']
            else:
                tenant_id = auth.get('tenantId', None)

            try:
                (user_ref, tenant_ref, metadata_ref) = \
                        self.identity_api.authenticate(context=context,
                                                       user_id=user_id,
                                                       password=password,
                                                       tenant_id=tenant_id)

                # If the user is disabled don't allow them to authenticate
                if not user_ref.get('enabled', True):
                    raise webob.exc.HTTPForbidden('User has been disabled')
            except AssertionError as e:
                raise webob.exc.HTTPForbidden(e.message)

            token_ref = self.token_api.create_token(
                context, token_id,
                dict(expires='',
                     id=token_id,
                     user=user_ref,
                     tenant=tenant_ref,
                     metadata=metadata_ref))
            if tenant_ref:
                catalog_ref = self.catalog_api.get_catalog(
                    context=context,
                    user_id=user_ref['id'],
                    tenant_id=tenant_ref['id'],
                    metadata=metadata_ref)
            else:
                catalog_ref = {}

        elif 'token' in auth:
            token = auth['token'].get('id', None)

            tenant_name = auth.get('tenantName')

            # more compat
            if tenant_name:
                tenant_ref = self.identity_api.get_tenant_by_name(
                    context=context, tenant_name=tenant_name)
                tenant_id = tenant_ref['id']
            else:
                tenant_id = auth.get('tenantId', None)

            old_token_ref = self.token_api.get_token(context=context,
                                                     token_id=token)
            user_ref = old_token_ref['user']

            tenants = self.identity_api.get_tenants_for_user(
                context, user_ref['id'])
            if tenant_id:
                assert tenant_id in tenants

            tenant_ref = self.identity_api.get_tenant(context=context,
                                                      tenant_id=tenant_id)
            if tenant_ref:
                metadata_ref = self.identity_api.get_metadata(
                    context=context,
                    user_id=user_ref['id'],
                    tenant_id=tenant_ref['id'])
                catalog_ref = self.catalog_api.get_catalog(
                    context=context,
                    user_id=user_ref['id'],
                    tenant_id=tenant_ref['id'],
                    metadata=metadata_ref)
            else:
                metadata_ref = {}
                catalog_ref = {}

            token_ref = self.token_api.create_token(
                context, token_id,
                dict(expires='',
                     id=token_id,
                     user=user_ref,
                     tenant=tenant_ref,
                     metadata=metadata_ref))

        # TODO(termie): optimize this call at some point and put it into the
        #               the return for metadata
        # fill out the roles in the metadata
        roles_ref = []
        for role_id in metadata_ref.get('roles', []):
            roles_ref.append(self.identity_api.get_role(context, role_id))
        logging.debug('TOKEN_REF %s', token_ref)
        return self._format_authenticate(token_ref, roles_ref, catalog_ref)