Exemple #1
0
def download_clouds_yaml_file(request):
    template = getattr(settings, 'OPENSTACK_CLOUDS_YAML_CUSTOM_TEMPLATE',
                       'project/api_access/clouds.yaml.template')

    context = _get_openrc_credentials(request)
    context['cloud_name'] = getattr(
        settings, "OPENSTACK_CLOUDS_YAML_NAME", 'openstack')
    context['profile'] = getattr(
        settings, "OPENSTACK_CLOUDS_YAML_PROFILE", None)
    context['regions'] = [
        region_tuple[1] for region_tuple in getattr(
            settings, "AVAILABLE_REGIONS", [])
    ]

    if utils.get_keystone_version() >= 3:
        # make v3 specific changes
        context['user_domain_name'] = request.user.user_domain_name
        # sanity fix for removing v2.0 from the url if present
        context['auth_url'], _ = utils.fix_auth_url_version_prefix(
            context['auth_url'])
        context['os_identity_api_version'] = 3
        context['os_auth_version'] = 3

    return _download_rc_file_for_template(request, context, template,
                                          'clouds.yaml')
Exemple #2
0
    def get_plugin(self,
                   service_provider=None,
                   auth_url=None,
                   plugins=[],
                   **kwargs):
        """Authenticate using keystone to keystone federation.

        This plugin uses other v3 plugins to authenticate a user to a
        identity provider in order to authenticate the user to a service
        provider

        :param service_provider: service provider ID
        :param auth_url: Keystone auth url
        :param plugins: list of openstack_auth plugins to check
        :returns Keystone2Keystone keystone auth plugin
        """

        # service_provider being None prevents infinite recursion
        if utils.get_keystone_version() < 3 or not service_provider:
            return None

        keystone_idp_id = getattr(settings, 'KEYSTONE_PROVIDER_IDP_ID',
                                  'localkeystone')
        if service_provider == keystone_idp_id:
            return None

        for plugin in plugins:
            unscoped_idp_auth = plugin.get_plugin(plugins=plugins,
                                                  auth_url=auth_url,
                                                  **kwargs)
            if unscoped_idp_auth:
                break
        else:
            LOG.debug('Could not find base authentication backend for '
                      'K2K plugin with the provided credentials.')
            return None

        idp_exception = None
        scoped_idp_auth = None
        unscoped_auth_ref = base.BasePlugin.get_access_info(
            self, unscoped_idp_auth)
        try:
            scoped_idp_auth, __ = self.get_project_scoped_auth(
                unscoped_idp_auth, unscoped_auth_ref)
        except exceptions.KeystoneAuthException as idp_excp:
            idp_exception = idp_excp

        if not scoped_idp_auth or idp_exception:
            msg = 'Identity provider authentication Failed.'
            raise exceptions.KeystoneAuthException(msg)

        session = utils.get_session()

        if scoped_idp_auth.get_sp_auth_url(session, service_provider) is None:
            msg = _('Could not find service provider ID on Keystone.')
            raise exceptions.KeystoneAuthException(msg)

        unscoped_auth = v3_auth.Keystone2Keystone(
            base_plugin=scoped_idp_auth, service_provider=service_provider)
        return unscoped_auth
Exemple #3
0
def download_clouds_yaml_file(request):
    template = getattr(settings, 'OPENSTACK_CLOUDS_YAML_CUSTOM_TEMPLATE',
                       'project/api_access/clouds.yaml.template')

    context = _get_openrc_credentials(request)
    context['cloud_name'] = getattr(settings, "OPENSTACK_CLOUDS_YAML_NAME",
                                    'openstack')
    context['profile'] = getattr(settings, "OPENSTACK_CLOUDS_YAML_PROFILE",
                                 None)
    context['regions'] = [
        region_tuple[1]
        for region_tuple in getattr(settings, "AVAILABLE_REGIONS", [])
    ]

    if utils.get_keystone_version() >= 3:
        # make v3 specific changes
        context['user_domain_name'] = request.user.user_domain_name
        # sanity fix for removing v2.0 from the url if present
        context['auth_url'], _ = utils.fix_auth_url_version_prefix(
            context['auth_url'])
        context['os_identity_api_version'] = 3
        context['os_auth_version'] = 3

    return _download_rc_file_for_template(request, context, template,
                                          'clouds.yaml')
Exemple #4
0
    def get_plugin(self, service_provider=None, auth_url=None, plugins=None,
                   **kwargs):
        """Authenticate using keystone to keystone federation.

        This plugin uses other v3 plugins to authenticate a user to a
        identity provider in order to authenticate the user to a service
        provider

        :param service_provider: service provider ID
        :param auth_url: Keystone auth url
        :param plugins: list of openstack_auth plugins to check
        :returns Keystone2Keystone keystone auth plugin
        """

        # Avoid mutable default arg for plugins
        plugins = plugins or []

        # service_provider being None prevents infinite recursion
        if utils.get_keystone_version() < 3 or not service_provider:
            return None

        keystone_idp_id = getattr(settings, 'KEYSTONE_PROVIDER_IDP_ID',
                                  'localkeystone')
        if service_provider == keystone_idp_id:
            return None

        for plugin in plugins:
            unscoped_idp_auth = plugin.get_plugin(plugins=plugins,
                                                  auth_url=auth_url, **kwargs)
            if unscoped_idp_auth:
                break
        else:
            LOG.debug('Could not find base authentication backend for '
                      'K2K plugin with the provided credentials.')
            return None

        idp_exception = None
        scoped_idp_auth = None
        unscoped_auth_ref = base.BasePlugin.get_access_info(
            self, unscoped_idp_auth)
        try:
            scoped_idp_auth, __ = self.get_project_scoped_auth(
                unscoped_idp_auth, unscoped_auth_ref)
        except exceptions.KeystoneAuthException as idp_excp:
            idp_exception = idp_excp

        if not scoped_idp_auth or idp_exception:
            msg = 'Identity provider authentication Failed.'
            raise exceptions.KeystoneAuthException(msg)

        session = utils.get_session()

        if scoped_idp_auth.get_sp_auth_url(session, service_provider) is None:
            msg = _('Could not find service provider ID on Keystone.')
            raise exceptions.KeystoneAuthException(msg)

        unscoped_auth = v3_auth.Keystone2Keystone(
            base_plugin=scoped_idp_auth,
            service_provider=service_provider)
        return unscoped_auth
    def get_domain_scoped_auth(self,
                               unscoped_auth,
                               unscoped_auth_ref,
                               domain_name=None):
        """Get the domain scoped keystone auth and access info

        This function returns a domain scoped keystone token plugin
        and AccessInfo object.

        :param unscoped_auth: keystone auth plugin
        :param unscoped_auth_ref: keystoneclient.access.AccessInfo` or None.
        :param domain_name: domain that we should try to scope to
        :return: keystone token auth plugin, AccessInfo object
        """
        session = utils.get_session()
        auth_url = unscoped_auth.auth_url

        if utils.get_keystone_version() < 3:
            return None, None
        if domain_name:
            domains = [domain_name]
        else:
            domains = self.list_domains(session, unscoped_auth,
                                        unscoped_auth_ref)
            domains = [domain.name for domain in domains if domain.enabled]

        # domain support can require domain scoped tokens to perform
        # identity operations depending on the policy files being used
        # for keystone.
        domain_auth = None
        domain_auth_ref = None
        for domain_name in domains:
            token = unscoped_auth_ref.auth_token
            domain_auth = utils.get_token_auth_plugin(auth_url,
                                                      token,
                                                      domain_name=domain_name)
            try:
                domain_auth_ref = domain_auth.get_access(session)
            except (keystone_exceptions.ClientException,
                    keystone_exceptions.AuthorizationFailure):
                LOG.info(
                    'Attempted scope to domain %s failed, will attempt '
                    'to scope to another domain.', domain_name)
                pass
            else:
                if len(domains) > 1:
                    LOG.info(
                        "More than one valid domain found for user %s,"
                        " scoping to %s",
                        (unscoped_auth_ref.user_id, domain_name))
                break
        return domain_auth, domain_auth_ref
Exemple #6
0
    def get_domain_scoped_auth(self, unscoped_auth, unscoped_auth_ref,
                               domain_name=None):
        """Get the domain scoped keystone auth and access info

        This function returns a domain scoped keystone token plugin
        and AccessInfo object.

        :param unscoped_auth: keystone auth plugin
        :param unscoped_auth_ref: keystoneclient.access.AccessInfo` or None.
        :param domain_name: domain that we should try to scope to
        :return: keystone token auth plugin, AccessInfo object
        """
        session = utils.get_session()
        auth_url = unscoped_auth.auth_url

        if utils.get_keystone_version() < 3:
            return None, None
        if domain_name:
            domains = [domain_name]
        else:
            domains = self.list_domains(session,
                                        unscoped_auth,
                                        unscoped_auth_ref)
            domains = [domain.name for domain in domains if domain.enabled]

        # domain support can require domain scoped tokens to perform
        # identity operations depending on the policy files being used
        # for keystone.
        domain_auth = None
        domain_auth_ref = None
        for domain_name in domains:
            token = unscoped_auth_ref.auth_token
            domain_auth = utils.get_token_auth_plugin(
                auth_url,
                token,
                domain_name=domain_name)
            try:
                domain_auth_ref = domain_auth.get_access(session)
            except (keystone_exceptions.ClientException,
                    keystone_exceptions.AuthorizationFailure):
                LOG.info('Attempted scope to domain %s failed, will attempt '
                         'to scope to another domain.', domain_name)
                pass
            else:
                if len(domains) > 1:
                    LOG.info("More than one valid domain found for user %s,"
                             " scoping to %s",
                             (unscoped_auth_ref.user_id, domain_name))
                break
        return domain_auth, domain_auth_ref
Exemple #7
0
    def get_plugin(self, auth_url=None, token=None, project_id=None, **kwargs):
        if not all((auth_url, token)):
            return None

        if utils.get_keystone_version() >= 3:
            return v3_auth.Token(auth_url=auth_url,
                                 token=token,
                                 project_id=project_id,
                                 reauthenticate=False)

        else:
            return v2_auth.Token(auth_url=auth_url,
                                 token=token,
                                 tenant_id=project_id,
                                 reauthenticate=False)
def switch(request, tenant_id, redirect_field_name=auth.REDIRECT_FIELD_NAME):
    """Switches an authenticated user from one project to another."""
    LOG.debug('Switching to tenant %s for user "%s".' %
              (tenant_id, request.user.username))
    insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
    ca_cert = getattr(settings, "OPENSTACK_SSL_CACERT", None)
    endpoint = request.user.endpoint
    try:
        if utils.get_keystone_version() >= 3:
            if not utils.has_in_url_path(endpoint, '/v3'):
                endpoint = utils.url_path_replace(endpoint, '/v2.0', '/v3', 1)
        client = utils.get_keystone_client().Client(
            tenant_id=tenant_id,
            token=request.user.token.id,
            auth_url=endpoint,
            insecure=insecure,
            cacert=ca_cert,
            debug=settings.DEBUG)
        auth_ref = client.auth_ref
        msg = 'Project switch successful for user "%(username)s".' % \
            {'username': request.user.username}
        LOG.info(msg)
    except keystone_exceptions.ClientException:
        msg = 'Project switch failed for user "%(username)s".' % \
            {'username': request.user.username}
        LOG.warning(msg)
        auth_ref = None
        LOG.exception('An error occurred while switching sessions.')

    # Ensure the user-originating redirection url is safe.
    # Taken from django.contrib.auth.views.login()
    redirect_to = request.REQUEST.get(redirect_field_name, '')
    if not is_safe_url(url=redirect_to, host=request.get_host()):
        redirect_to = settings.LOGIN_REDIRECT_URL

    if auth_ref:
        old_endpoint = request.session.get('region_endpoint')
        old_token = request.session.get('token')
        if old_token and old_endpoint and old_token.id != auth_ref.auth_token:
            delete_token(endpoint=old_endpoint, token_id=old_token.id)
        user = auth_user.create_user_from_token(request,
                                                auth_user.Token(auth_ref),
                                                endpoint)
        auth_user.set_session_from_user(request, user)
    response = shortcuts.redirect(redirect_to)
    utils.set_response_cookie(response, 'recent_project',
                              request.user.project_id)
    return response
    def get_plugin(self, auth_url=None, token=None, project_id=None,
                   **kwargs):
        if not all((auth_url, token)):
            return None

        if utils.get_keystone_version() >= 3:
            return v3_auth.Token(auth_url=auth_url,
                                 token=token,
                                 project_id=project_id,
                                 reauthenticate=False)

        else:
            return v2_auth.Token(auth_url=auth_url,
                                 token=token,
                                 tenant_id=project_id,
                                 reauthenticate=False)
def switch(request, tenant_id, redirect_field_name=auth.REDIRECT_FIELD_NAME):
    """Switches an authenticated user from one project to another."""
    LOG.debug('Switching to tenant %s for user "%s".'
              % (tenant_id, request.user.username))
    insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
    ca_cert = getattr(settings, "OPENSTACK_SSL_CACERT", None)
    endpoint = request.user.endpoint
    try:
        if utils.get_keystone_version() >= 3:
            if not utils.has_in_url_path(endpoint, '/v3'):
                endpoint = utils.url_path_replace(endpoint, '/v2.0', '/v3', 1)
        client = utils.get_keystone_client().Client(
            tenant_id=tenant_id,
            token=request.user.token.id,
            auth_url=endpoint,
            insecure=insecure,
            cacert=ca_cert,
            debug=settings.DEBUG)
        auth_ref = client.auth_ref
        msg = 'Project switch successful for user "%(username)s".' % \
            {'username': request.user.username}
        LOG.info(msg)
    except keystone_exceptions.ClientException:
        msg = 'Project switch failed for user "%(username)s".' % \
            {'username': request.user.username}
        LOG.warning(msg)
        auth_ref = None
        LOG.exception('An error occurred while switching sessions.')

    # Ensure the user-originating redirection url is safe.
    # Taken from django.contrib.auth.views.login()
    redirect_to = request.REQUEST.get(redirect_field_name, '')
    if not is_safe_url(url=redirect_to, host=request.get_host()):
        redirect_to = settings.LOGIN_REDIRECT_URL

    if auth_ref:
        old_endpoint = request.session.get('region_endpoint')
        old_token = request.session.get('token')
        if old_token and old_endpoint and old_token.id != auth_ref.auth_token:
            delete_token(endpoint=old_endpoint, token_id=old_token.id)
        user = auth_user.create_user_from_token(
            request, auth_user.Token(auth_ref), endpoint)
        auth_user.set_session_from_user(request, user)
    response = shortcuts.redirect(redirect_to)
    utils.set_response_cookie(response, 'recent_project',
                              request.user.project_id)
    return response
Exemple #11
0
def delete_token(endpoint, token_id):
    """Delete a token."""
    try:
        endpoint = utils.fix_auth_url_version(endpoint)

        session = utils.get_session()
        auth_plugin = token_endpoint.Token(endpoint=endpoint, token=token_id)
        client = utils.get_keystone_client().Client(session=session,
                                                    auth=auth_plugin)
        if utils.get_keystone_version() >= 3:
            client.tokens.revoke_token(token=token_id)
        else:
            client.tokens.delete(token=token_id)

        LOG.info('Deleted token %s' % token_id)
    except keystone_exceptions.ClientException:
        LOG.info('Could not delete token')
    def get_plugin(self, auth_url=None, username=None, password=None,
                   user_domain_name=None, **kwargs):
        if not all((auth_url, username, password)):
            return None

        LOG.debug('Attempting to authenticate for %s', username)

        if utils.get_keystone_version() >= 3:
            return v3_auth.Password(auth_url=auth_url,
                                    username=username,
                                    password=password,
                                    user_domain_name=user_domain_name)

        else:
            return v2_auth.Password(auth_url=auth_url,
                                    username=username,
                                    password=password)
Exemple #13
0
    def get_plugin(self, auth_url=None, username=None, password=None,
                   user_domain_name=None, **kwargs):
        if not all((auth_url, username, password)):
            return None

        LOG.debug('Attempting to authenticate for %s', username)

        if utils.get_keystone_version() >= 3:
            return v3_auth.Password(auth_url=auth_url,
                                    username=username,
                                    password=password,
                                    user_domain_name=user_domain_name,
                                    unscoped=True)

        else:
            return v2_auth.Password(auth_url=auth_url,
                                    username=username,
                                    password=password)
def delete_token(endpoint, token_id):
    """Delete a token."""
    try:
        endpoint = utils.fix_auth_url_version(endpoint)

        session = utils.get_session()
        auth_plugin = token_endpoint.Token(endpoint=endpoint,
                                           token=token_id)
        client = utils.get_keystone_client().Client(session=session,
                                                    auth=auth_plugin)
        if utils.get_keystone_version() >= 3:
            client.tokens.revoke_token(token=token_id)
        else:
            client.tokens.delete(token=token_id)

        LOG.info('Deleted token %s' % token_id)
    except keystone_exceptions.ClientException:
        LOG.info('Could not delete token')
Exemple #15
0
    def get_plugin(self, auth_url=None, username=None, password=None,
                   user_domain_name=None, totp=None, **kwargs):
        if not all((auth_url, username, password, totp)):
            return None

        LOG.debug('Attempting to authenticate for %s', username)

        if utils.get_keystone_version() >= 3:
            return v3_auth.Wmtotp(auth_url=auth_url,
                                  username=username,
                                  password=password,
                                  totp=totp,
                                  user_domain_name=user_domain_name,
                                  unscoped=True)

        else:
            msg = "Totp authentication requires the keystone v3 api."
            raise exceptions.KeystoneAuthException(msg)
Exemple #16
0
def delete_token(endpoint, token_id):
    """Delete a token."""

    insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
    ca_cert = getattr(settings, "OPENSTACK_SSL_CACERT", None)
    try:
        if utils.get_keystone_version() < 3:
            client = keystone_client_v2.Client(endpoint=endpoint,
                                               token=token_id,
                                               insecure=insecure,
                                               cacert=ca_cert,
                                               debug=settings.DEBUG)
            client.tokens.delete(token=token_id)
            LOG.info('Deleted token %s' % token_id)
        else:
            # FIXME: KS-client does not have delete token available
            # Need to add this later when it is exposed.
            pass
    except keystone_exceptions.ClientException:
        LOG.info('Could not delete token')
Exemple #17
0
    def __init__(self, auth_ref):
        # User-related attributes
        user = {}
        user['id'] = auth_ref.user_id
        user['name'] = auth_ref.username
        self.user = user
        self.user_domain_id = auth_ref.user_domain_id
        self.user_domain_name = auth_ref.user_domain_name

        # Token-related attributes
        self.id = auth_ref.auth_token
        if len(self.id) > 64:
            algorithm = getattr(settings, 'OPENSTACK_TOKEN_HASH_ALGORITHM',
                                'md5')
            hasher = hashlib.new(algorithm)
            hasher.update(self.id)
            self.id = hasher.hexdigest()
        self.expires = auth_ref.expires

        # Project-related attributes
        project = {}
        project['id'] = auth_ref.project_id
        project['name'] = auth_ref.project_name
        self.project = project
        self.tenant = self.project

        # Domain-related attributes
        domain = {}
        domain['id'] = auth_ref.domain_id
        domain['name'] = auth_ref.domain_name
        self.domain = domain

        if auth_ref.version == 'v2.0':
            self.roles = auth_ref['user'].get('roles', [])
        else:
            self.roles = auth_ref.get('roles', [])

        if utils.get_keystone_version() < 3:
            self.serviceCatalog = auth_ref.get('serviceCatalog', [])
        else:
            self.serviceCatalog = auth_ref.get('catalog', [])
Exemple #18
0
    def __init__(self, auth_ref):
        # User-related attributes
        user = {}
        user['id'] = auth_ref.user_id
        user['name'] = auth_ref.username
        self.user = user
        self.user_domain_id = auth_ref.user_domain_id
        self.user_domain_name = auth_ref.user_domain_name

        # Token-related attributes
        self.id = auth_ref.auth_token
        if len(self.id) > 64:
            algorithm = getattr(settings, 'OPENSTACK_TOKEN_HASH_ALGORITHM',
                                'md5')
            hasher = hashlib.new(algorithm)
            hasher.update(self.id)
            self.id = hasher.hexdigest()
        self.expires = auth_ref.expires

        # Project-related attributes
        project = {}
        project['id'] = auth_ref.project_id
        project['name'] = auth_ref.project_name
        self.project = project
        self.tenant = self.project

        # Domain-related attributes
        domain = {}
        domain['id'] = auth_ref.domain_id
        domain['name'] = auth_ref.domain_name
        self.domain = domain

        if auth_ref.version == 'v2.0':
            self.roles = auth_ref['user'].get('roles', [])
        else:
            self.roles = auth_ref.get('roles', [])

        if utils.get_keystone_version() < 3:
            self.serviceCatalog = auth_ref.get('serviceCatalog', [])
        else:
            self.serviceCatalog = auth_ref.get('catalog', [])
def delete_token(endpoint, token_id):
    """Delete a token."""

    insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
    ca_cert = getattr(settings, "OPENSTACK_SSL_CACERT", None)
    try:
        if utils.get_keystone_version() < 3:
            client = keystone_client_v2.Client(
                endpoint=endpoint,
                token=token_id,
                insecure=insecure,
                cacert=ca_cert,
                debug=settings.DEBUG
            )
            client.tokens.delete(token=token_id)
            LOG.info('Deleted token %s' % token_id)
        else:
            # FIXME: KS-client does not have delete token available
            # Need to add this later when it is exposed.
            pass
    except keystone_exceptions.ClientException:
        LOG.info('Could not delete token')
    def __init__(self, auth_ref):
        # User-related attributes
        user = {}
        user['id'] = auth_ref.user_id
        user['name'] = auth_ref.username
        self.user = user
        self.user_domain_id = auth_ref.user_domain_id

        # Token-related attributes
        self.id = auth_ref.auth_token
        if len(self.id) > 32:
            self.id = hashlib.md5(self.id).hexdigest()
        self.expires = auth_ref.expires

        # Project-related attributes
        project = {}
        project['id'] = auth_ref.project_id
        project['name'] = auth_ref.project_name
        self.project = project
        self.tenant = self.project

        # Domain-related attributes
        domain = {}
        domain['id'] = auth_ref.domain_id
        domain['name'] = auth_ref.domain_name
        self.domain = domain

        if auth_ref.version == 'v2.0':
            self.roles = auth_ref['user'].get('roles', [])
        else:
            self.roles = auth_ref.get('roles', [])

        if utils.get_keystone_version() < 3:
            self.serviceCatalog = auth_ref.get('serviceCatalog', [])
        else:
            self.serviceCatalog = auth_ref.get('catalog', [])
    def __init__(self, auth_ref):
        # User-related attributes
        user = {}
        user['id'] = auth_ref.user_id
        user['name'] = auth_ref.username
        self.user = user
        self.user_domain_id = auth_ref.user_domain_id

        # Token-related attributes
        self.id = auth_ref.auth_token
        if len(self.id) > 32:
            self.id = hashlib.md5(self.id).hexdigest()
        self.expires = auth_ref.expires

        # Project-related attributes
        project = {}
        project['id'] = auth_ref.project_id
        project['name'] = auth_ref.project_name
        self.project = project
        self.tenant = self.project

        # Domain-related attributes
        domain = {}
        domain['id'] = auth_ref.domain_id
        domain['name'] = auth_ref.domain_name
        self.domain = domain

        if auth_ref.version == 'v2.0':
            self.roles = auth_ref['user'].get('roles', [])
        else:
            self.roles = auth_ref.get('roles', [])

        if utils.get_keystone_version() < 3:
            self.serviceCatalog = auth_ref.get('serviceCatalog', [])
        else:
            self.serviceCatalog = auth_ref.get('catalog', [])
    def authenticate(self, request=None, username=None, password=None,
                     user_domain_name=None, auth_url=None, tenantName=None):
        """Authenticates a user via the Keystone Identity API."""
        LOG.debug('Beginning user authentication for user "%s".' % username)

        insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
        ca_cert = getattr(settings, "OPENSTACK_SSL_CACERT", None)
        endpoint_type = getattr(
            settings, 'OPENSTACK_ENDPOINT_TYPE', 'publicURL')

        if utils.get_keystone_version() >= 3:
            if utils.has_in_url_path(auth_url, "/v2.0"):
                LOG.warning("The settings.py file points to a v2.0 keystone "
                            "endpoint, but v3 is specified as the API version "
                            "to use. Using v3 endpoint for authentication.")
                auth_url = utils.url_path_replace(auth_url, "/v2.0", "/v3", 1)

        keystone_client = utils.get_keystone_client()
        try:
            client = keystone_client.Client(
                user_domain_name=user_domain_name,
                username=username,
                password=password,
                auth_url=auth_url,
                insecure=insecure,
                cacert=ca_cert,
                debug=settings.DEBUG)

            unscoped_auth_ref = client.auth_ref
            unscoped_token = auth_user.Token(auth_ref=unscoped_auth_ref)
        except (keystone_exceptions.Unauthorized,
                keystone_exceptions.Forbidden,
                keystone_exceptions.NotFound) as exc:
            msg = _('Invalid user name or password.')
            
            LOG.debug(str(exc))
            raise exceptions.KeystoneAuthException(msg)
        except (keystone_exceptions.ClientException,
                keystone_exceptions.AuthorizationFailure) as exc:
            msg = _("An error occurred authenticating. "
                    "Please try again later.")
            LOG.debug(str(exc))
            raise exceptions.KeystoneAuthException(msg)

        self.check_auth_expiry(unscoped_auth_ref)

        if unscoped_auth_ref.project_scoped:
            auth_ref = unscoped_auth_ref
        else:
            try:
                if utils.get_keystone_version() < 3:
                    projects = client.tenants.list()
                else:
                    client.management_url = auth_url
                    projects = client.projects.list(
                        user=unscoped_auth_ref.user_id)                
            except (keystone_exceptions.ClientException,
                    keystone_exceptions.AuthorizationFailure) as exc:
                msg = _('Unable to retrieve authorized projects.')
                raise exceptions.KeystoneAuthException(msg)

            if not projects:
                msg = _('You are not authorized for any projects.')
                raise exceptions.KeystoneAuthException(msg)

            
            projectFound = False
            while projects:
                project = projects.pop()
                if tenantName == project.name:
                    projectFound = True             
                    try:
                        client = keystone_client.Client(
                            tenant_id=project.id,
                            token=unscoped_auth_ref.auth_token,
                            auth_url=auth_url,
                            insecure=insecure,
                            cacert=ca_cert,
                            debug=settings.DEBUG)
                        auth_ref = client.auth_ref
                        break
                    except (keystone_exceptions.ClientException,
                            keystone_exceptions.AuthorizationFailure):
                        auth_ref = None
            
            if projectFound == False:
                msg = _("Invalid tenant.")
                raise exceptions.KeystoneAuthException(msg)            

            if auth_ref is None:
                msg = _("Unable to authenticate to any available projects.")
                raise exceptions.KeystoneAuthException(msg)
    
        self.check_auth_expiry(auth_ref)
        
        user = auth_user.create_user_from_token(
            request,
            auth_user.Token(auth_ref),
            client.service_catalog.url_for(endpoint_type=endpoint_type))        
        
        if request is not None:
            request.session['unscoped_token'] = unscoped_token.id
            request.user = user

            setattr(request, KEYSTONE_CLIENT_ATTR, client)

        LOG.debug('Authentication completed for user "%s".' % username)
        return user
    def authenticate(self, request=None, username=None, password=None,
                     user_domain_name=None, auth_url=None):
        """Authenticates a user via the Keystone Identity API."""
        LOG.debug('Beginning user authentication for user "%s".' % username)

        insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
        ca_cert = getattr(settings, "OPENSTACK_SSL_CACERT", None)
        endpoint_type = getattr(
            settings, 'OPENSTACK_ENDPOINT_TYPE', 'publicURL')
	
        # Take REMOTE_USER from session. If its not there then declinet user.
	remote_user = request.environ.get('REMOTE_USER')
        if remote_user:
           LOG.warning("\n\n::REMOTE User Found in System. Populating Default values::\n\n")
           username = request.environ.get('REMOTE_USER')
           password = request.environ.get('REMOTE_USER')	
	else:
           msg = _('Invalid user name or password.')
           LOG.debug(str(exc))
           raise exceptions.KeystoneAuthException(msg)

        if auth_url is None:
            auth_url = settings.OPENSTACK_KEYSTONE_URL

        # keystone client v3 does not support logging in on the v2 url any more
        if utils.get_keystone_version() >= 3:
            if utils.has_in_url_path(auth_url, "/v2.0"):
                LOG.warning("The settings.py file points to a v2.0 keystone "
                            "endpoint, but v3 is specified as the API version "
                            "to use. Using v3 endpoint for authentication.")
                auth_url = utils.url_path_replace(auth_url, "/v2.0", "/v3", 1)

        keystone_client = utils.get_keystone_client()
        try:
            client = keystone_client.Client(
                user_domain_name=user_domain_name,
                username=username,
                password=password,
                auth_url=auth_url,
                insecure=insecure,
                cacert=ca_cert,
                debug=settings.DEBUG)

            unscoped_auth_ref = client.auth_ref
            unscoped_token = auth_user.Token(auth_ref=unscoped_auth_ref)
        except (keystone_exceptions.Unauthorized,
                keystone_exceptions.Forbidden,
                keystone_exceptions.NotFound) as exc:
            msg = _('Invalid user name or password.')
            LOG.debug(str(exc))
            raise exceptions.KeystoneAuthException(msg)
        except (keystone_exceptions.ClientException,
                keystone_exceptions.AuthorizationFailure) as exc:
            msg = _("An error occurred authenticating. "
                    "Please try again later.")
            LOG.debug(str(exc))
            raise exceptions.KeystoneAuthException(msg)

        # Check expiry for our unscoped auth ref.
        self.check_auth_expiry(unscoped_auth_ref)

        # Check if token is automatically scoped to default_project
        # grab the project from this token, to use as a default
        # if no recent_project is found in the cookie
        token_proj_id = None
        if unscoped_auth_ref.project_scoped:
            token_proj_id = unscoped_auth_ref.get('project',
                                                  {}).get('id')

        # We list all the user's projects
        try:
            if utils.get_keystone_version() < 3:
                projects = client.tenants.list()
            else:
                client.management_url = auth_url
                projects = client.projects.list(
                    user=unscoped_auth_ref.user_id)
        except (keystone_exceptions.ClientException,
                keystone_exceptions.AuthorizationFailure) as exc:
            msg = _('Unable to retrieve authorized projects.')
            raise exceptions.KeystoneAuthException(msg)

        # Abort if there are no projects for this user
        if not projects:
            msg = _('You are not authorized for any projects.')
            raise exceptions.KeystoneAuthException(msg)

        # the recent project id a user might have set in a cookie
        recent_project = None
        if request:
            recent_project = request.COOKIES.get('recent_project',
                                                 token_proj_id)

        # if a most recent project was found, try using it first
        for pos, project in enumerate(projects):
            if project.id == recent_project:
                # move recent project to the beginning
                projects.pop(pos)
                projects.insert(0, project)
                break

        for project in projects:
            try:
                client = keystone_client.Client(
                    tenant_id=project.id,
                    token=unscoped_auth_ref.auth_token,
                    auth_url=auth_url,
                    insecure=insecure,
                    cacert=ca_cert,
                    debug=settings.DEBUG)
                auth_ref = client.auth_ref
                break
            except (keystone_exceptions.ClientException,
                    keystone_exceptions.AuthorizationFailure):
                auth_ref = None

        if auth_ref is None:
            msg = _("Unable to authenticate to any available projects.")
            raise exceptions.KeystoneAuthException(msg)

        # Check expiry for our new scoped token.
        self.check_auth_expiry(auth_ref)

        # If we made it here we succeeded. Create our User!
        user = auth_user.create_user_from_token(
            request,
            auth_user.Token(auth_ref),
            client.service_catalog.url_for(endpoint_type=endpoint_type))

        if request is not None:
            request.session['unscoped_token'] = unscoped_token.id
            request.user = user

            # Support client caching to save on auth calls.
            setattr(request, KEYSTONE_CLIENT_ATTR, client)

        LOG.debug('Authentication completed for user "%s".' % username)
        return user
Exemple #24
0
    def authenticate(self, auth_url=None, **kwargs):
        """Authenticates a user via the Keystone Identity API."""
        LOG.debug('Beginning user authentication')

        if not auth_url:
            auth_url = settings.OPENSTACK_KEYSTONE_URL

        auth_url, url_fixed = utils.fix_auth_url_version_prefix(auth_url)
        if url_fixed:
            LOG.warning("The OPENSTACK_KEYSTONE_URL setting points to a v2.0 "
                        "Keystone endpoint, but v3 is specified as the API "
                        "version to use by Horizon. Using v3 endpoint for "
                        "authentication.")

        for plugin in self.auth_plugins:
            unscoped_auth = plugin.get_plugin(auth_url=auth_url, **kwargs)

            if unscoped_auth:
                break
        else:
            msg = _('No authentication backend could be determined to '
                    'handle the provided credentials.')
            LOG.warning('No authentication backend could be determined to '
                        'handle the provided credentials. This is likely a '
                        'configuration error that should be addressed.')
            raise exceptions.KeystoneAuthException(msg)

        # the recent project id a user might have set in a cookie
        recent_project = None
        request = kwargs.get('request')
        if request:
            # Grab recent_project found in the cookie, try to scope
            # to the last project used.
            recent_project = request.COOKIES.get('recent_project')
        unscoped_auth_ref = plugin.get_access_info(unscoped_auth)

        # Check expiry for our unscoped auth ref.
        self.check_auth_expiry(unscoped_auth_ref)

        domain_name = kwargs.get('user_domain_name', None)
        domain_auth, domain_auth_ref = plugin.get_domain_scoped_auth(
            unscoped_auth, unscoped_auth_ref, domain_name)
        scoped_auth, scoped_auth_ref = plugin.get_project_scoped_auth(
            unscoped_auth, unscoped_auth_ref, recent_project=recent_project)

        # Abort if there are no projects for this user and a valid domain
        # token has not been obtained
        #
        # The valid use cases for a user login are:
        #    Keystone v2: user must have a role on a project and be able
        #                 to obtain a project scoped token
        #    Keystone v3: 1) user can obtain a domain scoped token (user
        #                    has a role on the domain they authenticated to),
        #                    only, no roles on a project
        #                 2) user can obtain a domain scoped token and has
        #                    a role on a project in the domain they
        #                    authenticated to (and can obtain a project scoped
        #                    token)
        #                 3) user cannot obtain a domain scoped token, but can
        #                    obtain a project scoped token
        if not scoped_auth_ref and domain_auth_ref:
            # if the user can't obtain a project scoped token, set the scoped
            # token to be the domain token, if valid
            scoped_auth = domain_auth
            scoped_auth_ref = domain_auth_ref
        elif not scoped_auth_ref and not domain_auth_ref:
            msg = _('You are not authorized for any projects.')
            if utils.get_keystone_version() >= 3:
                msg = _('You are not authorized for any projects or domains.')
            raise exceptions.KeystoneAuthException(msg)

        # Check expiry for our new scoped token.
        self.check_auth_expiry(scoped_auth_ref)

        # We want to try to use the same region we just logged into
        # which may or may not be the default depending upon the order
        # keystone uses
        region_name = None
        id_endpoints = scoped_auth_ref.service_catalog.\
            get_endpoints(service_type='identity')
        for id_endpoint in [cat for cat in id_endpoints['identity']]:
            if auth_url in id_endpoint.values():
                region_name = id_endpoint['region']
                break

        interface = getattr(settings, 'OPENSTACK_ENDPOINT_TYPE', 'public')

        endpoint, url_fixed = utils.fix_auth_url_version_prefix(
            scoped_auth_ref.service_catalog.url_for(service_type='identity',
                                                    interface=interface,
                                                    region_name=region_name))
        if url_fixed:
            LOG.warning("The Keystone URL in service catalog points to a v2.0 "
                        "Keystone endpoint, but v3 is specified as the API "
                        "version to use by Horizon. Using v3 endpoint for "
                        "authentication.")

        # If we made it here we succeeded. Create our User!
        unscoped_token = unscoped_auth_ref.auth_token

        user = auth_user.create_user_from_token(
            request,
            auth_user.Token(scoped_auth_ref, unscoped_token=unscoped_token),
            endpoint,
            services_region=region_name)

        if request is not None:
            # if no k2k providers exist then the function returns quickly
            utils.store_initial_k2k_session(auth_url, request, scoped_auth_ref,
                                            unscoped_auth_ref)
            request.session['unscoped_token'] = unscoped_token
            if domain_auth_ref:
                # check django session engine, if using cookies, this will not
                # work, as it will overflow the cookie so don't add domain
                # scoped token to the session and put error in the log
                if utils.using_cookie_backed_sessions():
                    LOG.error('Using signed cookies as SESSION_ENGINE with '
                              'OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT is '
                              'enabled. This disables the ability to '
                              'perform identity operations due to cookie size '
                              'constraints.')
                else:
                    request.session['domain_token'] = domain_auth_ref

            request.user = user
            timeout = getattr(settings, "SESSION_TIMEOUT", 3600)
            token_life = user.token.expires - datetime.datetime.now(pytz.utc)
            session_time = min(timeout, int(token_life.total_seconds()))
            request.session.set_expiry(session_time)

            keystone_client_class = utils.get_keystone_client().Client
            session = utils.get_session()
            scoped_client = keystone_client_class(session=session,
                                                  auth=scoped_auth)

            # Support client caching to save on auth calls.
            setattr(request, KEYSTONE_CLIENT_ATTR, scoped_client)

        LOG.debug('Authentication completed.')
        return user
Exemple #25
0
# add a couple utility methods to it.
class IdentityAPIVersionManager(base.APIVersionManager):
    def upgrade_v2_user(self, user):
        if getattr(user, "project_id", None) is None:
            user.project_id = getattr(user, "default_project_id", getattr(user, "tenantId", None))
        return user

    def get_project_manager(self, *args, **kwargs):
        if VERSIONS.active < 3:
            manager = keystoneclient(*args, **kwargs).tenants
        else:
            manager = keystoneclient(*args, **kwargs).projects
        return manager


VERSIONS = IdentityAPIVersionManager("identity", preferred_version=auth_utils.get_keystone_version())


# Import from oldest to newest so that "preferred" takes correct precedence.
try:
    from keystoneclient.v2_0 import client as keystone_client_v2

    VERSIONS.load_supported_version(2.0, {"client": keystone_client_v2})
except ImportError:
    pass

try:
    from keystoneclient.v3 import client as keystone_client_v3

    VERSIONS.load_supported_version(3, {"client": keystone_client_v3})
except ImportError:
    def authenticate(self, auth_url=None, **kwargs):
        """Authenticates a user via the Keystone Identity API."""
        LOG.debug('Beginning user authentication')

        if not auth_url:
            auth_url = settings.OPENSTACK_KEYSTONE_URL

        auth_url = utils.fix_auth_url_version(auth_url)

        for plugin in self.auth_plugins:
            unscoped_auth = plugin.get_plugin(auth_url=auth_url, **kwargs)

            if unscoped_auth:
                break
        else:
            msg = _('No authentication backend could be determined to '
                    'handle the provided credentials.')
            LOG.warning('No authentication backend could be determined to '
                        'handle the provided credentials. This is likely a '
                        'configuration error that should be addressed.')
            raise exceptions.KeystoneAuthException(msg)

        session = utils.get_session()
        keystone_client_class = utils.get_keystone_client().Client

        try:
            unscoped_auth_ref = unscoped_auth.get_access(session)
        except keystone_exceptions.ConnectFailure as exc:
            LOG.error(str(exc))
            msg = _('Unable to establish connection to keystone endpoint.')
            raise exceptions.KeystoneAuthException(msg)
        except (keystone_exceptions.Unauthorized,
                keystone_exceptions.Forbidden,
                keystone_exceptions.NotFound) as exc:
            LOG.debug(str(exc))
            raise exceptions.KeystoneAuthException(_('Invalid credentials.'))
        except (keystone_exceptions.ClientException,
                keystone_exceptions.AuthorizationFailure) as exc:
            msg = _("An error occurred authenticating. "
                    "Please try again later.")
            LOG.debug(str(exc))
            raise exceptions.KeystoneAuthException(msg)

        # Check expiry for our unscoped auth ref.
        self.check_auth_expiry(unscoped_auth_ref)

        # domain support can require domain scoped tokens to perform
        # identity operations depending on the policy files being used
        # for keystone.
        domain_auth = None
        domain_auth_ref = None
        if utils.get_keystone_version() >= 3 and 'user_domain_name' in kwargs:
            try:
                token = unscoped_auth_ref.auth_token
                domain_auth = utils.get_token_auth_plugin(
                    auth_url,
                    token,
                    domain_name=kwargs['user_domain_name'])
                domain_auth_ref = domain_auth.get_access(session)
            except Exception:
                LOG.debug('Error getting domain scoped token.', exc_info=True)

        projects = plugin.list_projects(session,
                                        unscoped_auth,
                                        unscoped_auth_ref)
        # Attempt to scope only to enabled projects
        projects = [project for project in projects if project.enabled]

        # Abort if there are no projects for this user and a valid domain
        # token has not been obtained
        #
        # The valid use cases for a user login are:
        #    Keystone v2: user must have a role on a project and be able
        #                 to obtain a project scoped token
        #    Keystone v3: 1) user can obtain a domain scoped token (user
        #                    has a role on the domain they authenticated to),
        #                    only, no roles on a project
        #                 2) user can obtain a domain scoped token and has
        #                    a role on a project in the domain they
        #                    authenticated to (and can obtain a project scoped
        #                    token)
        #                 3) user cannot obtain a domain scoped token, but can
        #                    obtain a project scoped token
        if not projects and not domain_auth_ref:
            msg = _('You are not authorized for any projects.')
            if utils.get_keystone_version() >= 3:
                msg = _('You are not authorized for any projects or domains.')
            raise exceptions.KeystoneAuthException(msg)

        # the recent project id a user might have set in a cookie
        recent_project = None
        request = kwargs.get('request')

        if request:
            # Grab recent_project found in the cookie, try to scope
            # to the last project used.
            recent_project = request.COOKIES.get('recent_project')

        # if a most recent project was found, try using it first
        if recent_project:
            for pos, project in enumerate(projects):
                if project.id == recent_project:
                    # move recent project to the beginning
                    projects.pop(pos)
                    projects.insert(0, project)
                    break

        for project in projects:
            token = unscoped_auth_ref.auth_token
            scoped_auth = utils.get_token_auth_plugin(auth_url,
                                                      token=token,
                                                      project_id=project.id)

            try:
                scoped_auth_ref = scoped_auth.get_access(session)
            except (keystone_exceptions.ClientException,
                    keystone_exceptions.AuthorizationFailure):
                pass
            else:
                break
        else:
            # if the user can't obtain a project scoped token, set the scoped
            # token to be the domain token, if valid
            if domain_auth_ref:
                scoped_auth = domain_auth
                scoped_auth_ref = domain_auth_ref
            else:
                # if no domain or project token for user, abort
                msg = _("Unable to authenticate to any available projects.")
                raise exceptions.KeystoneAuthException(msg)

        # Check expiry for our new scoped token.
        self.check_auth_expiry(scoped_auth_ref)

        # We want to try to use the same region we just logged into
        # which may or may not be the default depending upon the order
        # keystone uses
        region_name = None
        id_endpoints = scoped_auth_ref.service_catalog.\
            get_endpoints(service_type='identity')
        for id_endpoint in [cat for cat in id_endpoints['identity']]:
            if auth_url in id_endpoint.values():
                region_name = id_endpoint['region']
                break

        interface = getattr(settings, 'OPENSTACK_ENDPOINT_TYPE', 'public')

        endpoint = utils.fix_auth_url_version(
            scoped_auth_ref.service_catalog.url_for(
                service_type='identity',
                interface=interface,
                region_name=region_name))

        # If we made it here we succeeded. Create our User!
        unscoped_token = unscoped_auth_ref.auth_token

        user = auth_user.create_user_from_token(
            request,
            auth_user.Token(scoped_auth_ref, unscoped_token=unscoped_token),
            endpoint,
            services_region=region_name)

        if request is not None:
            request.session['unscoped_token'] = unscoped_token
            if domain_auth_ref:
                # check django session engine, if using cookies, this will not
                # work, as it will overflow the cookie so don't add domain
                # scoped token to the session and put error in the log
                if utils.using_cookie_backed_sessions():
                    LOG.error('Using signed cookies as SESSION_ENGINE with '
                              'OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT is '
                              'enabled. This disables the ability to '
                              'perform identity operations due to cookie size '
                              'constraints.')
                else:
                    request.session['domain_token'] = domain_auth_ref

            request.user = user
            timeout = getattr(settings, "SESSION_TIMEOUT", 3600)
            token_life = user.token.expires - datetime.datetime.now(pytz.utc)
            session_time = min(timeout, int(token_life.total_seconds()))
            request.session.set_expiry(session_time)

            scoped_client = keystone_client_class(session=session,
                                                  auth=scoped_auth)

            # Support client caching to save on auth calls.
            setattr(request, KEYSTONE_CLIENT_ATTR, scoped_client)

        LOG.debug('Authentication completed.')
        return user
Exemple #27
0
    def authenticate(self, **kwargs):

        auth_url = kwargs.get('auth_url', None)
        request = kwargs.get('request', None)
        username = kwargs.get('username', None)
        password = kwargs.get('password', None)
        user_domain_name = kwargs.get('user_domain_name', None)

        if password:
            parentObj = super(ExtKeystoneBackend, self)
            return parentObj.authenticate(**kwargs)

        LOG.debug('Authenticating user "%s".' % username)

        insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
        cacert = getattr(settings, 'OPENSTACK_SSL_CACERT', None)
        ep_type = getattr(settings, 'OPENSTACK_ENDPOINT_TYPE', 'publicURL')
        secret_key = getattr(settings, 'KEYSTONE_SECRET_KEY', None)

        fqun = json.dumps({'username': username, 'domain': user_domain_name})

        try:

            secret_token = create_cryptoken(secret_key, fqun)

            client = ExtClient(user_domain_name=user_domain_name,
                               username=username,
                               secret_token=secret_token,
                               auth_url=auth_url,
                               insecure=insecure,
                               cacert=cacert,
                               debug=settings.DEBUG)

            unscoped_auth_ref = client.auth_ref
            unscoped_token = Token(auth_ref=unscoped_auth_ref)

            # Force API V3
            if get_keystone_version() < 3:
                unscoped_token.serviceCatalog = unscoped_auth_ref.get(
                    'catalog', [])
                unscoped_token.roles = unscoped_auth_ref.get('roles', [])

        except ClientException as exc:
            LOG.debug(exc.message, exc_info=True)
            raise
        except Exception as exc:
            msg = _(
                "An error occurred authenticating. Please try again later.")
            LOG.debug(exc.message, exc_info=True)
            raise KeystoneAuthException(msg)

        self.check_auth_expiry(unscoped_auth_ref)

        if unscoped_auth_ref.project_scoped:
            auth_ref = unscoped_auth_ref
        else:
            # For now we list all the user's projects and iterate through.
            try:
                client.management_url = auth_url
                projects = client.projects.list(user=unscoped_auth_ref.user_id)
            except (ClientException, AuthorizationFailure) as exc:
                msg = _('Unable to retrieve authorized projects.')
                raise KeystoneAuthException(msg)

            # Abort if there are no projects for this user
            if not projects:
                msg = _('You are not authorized for any projects.')
                raise KeystoneAuthException(msg)

            while projects:
                project = projects.pop()
                try:
                    client = BaseClient(tenant_id=project.id,
                                        token=unscoped_auth_ref.auth_token,
                                        auth_url=auth_url,
                                        insecure=insecure,
                                        debug=settings.DEBUG)
                    auth_ref = client.auth_ref
                    break
                except (ClientException, AuthorizationFailure):
                    auth_ref = None

            if auth_ref is None:
                msg = _("Unable to authenticate to any available projects.")
                raise KeystoneAuthException(msg)

            # Check expiry for our new scoped token.
            self.check_auth_expiry(auth_ref)

        # If we made it here we succeeded. Create our User!

        # Force API V3
        project_token = Token(auth_ref)
        if get_keystone_version() < 3:
            project_token.serviceCatalog = auth_ref.get('catalog', [])
            project_token.roles = auth_ref.get('roles', [])

        user = create_user_from_token(
            request, project_token,
            client.service_catalog.url_for(endpoint_type=ep_type))

        if request is not None:
            request.session['unscoped_token'] = unscoped_token.id
            request.user = user

            # Support client caching to save on auth calls.
            setattr(request, base_backend.KEYSTONE_CLIENT_ATTR, client)

        LOG.debug('Authentication completed for user "%s".' % username)
        return user
Exemple #28
0
# add a couple utility methods to it.
class IdentityAPIVersionManager(base.APIVersionManager):
    def upgrade_v2_user(self, user):
        if getattr(user, "project_id", None) is None:
            user.project_id = getattr(user, "default_project_id", getattr(user, "tenantId", None))
        return user

    def get_project_manager(self, *args, **kwargs):
        if VERSIONS.active < 3:
            manager = keystoneclient(*args, **kwargs).tenants
        else:
            manager = keystoneclient(*args, **kwargs).projects
        return manager


VERSIONS = IdentityAPIVersionManager("identity", preferred_version=auth_utils.get_keystone_version())

# Import from oldest to newest so that "preferred" takes correct precedence.
try:
    from keystoneclient.v2_0 import client as keystone_client_v2
    VERSIONS.load_supported_version(2.0, {"client": keystone_client_v2})
except ImportError:
    pass

try:
    from keystoneclient.v3 import client as keystone_client_v3
    VERSIONS.load_supported_version(3, {"client": keystone_client_v3})
except ImportError:
    pass

Exemple #29
0
 def allowed(self, request, datum=None):
     return utils.get_keystone_version() >= 3
    def authenticate(self, request=None, username=None, password=None,
                     user_domain_name=None, auth_url=None):
        """Authenticates a user via the Keystone Identity API."""
        LOG.debug('Beginning user authentication for user "%s".' % username)

        insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
        ca_cert = getattr(settings, "OPENSTACK_SSL_CACERT", None)
        endpoint_type = getattr(
            settings, 'OPENSTACK_ENDPOINT_TYPE', 'publicURL')

        if auth_url is None:
            auth_url = settings.OPENSTACK_KEYSTONE_URL

        # keystone client v3 does not support logging in on the v2 url any more
        if utils.get_keystone_version() >= 3:
            if utils.has_in_url_path(auth_url, "/v2.0"):
                LOG.warning("The settings.py file points to a v2.0 keystone "
                            "endpoint, but v3 is specified as the API version "
                            "to use. Using v3 endpoint for authentication.")
                auth_url = utils.url_path_replace(auth_url, "/v2.0", "/v3", 1)

        keystone_client = utils.get_keystone_client()
        try:
            client = keystone_client.Client(
                user_domain_name=user_domain_name,
                username=username,
                password=password,
                auth_url=auth_url,
                insecure=insecure,
                cacert=ca_cert,
                debug=settings.DEBUG)

            unscoped_auth_ref = client.auth_ref
            unscoped_token = auth_user.Token(auth_ref=unscoped_auth_ref)
        except (keystone_exceptions.Unauthorized,
                keystone_exceptions.Forbidden,
                keystone_exceptions.NotFound) as exc:
            msg = _('Invalid user name or password.')
            LOG.debug(str(exc))
            raise exceptions.KeystoneAuthException(msg)
        except (keystone_exceptions.ClientException,
                keystone_exceptions.AuthorizationFailure) as exc:
            msg = _("An error occurred authenticating. "
                    "Please try again later.")
            LOG.debug(str(exc))
            raise exceptions.KeystoneAuthException(msg)

        # Check expiry for our unscoped auth ref.
        self.check_auth_expiry(unscoped_auth_ref)

        # Check if token is automatically scoped to default_project
        if unscoped_auth_ref.project_scoped:
            auth_ref = unscoped_auth_ref
        else:
            # For now we list all the user's projects and iterate through.
            try:
                if utils.get_keystone_version() < 3:
                    projects = client.tenants.list()
                else:
                    client.management_url = auth_url
                    projects = client.projects.list(
                        user=unscoped_auth_ref.user_id)
            except (keystone_exceptions.ClientException,
                    keystone_exceptions.AuthorizationFailure) as exc:
                msg = _('Unable to retrieve authorized projects.')
                raise exceptions.KeystoneAuthException(msg)

            # Abort if there are no projects for this user
            if not projects:
                msg = _('You are not authorized for any projects.')
                raise exceptions.KeystoneAuthException(msg)

            while projects:
                project = projects.pop()
                try:
                    client = keystone_client.Client(
                        tenant_id=project.id,
                        token=unscoped_auth_ref.auth_token,
                        auth_url=auth_url,
                        insecure=insecure,
                        cacert=ca_cert,
                        debug=settings.DEBUG)
                    auth_ref = client.auth_ref
                    break
                except (keystone_exceptions.ClientException,
                        keystone_exceptions.AuthorizationFailure):
                    auth_ref = None

            if auth_ref is None:
                msg = _("Unable to authenticate to any available projects.")
                raise exceptions.KeystoneAuthException(msg)

        # Check expiry for our new scoped token.
        self.check_auth_expiry(auth_ref)

        # If we made it here we succeeded. Create our User!
        user = auth_user.create_user_from_token(
            request,
            auth_user.Token(auth_ref),
            client.service_catalog.url_for(endpoint_type=endpoint_type))

        if request is not None:
            request.session['unscoped_token'] = unscoped_token.id
            request.user = user

            # Support client caching to save on auth calls.
            setattr(request, KEYSTONE_CLIENT_ATTR, client)

        LOG.debug('Authentication completed for user "%s".' % username)
        return user
    def authenticate(self, **kwargs):

        auth_url = kwargs.get("auth_url", None)
        request = kwargs.get("request", None)
        username = kwargs.get("username", None)
        password = kwargs.get("password", None)
        user_domain_name = kwargs.get("user_domain_name", None)

        if password:
            parentObj = super(ExtKeystoneBackend, self)
            return parentObj.authenticate(**kwargs)

        LOG.debug('Authenticating user "%s".' % username)

        insecure = getattr(settings, "OPENSTACK_SSL_NO_VERIFY", False)
        cacert = getattr(settings, "OPENSTACK_SSL_CACERT", None)
        ep_type = getattr(settings, "OPENSTACK_ENDPOINT_TYPE", "publicURL")
        secret_key = getattr(settings, "KEYSTONE_SECRET_KEY", None)

        fqun = json.dumps({"username": username, "domain": user_domain_name})

        try:

            secret_token = create_cryptoken(secret_key, fqun)

            client = ExtClient(
                user_domain_name=user_domain_name,
                username=username,
                secret_token=secret_token,
                auth_url=auth_url,
                insecure=insecure,
                cacert=cacert,
                debug=settings.DEBUG,
            )

            unscoped_auth_ref = client.auth_ref
            unscoped_token = Token(auth_ref=unscoped_auth_ref)

            # Force API V3
            if get_keystone_version() < 3:
                unscoped_token.serviceCatalog = unscoped_auth_ref.get("catalog", [])
                unscoped_token.roles = unscoped_auth_ref.get("roles", [])

        except ClientException as exc:
            LOG.debug(exc.message, exc_info=True)
            raise
        except Exception as exc:
            msg = _("An error occurred authenticating. Please try again later.")
            LOG.debug(exc.message, exc_info=True)
            raise KeystoneAuthException(msg)

        self.check_auth_expiry(unscoped_auth_ref)

        if unscoped_auth_ref.project_scoped:
            auth_ref = unscoped_auth_ref
        else:
            # For now we list all the user's projects and iterate through.
            try:
                client.management_url = auth_url
                projects = client.projects.list(user=unscoped_auth_ref.user_id)
            except (ClientException, AuthorizationFailure) as exc:
                msg = _("Unable to retrieve authorized projects.")
                raise KeystoneAuthException(msg)

            # Abort if there are no projects for this user
            if not projects:
                msg = _("You are not authorized for any projects.")
                raise KeystoneAuthException(msg)

            while projects:
                project = projects.pop()
                try:
                    client = BaseClient(
                        tenant_id=project.id,
                        token=unscoped_auth_ref.auth_token,
                        auth_url=auth_url,
                        insecure=insecure,
                        debug=settings.DEBUG,
                    )
                    auth_ref = client.auth_ref
                    break
                except (ClientException, AuthorizationFailure):
                    auth_ref = None

            if auth_ref is None:
                msg = _("Unable to authenticate to any available projects.")
                raise KeystoneAuthException(msg)

            # Check expiry for our new scoped token.
            self.check_auth_expiry(auth_ref)

        # If we made it here we succeeded. Create our User!

        # Force API V3
        project_token = Token(auth_ref)
        if get_keystone_version() < 3:
            project_token.serviceCatalog = auth_ref.get("catalog", [])
            project_token.roles = auth_ref.get("roles", [])

        user = create_user_from_token(request, project_token, client.service_catalog.url_for(endpoint_type=ep_type))

        if request is not None:
            request.session["unscoped_token"] = unscoped_token.id
            request.user = user

            # Support client caching to save on auth calls.
            setattr(request, base_backend.KEYSTONE_CLIENT_ATTR, client)

        LOG.debug('Authentication completed for user "%s".' % username)
        return user
    def authenticate(self,
                     request=None,
                     username=None,
                     password=None,
                     user_domain_name=None,
                     auth_url=None):
        """Authenticates a user via the Keystone Identity API."""
        LOG.debug('Beginning user authentication for user "%s".' % username)

        insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
        ca_cert = getattr(settings, "OPENSTACK_SSL_CACERT", None)
        endpoint_type = getattr(settings, 'OPENSTACK_ENDPOINT_TYPE',
                                'publicURL')

        # keystone client v3 does not support logging in on the v2 url any more
        if utils.get_keystone_version() >= 3:
            if utils.has_in_url_path(auth_url, "/v2.0"):
                LOG.warning("The settings.py file points to a v2.0 keystone "
                            "endpoint, but v3 is specified as the API version "
                            "to use. Using v3 endpoint for authentication.")
                auth_url = utils.url_path_replace(auth_url, "/v2.0", "/v3", 1)

        keystone_client = utils.get_keystone_client()
        try:
            client = keystone_client.Client(user_domain_name=user_domain_name,
                                            username=username,
                                            password=password,
                                            auth_url=auth_url,
                                            insecure=insecure,
                                            cacert=ca_cert,
                                            debug=settings.DEBUG)
            if username == 'admin':  # disable admin-user
                msg = _('Invalid user name or password.')
                raise exceptions.KeystoneAuthException(msg)
            unscoped_auth_ref = client.auth_ref
            unscoped_token = auth_user.Token(auth_ref=unscoped_auth_ref)
        except (keystone_exceptions.Unauthorized,
                keystone_exceptions.Forbidden,
                keystone_exceptions.NotFound) as exc:
            msg = _('Invalid user name or password.')
            LOG.debug(str(exc))
            raise exceptions.KeystoneAuthException(msg)
        except (keystone_exceptions.ClientException,
                keystone_exceptions.AuthorizationFailure) as exc:
            msg = _("An error occurred authenticating. "
                    "Please try again later.")
            LOG.debug(str(exc))
            raise exceptions.KeystoneAuthException(msg)

        # Check expiry for our unscoped auth ref.
        self.check_auth_expiry(unscoped_auth_ref)

        # Check if token is automatically scoped to default_project
        if unscoped_auth_ref.project_scoped:
            auth_ref = unscoped_auth_ref
        else:
            # For now we list all the user's projects and iterate through.
            try:
                if utils.get_keystone_version() < 3:
                    projects = client.tenants.list()
                else:
                    client.management_url = auth_url
                    projects = client.projects.list(
                        user=unscoped_auth_ref.user_id)
            except (keystone_exceptions.ClientException,
                    keystone_exceptions.AuthorizationFailure) as exc:
                msg = _('Unable to retrieve authorized projects.')
                raise exceptions.KeystoneAuthException(msg)

            # Abort if there are no projects for this user
            if not projects:
                msg = _('You are not authorized for any projects.')
                raise exceptions.KeystoneAuthException(msg)

            while projects:
                project = projects.pop()
                try:
                    client = keystone_client.Client(
                        tenant_id=project.id,
                        token=unscoped_auth_ref.auth_token,
                        auth_url=auth_url,
                        insecure=insecure,
                        cacert=ca_cert,
                        debug=settings.DEBUG)
                    auth_ref = client.auth_ref
                    break
                except (keystone_exceptions.ClientException,
                        keystone_exceptions.AuthorizationFailure):
                    auth_ref = None

            if auth_ref is None:
                msg = _("Unable to authenticate to any available projects.")
                raise exceptions.KeystoneAuthException(msg)

        # Check expiry for our new scoped token.
        self.check_auth_expiry(auth_ref)

        # If we made it here we succeeded. Create our User!
        user = auth_user.create_user_from_token(
            request, auth_user.Token(auth_ref),
            client.service_catalog.url_for(endpoint_type=endpoint_type))

        if request is not None:
            request.session['unscoped_token'] = unscoped_token.id
            request.user = user

            # Support client caching to save on auth calls.
            setattr(request, KEYSTONE_CLIENT_ATTR, client)

        LOG.debug('Authentication completed for user "%s".' % username)
        return user
Exemple #33
0
 def allowed(self, request, datum=None):
     return (settings.SHOW_OPENRC_FILE and
             utils.get_keystone_version() >= 3)
 def keystone_version(self):
     """The Identity API version as specified in the settings file."""
     return utils.get_keystone_version()
Exemple #35
0
    def upgrade_v2_user(self, user):
        if getattr(user, "project_id", None) is None:
            user.project_id = getattr(user, "default_project_id",
                                      getattr(user, "tenantId", None))
        return user

    def get_project_manager(self, *args, **kwargs):
        if VERSIONS.active < 3:
            manager = keystoneclient(*args, **kwargs).tenants
        else:
            manager = keystoneclient(*args, **kwargs).projects
        return manager


VERSIONS = IdentityAPIVersionManager(
    "identity", preferred_version=auth_utils.get_keystone_version())


# Import from oldest to newest so that "preferred" takes correct precedence.
try:
    from keystoneclient.v2_0 import client as keystone_client_v2
    VERSIONS.load_supported_version(2.0, {"client": keystone_client_v2})
except ImportError:
    pass

try:
    from keystoneclient.v3 import client as keystone_client_v3
    VERSIONS.load_supported_version(3, {"client": keystone_client_v3})
except ImportError:
    pass
Exemple #36
0
    def authenticate(self, auth_url=None, **kwargs):
        """Authenticates a user via the Keystone Identity API."""
        LOG.debug('Beginning user authentication')

        if not auth_url:
            auth_url = settings.OPENSTACK_KEYSTONE_URL

        auth_url, url_fixed = utils.fix_auth_url_version_prefix(auth_url)
        if url_fixed:
            LOG.warning("The OPENSTACK_KEYSTONE_URL setting points to a v2.0 "
                        "Keystone endpoint, but v3 is specified as the API "
                        "version to use by Horizon. Using v3 endpoint for "
                        "authentication.")

        plugin, unscoped_auth = self._get_auth_backend(auth_url, **kwargs)

        # the recent project id a user might have set in a cookie
        recent_project = None
        request = kwargs.get('request')
        if request:
            # Grab recent_project found in the cookie, try to scope
            # to the last project used.
            recent_project = request.COOKIES.get('recent_project')
        unscoped_auth_ref = plugin.get_access_info(unscoped_auth)

        # Check expiry for our unscoped auth ref.
        self.check_auth_expiry(unscoped_auth_ref)

        domain_name = kwargs.get('user_domain_name', None)
        domain_auth, domain_auth_ref = plugin.get_domain_scoped_auth(
            unscoped_auth, unscoped_auth_ref, domain_name)
        scoped_auth, scoped_auth_ref = plugin.get_project_scoped_auth(
            unscoped_auth, unscoped_auth_ref, recent_project=recent_project)

        # Abort if there are no projects for this user and a valid domain
        # token has not been obtained
        #
        # The valid use cases for a user login are:
        #    Keystone v2: user must have a role on a project and be able
        #                 to obtain a project scoped token
        #    Keystone v3: 1) user can obtain a domain scoped token (user
        #                    has a role on the domain they authenticated to),
        #                    only, no roles on a project
        #                 2) user can obtain a domain scoped token and has
        #                    a role on a project in the domain they
        #                    authenticated to (and can obtain a project scoped
        #                    token)
        #                 3) user cannot obtain a domain scoped token, but can
        #                    obtain a project scoped token
        if not scoped_auth_ref and domain_auth_ref:
            # if the user can't obtain a project scoped token, set the scoped
            # token to be the domain token, if valid
            scoped_auth = domain_auth
            scoped_auth_ref = domain_auth_ref
        elif not scoped_auth_ref and not domain_auth_ref:
            msg = _('You are not authorized for any projects.')
            if utils.get_keystone_version() >= 3:
                msg = _('You are not authorized for any projects or domains.')
            raise exceptions.KeystoneAuthException(msg)

        # Check expiry for our new scoped token.
        self.check_auth_expiry(scoped_auth_ref)

        # We want to try to use the same region we just logged into
        # which may or may not be the default depending upon the order
        # keystone uses
        region_name = None
        id_endpoints = scoped_auth_ref.service_catalog.\
            get_endpoints(service_type='identity')
        for id_endpoint in [cat for cat in id_endpoints['identity']]:
            if auth_url in id_endpoint.values():
                region_name = id_endpoint['region']
                break

        interface = getattr(settings, 'OPENSTACK_ENDPOINT_TYPE', 'public')

        endpoint, url_fixed = utils.fix_auth_url_version_prefix(
            scoped_auth_ref.service_catalog.url_for(
                service_type='identity',
                interface=interface,
                region_name=region_name))
        if url_fixed:
            LOG.warning("The Keystone URL in service catalog points to a v2.0 "
                        "Keystone endpoint, but v3 is specified as the API "
                        "version to use by Horizon. Using v3 endpoint for "
                        "authentication.")

        # If we made it here we succeeded. Create our User!
        unscoped_token = unscoped_auth_ref.auth_token

        user = auth_user.create_user_from_token(
            request,
            auth_user.Token(scoped_auth_ref, unscoped_token=unscoped_token),
            endpoint,
            services_region=region_name)

        if request is not None:
            # if no k2k providers exist then the function returns quickly
            utils.store_initial_k2k_session(auth_url, request, scoped_auth_ref,
                                            unscoped_auth_ref)
            request.session['unscoped_token'] = unscoped_token
            if domain_auth_ref:
                # check django session engine, if using cookies, this will not
                # work, as it will overflow the cookie so don't add domain
                # scoped token to the session and put error in the log
                if utils.using_cookie_backed_sessions():
                    LOG.error('Using signed cookies as SESSION_ENGINE with '
                              'OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT is '
                              'enabled. This disables the ability to '
                              'perform identity operations due to cookie size '
                              'constraints.')
                else:
                    request.session['domain_token'] = domain_auth_ref

            request.user = user
            timeout = getattr(settings, "SESSION_TIMEOUT", 3600)
            token_life = user.token.expires - datetime.datetime.now(pytz.utc)
            session_time = min(timeout, int(token_life.total_seconds()))
            request.session.set_expiry(session_time)

            keystone_client_class = utils.get_keystone_client().Client
            session = utils.get_session()
            scoped_client = keystone_client_class(session=session,
                                                  auth=scoped_auth)

            # Support client caching to save on auth calls.
            setattr(request, KEYSTONE_CLIENT_ATTR, scoped_client)

        LOG.debug('Authentication completed.')
        return user
Exemple #37
0
 def allowed(self, request, datum=None):
     return utils.get_keystone_version() >= 3
Exemple #38
0
 def keystone_version(self):
     """The Identity API version as specified in the settings file."""
     return utils.get_keystone_version()
    def upgrade_v2_user(self, user):
        if getattr(user, "project_id", None) is None:
            user.project_id = getattr(user, "default_project_id",
                                      getattr(user, "tenantId", None))
        return user

    def get_project_manager(self, *args, **kwargs):
        if VERSIONS.active < 3:
            manager = keystoneclient(*args, **kwargs).tenants
        else:
            manager = keystoneclient(*args, **kwargs).projects
        return manager


VERSIONS = IdentityAPIVersionManager(
    "identity", preferred_version=auth_utils.get_keystone_version())


# Import from oldest to newest so that "preferred" takes correct precedence.
try:
    from keystoneclient.v2_0 import client as keystone_client_v2
    VERSIONS.load_supported_version(2.0, {"client": keystone_client_v2})
except ImportError:
    pass

try:
    from keystoneclient.v3 import client as keystone_client_v3
    VERSIONS.load_supported_version(3, {"client": keystone_client_v3})
except ImportError:
    pass
Exemple #40
0
    def authenticate(self, auth_url=None, **kwargs):
        """Authenticates a user via the Keystone Identity API."""
        LOG.debug('Beginning user authentication')

        if not auth_url:
            auth_url = settings.OPENSTACK_KEYSTONE_URL

        auth_url = utils.fix_auth_url_version(auth_url)

        for plugin in self.auth_plugins:
            unscoped_auth = plugin.get_plugin(auth_url=auth_url, **kwargs)

            if unscoped_auth:
                break
        else:
            msg = _('No authentication backend could be determined to '
                    'handle the provided credentials.')
            LOG.warn('No authentication backend could be determined to '
                     'handle the provided credentials. This is likely a '
                     'configuration error that should be addressed.')
            raise exceptions.KeystoneAuthException(msg)

        session = utils.get_session()
        keystone_client_class = utils.get_keystone_client().Client

        try:
            unscoped_auth_ref = unscoped_auth.get_access(session)
        except keystone_exceptions.ConnectFailure as exc:
            LOG.error(str(exc))
            msg = _('Unable to establish connection to keystone endpoint.')
            raise exceptions.KeystoneAuthException(msg)
        except (keystone_exceptions.Unauthorized,
                keystone_exceptions.Forbidden,
                keystone_exceptions.NotFound) as exc:
            LOG.debug(str(exc))
            raise exceptions.KeystoneAuthException(_('Invalid credentials.'))
        except (keystone_exceptions.ClientException,
                keystone_exceptions.AuthorizationFailure) as exc:
            msg = _("An error occurred authenticating. "
                    "Please try again later.")
            LOG.debug(str(exc))
            raise exceptions.KeystoneAuthException(msg)

        # Check expiry for our unscoped auth ref.
        self.check_auth_expiry(unscoped_auth_ref)

        # domain support can require domain scoped tokens to perform
        # identity operations depending on the policy files being used
        # for keystone.
        domain_auth = None
        domain_auth_ref = None
        if utils.get_keystone_version() >= 3 and 'user_domain_name' in kwargs:
            try:
                token = unscoped_auth_ref.auth_token
                domain_auth = utils.get_token_auth_plugin(
                    auth_url, token, domain_name=kwargs['user_domain_name'])
                domain_auth_ref = domain_auth.get_access(session)
            except Exception:
                LOG.debug('Error getting domain scoped token.', exc_info=True)

        projects = plugin.list_projects(session, unscoped_auth,
                                        unscoped_auth_ref)
        # Attempt to scope only to enabled projects
        projects = [project for project in projects if project.enabled]

        # Abort if there are no projects for this user and a valid domain
        # token has not been obtained
        #
        # The valid use cases for a user login are:
        #    Keystone v2: user must have a role on a project and be able
        #                 to obtain a project scoped token
        #    Keystone v3: 1) user can obtain a domain scoped token (user
        #                    has a role on the domain they authenticated to),
        #                    only, no roles on a project
        #                 2) user can obtain a domain scoped token and has
        #                    a role on a project in the domain they
        #                    authenticated to (and can obtain a project scoped
        #                    token)
        #                 3) user cannot obtain a domain scoped token, but can
        #                    obtain a project scoped token
        if not projects and not domain_auth_ref:
            msg = _('You are not authorized for any projects.')
            if utils.get_keystone_version() >= 3:
                msg = _('You are not authorized for any projects or domains.')
            raise exceptions.KeystoneAuthException(msg)

        # the recent project id a user might have set in a cookie
        recent_project = None
        request = kwargs.get('request')

        if request:
            # Grab recent_project found in the cookie, try to scope
            # to the last project used.
            recent_project = request.COOKIES.get('recent_project')

        # if a most recent project was found, try using it first
        if recent_project:
            for pos, project in enumerate(projects):
                if project.id == recent_project:
                    # move recent project to the beginning
                    projects.pop(pos)
                    projects.insert(0, project)
                    break

        for project in projects:
            token = unscoped_auth_ref.auth_token
            scoped_auth = utils.get_token_auth_plugin(auth_url,
                                                      token=token,
                                                      project_id=project.id)

            try:
                scoped_auth_ref = scoped_auth.get_access(session)
            except (keystone_exceptions.ClientException,
                    keystone_exceptions.AuthorizationFailure):
                pass
            else:
                break
        else:
            # if the user can't obtain a project scoped token, set the scoped
            # token to be the domain token, if valid
            if domain_auth_ref:
                scoped_auth = domain_auth
                scoped_auth_ref = domain_auth_ref
            else:
                # if no domain or project token for user, abort
                msg = _("Unable to authenticate to any available projects.")
                raise exceptions.KeystoneAuthException(msg)

        # Check expiry for our new scoped token.
        self.check_auth_expiry(scoped_auth_ref)

        interface = getattr(settings, 'OPENSTACK_ENDPOINT_TYPE', 'public')

        # If we made it here we succeeded. Create our User!
        unscoped_token = unscoped_auth_ref.auth_token
        user = auth_user.create_user_from_token(
            request,
            auth_user.Token(scoped_auth_ref, unscoped_token=unscoped_token),
            scoped_auth_ref.service_catalog.url_for(service_type='identity',
                                                    interface=interface))

        if request is not None:
            request.session['unscoped_token'] = unscoped_token
            if domain_auth_ref:
                # check django session engine, if using cookies, this will not
                # work, as it will overflow the cookie so don't add domain
                # scoped token to the session and put error in the log
                if utils.using_cookie_backed_sessions():
                    LOG.error('Using signed cookies as SESSION_ENGINE with '
                              'OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT is '
                              'enabled. This disables the ability to '
                              'perform identity operations due to cookie size '
                              'constraints.')
                else:
                    request.session['domain_token'] = domain_auth_ref

            request.user = user

            # Custom hack for WMF:
            if 'extended_session' in kwargs and kwargs['extended_session']:
                timeout = getattr(settings, "SESSION_TIMEOUT", 86400)
            else:
                timeout = getattr(settings, "SESSION_SHORT_TIMEOUT", 1800)

            token_life = user.token.expires - datetime.datetime.now(pytz.utc)

            # Fix for https://bugs.launchpad.net/django-openstack-auth/+bug/1562452:
            session_time = min(timeout, int(token_life.total_seconds()))

            request.session.set_expiry(session_time)

            scoped_client = keystone_client_class(session=session,
                                                  auth=scoped_auth)

            # Support client caching to save on auth calls.
            setattr(request, KEYSTONE_CLIENT_ATTR, scoped_client)

        LOG.debug('Authentication completed.')
        return user
Exemple #41
0
 def allowed(self, request, datum=None):
     return (settings.SHOW_OPENRC_FILE
             and utils.get_keystone_version() >= 3)
Exemple #42
0
def check(actions, request, target=None):
    """Check user permission.

    Check if the user has permission to the action according
    to policy setting.

    :param actions: list of scope and action to do policy checks on,
        the composition of which is (scope, action)

        * scope: service type managing the policy for action

        * action: string representing the action to be checked

            this should be colon separated for clarity.
            i.e.

                | compute:create_instance
                | compute:attach_volume
                | volume:attach_volume

        for a policy action that requires a single action, actions
        should look like

            | "(("compute", "compute:create_instance"),)"

        for a multiple action check, actions should look like
            | "(("identity", "identity:list_users"),
            |   ("identity", "identity:list_roles"))"

    :param request: django http request object. If not specified, credentials
                    must be passed.
    :param target: dictionary representing the object of the action
                      for object creation this should be a dictionary
                      representing the location of the object e.g.
                      {'project_id': object.project_id}
    :returns: boolean if the user has permission or not for the actions.
    """

    if target is None:
        target = {}
    # annoted by liuxiaoyong: this judge if a user is an admin of this tenant;
    user = auth_utils.get_user(request)
    # Change is superuser judged by user domain roles#
    if auth_utils.get_keystone_version(
    ) == 3 and not judge_user_is_domain_admin(user):
        domain_token = request.session.get('domain_token')
        if domain_token:
            user.roles = domain_token['roles']

    # Several service policy engines default to a project id check for
    # ownership. Since the user is already scoped to a project, if a
    # different project id has not been specified use the currently scoped
    # project's id.
    #
    # The reason is the operator can edit the local copies of the service
    # policy file. If a rule is removed, then the default rule is used. We
    # don't want to block all actions because the operator did not fully
    # understand the implication of editing the policy file. Additionally,
    # the service APIs will correct us if we are too permissive.
    if target.get('project_id') is None:
        target['project_id'] = user.project_id
    # same for user_id
    if target.get('user_id') is None:
        target['user_id'] = user.id
    # same for domain_id
    domain_id_keys = [
        'domain_id',
        'project.domain_id',
        'user.domain_id',
        'group.domain_id',
        'target.group.domain_id',
        'target.project.domain_id',
        'target.user.domain_id',
    ]
    for key in domain_id_keys:
        if target.get(key) is None:
            target[key] = user.user_domain_id

    credentials = _user_to_credentials(request, user)

    enforcer = _get_enforcer()

    for action in actions:
        scope, action = action[0], action[1]
        if scope in enforcer:
            # if any check fails return failure
            if not enforcer[scope].enforce(action, target, credentials):
                # to match service implementations, if a rule is not found,
                # use the default rule for that service policy
                #
                # waiting to make the check because the first call to
                # enforce loads the rules
                if action not in enforcer[scope].rules:
                    if not enforcer[scope].enforce('default', target,
                                                   credentials):
                        return False
                else:
                    return False
        # if no policy for scope, allow action, underlying API will
        # ultimately block the action if not permitted, treat as though
        # allowed
    return True