Exemplo n.º 1
0
def switch_tenants(request, tenant_id):
    """
    Swaps a user from one tenant to another using the unscoped token from
    Keystone to exchange scoped tokens for the new tenant.
    """
    if request.user.tenant_id == tenant_id:
        return True

    endpoint = request.user.endpoint
    unscoped_token = request.session.get('unscoped_token', None)

    if unscoped_token:
        try:
            token = api.token_create_scoped(request,
                                            tenant_id,
                                            unscoped_token)
            user = create_user_from_token(request, token, endpoint)
            request.user = user
            set_session_from_user(request, user)
            return request.user
        except Unauthorized:
            raise
        except Exception, e:
            LOG.error('User(%s) can not authorize project %s. Error: %s'
                      % (request.user.id, tenant_id, e))
        return None
Exemplo n.º 2
0
    def authenticate(self, request=None, username=None, password=None, tenant=None, auth_url=None):
        """ Authenticates a user via the Keystone Identity API. """
        LOG.debug('Beginning user authentication for user "%s".' % username)

        try:
            client = keystone_client.Client(username=username, password=password, tenant_id=tenant, auth_url=auth_url)
            unscoped_token_data = {"token": client.service_catalog.get_token()}
            unscoped_token = Token(TokenManager(None), unscoped_token_data, loaded=True)
        except keystone_exceptions.Unauthorized:
            msg = _("Invalid user name or password, or you are not " "authorized to access the DreamCompute service")
            raise KeystoneAuthException(msg)
        except (keystone_exceptions.ClientException, keystone_exceptions.AuthorizationFailure):
            msg = _("An error occurred authenticating. " "Please try again later.")
            raise KeystoneAuthException(msg)

        # Check expiry for our unscoped token.
        self.check_auth_expiry(unscoped_token)

        # FIXME: Log in to default tenant when the Keystone API returns it...
        # For now we list all the user's tenants and iterate through.
        try:
            tenants = client.tenants.list()
        except (keystone_exceptions.ClientException, keystone_exceptions.AuthorizationFailure):
            msg = _("Unable to retrieve authorized projects.")
            raise KeystoneAuthException(msg)

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

        while tenants:
            tenant = tenants.pop()
            try:
                token = client.tokens.authenticate(username=username, token=unscoped_token.id, tenant_id=tenant.id)
                break
            except (keystone_exceptions.ClientException, keystone_exceptions.AuthorizationFailure):
                token = None

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

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

        # If we made it here we succeeded. Create our User!
        user = create_user_from_token(request, token, client.management_url)

        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, token=None, request=None):
        """ Reads in a Facebook code and asks Facebook
            if it's valid and what user it points to. """
        logger.error('test')
        keystone = KeystoneBackend()
        self.keystone = keystone

        # Get a legit access token from Facebook
        access_token, fb_profile = self.facebook_get_token_profile(token, request)
        if not access_token:
            # No access token means failed auth to FB
            msg = _("Facebook login invalid or Token Expired")
            messages.error(request, msg)
            logger.error(msg)
            return None

        facebook_id = fb_profile['id']

        # verify TryStack group membership
        if not self.facebook_trystack_group_member(access_token):
            msg = _("Facebook id %s is not a member of the TryStack Facebook group" % facebook_id)
            messages.error(request, msg)
            logger.error(msg)
            return None

        #### If we got here then auth and group membership are valid
        #### time to ensure the user exists and get a token

        # create user and tenant if they don't exist
        username = tenant_name = "facebook%s" % facebook_id
        password = "".join([random.choice(
                           string.ascii_lowercase + string.digits)
                           for i in range(8)])
        if not self.keystone_user_exists(username):
            tenant = self.add_keystone_user(settings, tenant_name, password, fb_profile)
        else:
            tenant = self.get_keystone_tenant(tenant_name)


        # get a keystone token for the user (requires the custom auth filter)
        d = '{"auth":{"%s": "customer-x", "passwordCredentials": {"username": "******", "password": "******"}}}' % (username, username)
        url = "%s/tokens/" % self.keystone_get_endpoint('keystone', 'adminurl')
        headers = {'Content-Type': 'application/json; charset=UTF-8', 'X-Auth-Token': settings.ADMIN_TOKEN}
        resp, content = Http().request(uri=url, method="POST", headers=headers, body=d)

        # load the token, create a new client based on the token
        auth_json = json.loads(content)['access']
        client = keystone_client.Client(username=username,
                                        tenant_name=username,
                                        token=auth_json['token']['id'],
                                        auth_url=settings.OPENSTACK_KEYSTONE_URL)
        # use the client and token to create a Token object
        token = Token(auth_ref=client.auth_ref)
        # generate a django user (this is how openstack_auth.backend does it too)
        user = create_user_from_token(request, token, settings.OPENSTACK_KEYSTONE_URL)
                          #client.service_catalog.url_for(endpoint_type='publicURL'))
        return user
Exemplo n.º 4
0
 def get_user(self, user_id):
     if (hasattr(self, 'request') and
             user_id == self.request.session["user_id"]):
         token = self.request.session['token']
         endpoint = self.request.session['region_endpoint']
         services_region = self.request.session['services_region']
         user = auth_user.create_user_from_token(self.request, token,
                                                 endpoint, services_region)
         return user
     else:
         return None
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))

    endpoint = utils.fix_auth_url_version(request.user.endpoint)
    session = utils.get_session()
    # Keystone can be configured to prevent exchanging a scoped token for
    # another token. Always use the unscoped token for requesting a
    # scoped token.
    unscoped_token = request.user.unscoped_token
    auth = utils.get_token_auth_plugin(auth_url=endpoint,
                                       token=unscoped_token,
                                       project_id=tenant_id)

    try:
        auth_ref = auth.get_access(session)
        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})
        messages.error(request, 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, unscoped_token=unscoped_token),
            endpoint)
        auth_user.set_session_from_user(request, user)
        message = (
            _('Switch to project "%(project_name)s" successful.') %
            {'project_name': request.user.project_name})
        messages.success(request, message)
    response = shortcuts.redirect(redirect_to)
    utils.set_response_cookie(response, 'recent_project',
                              request.user.project_id)
    return response
Exemplo n.º 6
0
def login(request, **kwargs):
    '''
    Logs a user in using the :class:`~openstack_auth.forms.Login` form.
    Referenced from openstack_auth.views.login
    '''
    if not request.is_ajax():
        # If the user is already authenticated, redirect them to the
        # dashboard straight away, unless the 'next' parameter is set as it
        # usually indicates requesting access to a page that requires different
        # permissions.
        if request.user.is_authenticated():
            return HttpResponseRedirect('/')

    # Get our initial region for the form.
    form = functional.curry(openstack_auth_form)
    template_name = 'auth/login.html'
    res = django_auth_views.login(request,
                                  template_name=template_name,
                                  authentication_form=form,
                                  **kwargs)

    # Save the region in the cookie, this is used as the default
    # selected region next time the Login form loads.
    if request.method == "POST":
        openstack_auth_utils.set_response_cookie(res, 'login_region',
                                                 request.POST.get('region', ''))
        openstack_auth_utils.set_response_cookie(res, 'login_domain',
                                                 request.POST.get('domain', ''))

    # Set the session data here because django's session key rotation
    # will erase it if we set it earlier.
    print request.user.is_authenticated()
    if request.user.is_authenticated():
        openstack_auth_user.set_session_from_user(request, request.user)
        session = openstack_auth_utils.get_session()
        user_endpoint = settings.OPENSTACK_KEYSTONE_URL
        auth = openstack_auth_utils.get_token_auth_plugin(auth_url=user_endpoint,
                                       token=request.user.unscoped_token,
                                       project_id=settings.ADMIN_TENANT_ID)

        try:
            auth_ref = auth.get_access(session)
        except keystone_client_exceptions.ClientException as e:
            auth_ref = None

        if auth_ref:
            new_user = openstack_auth_user.create_user_from_token(request,
                                                                  openstack_auth_user.Token(auth_ref),
                                                                  endpoint=request.user.endpoint)
            openstack_auth_user.set_session_from_user(request, new_user)

    return res
Exemplo n.º 7
0
    def _process_auth_ref(self, request, auth_ref, auth_url):
        # Check expiry for our unscoped auth ref.
        self.check_auth_expiry(auth_ref)

        addr_link = read_address_link(auth_ref['user']['idAddress'])
        if addr_link:
            auth_ref['addressLink'] = addr_link
        user = create_user_from_token(request, Token(auth_ref),
                                      endpoint=auth_url)
        if request is not None:
            request.session['unscoped_token'] = auth_ref['auth_token']
            request.user = user

        LOG.debug('Authentication completed for user "%s".' %
                  auth_ref['user']['name'])
        return user
Exemplo n.º 8
0
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_user(self, user_id):
        """Returns the current user (if authenticated) based on the user ID
        and session data.

        Note: this required monkey-patching the ``contrib.auth`` middleware
        to make the ``request`` object available to the auth backend class.
        """
        if (hasattr(self, 'request') and
                user_id == self.request.session["user_id"]):
            token = self.request.session['token']
            endpoint = self.request.session['region_endpoint']
            services_region = self.request.session['services_region']
            user = auth_user.create_user_from_token(self.request, token,
                                                    endpoint, services_region)
            return user
        else:
            return None
Exemplo n.º 10
0
def _domain_to_credentials(request, user):
    if not hasattr(user, "_domain_credentials"):
        try:
            domain_auth_ref = request.session.get('domain_token')

            # no domain role or not running on V3
            if not domain_auth_ref:
                return None
            domain_user = auth_user.create_user_from_token(
                request, auth_user.Token(domain_auth_ref),
                domain_auth_ref.service_catalog.url_for(interface=None))
            user._domain_credentials = _user_to_credentials(domain_user)

            # uses the domain_id associated with the domain_user
            user._domain_credentials['domain_id'] = domain_user.domain_id

        except Exception:
            LOG.warning("Failed to create user from domain scoped token.")
            return None
    return user._domain_credentials
Exemplo n.º 11
0
def set_user_admin_token(request):
    """
    Via admin account login again when admin token is expired.
    """
    from keystoneclient.v2_0 import client as keystone_client
    from keystoneclient import exceptions as keystone_exceptions
    from keystoneclient.v2_0.tokens import Token, TokenManager
    from openstack_auth.exceptions import KeystoneAuthException
    from openstack_auth.utils import is_ans1_token

    insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
    endpoint = request.user.endpoint
    try:
        password = getattr(settings, 'OPENSTACK_ADMIN_TOKEN', 'admin')
        client = keystone_client.Client(username=u'admin',
                                        password=password,
                                        tenant_id='',
                                        auth_url=endpoint,
                                        insecure=insecure)

        unscoped_token_data = {"token": client.service_catalog.get_token()}
        unscoped_token = Token(TokenManager(None),
                               unscoped_token_data,
                               loaded=True)
    except (keystone_exceptions.Unauthorized, keystone_exceptions.Forbidden,
            keystone_exceptions.NotFound) as exc:
        msg = _('Invalid user name or password.')
        LOG.debug(exc.message)
        raise KeystoneAuthException(msg)
    except (keystone_exceptions.ClientException,
            keystone_exceptions.AuthorizationFailure) as exc:
        msg = _("An error occurred authenticating. " "Please try again later.")
        LOG.debug(exc.message)
        raise KeystoneAuthException(msg)

    # FIXME: Log in to default tenant when the Keystone API returns it...
    # For now we list all the user's tenants and iterate through.
    try:
        tenants = client.tenants.list()
    except (keystone_exceptions.ClientException,
            keystone_exceptions.AuthorizationFailure):
        msg = _('Unable to retrieve authorized projects.')
        raise KeystoneAuthException(msg)

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

    while tenants:
        tenant = tenants.pop()
        try:
            token = api.token_create_scoped(request, tenant.id,
                                            unscoped_token.id)
            break
        except (keystone_exceptions.ClientException,
                keystone_exceptions.AuthorizationFailure):
            token = None

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

    # If we made it here we succeeded. Create our User!
    user = create_user_from_token(request, token, endpoint)

    if request is not None:
        if is_ans1_token(unscoped_token.id):
            hashed_token = hashlib.md5(unscoped_token.id).hexdigest()
            unscoped_token._info['token']['id'] = hashed_token
        request.session['unscoped_token'] = unscoped_token.id
        request.user = user
        set_session_from_user(request, request.user)

    return user
Exemplo n.º 12
0
    def authenticate(self, request=None, username=None, password=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')
        auth_url = getattr(
            settings, "OPENSTACK_KEYSTONE_URL", "http://0.0.0.0:5000/v2.0")

        keystone_client = utils.get_keystone_client()
        try:
            client = keystone_client.Client(
                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))
            return None
        except (keystone_exceptions.ClientException,
                keystone_exceptions.AuthorizationFailure) as exc:
            msg = _("An error occurred authenticating. "
                    "Please try again later.")
            LOG.debug(str(exc))
            return None

        # 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:
            return None

        # 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),
            auth_url)

        if request is not None:
            auth_user.set_session_from_user(request, user)

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

        logging.error('Authentication completed for user "%s".' % username)
        return user
Exemplo n.º 13
0
def set_user_admin_token(request):
    """
    Via admin account login again when admin token is expired.
    """
    from keystoneclient.v2_0 import client as keystone_client
    from keystoneclient import exceptions as keystone_exceptions
    from keystoneclient.v2_0.tokens import Token, TokenManager
    from openstack_auth.exceptions import KeystoneAuthException
    from openstack_auth.utils import is_ans1_token

    insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
    endpoint = request.user.endpoint
    try:
        password = getattr(settings, 'OPENSTACK_ADMIN_TOKEN', 'admin')
        client = keystone_client.Client(username=u'admin',
                                        password=password,
                                        tenant_id='',
                                        auth_url=endpoint,
                                        insecure=insecure)

        unscoped_token_data = {"token": client.service_catalog.get_token()}
        unscoped_token = Token(TokenManager(None),
                                unscoped_token_data,
                                loaded=True)
    except (keystone_exceptions.Unauthorized,
            keystone_exceptions.Forbidden,
            keystone_exceptions.NotFound) as exc:
        msg = _('Invalid user name or password.')
        LOG.debug(exc.message)
        raise KeystoneAuthException(msg)
    except (keystone_exceptions.ClientException,
            keystone_exceptions.AuthorizationFailure) as exc:
        msg = _("An error occurred authenticating. "
                "Please try again later.")
        LOG.debug(exc.message)
        raise KeystoneAuthException(msg)

    # FIXME: Log in to default tenant when the Keystone API returns it...
    # For now we list all the user's tenants and iterate through.
    try:
        tenants = client.tenants.list()
    except (keystone_exceptions.ClientException,
            keystone_exceptions.AuthorizationFailure):
        msg = _('Unable to retrieve authorized projects.')
        raise KeystoneAuthException(msg)

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

    while tenants:
        tenant = tenants.pop()
        try:
            token = api.token_create_scoped(request,
                                            tenant.id,
                                            unscoped_token.id)
            break
        except (keystone_exceptions.ClientException,
                keystone_exceptions.AuthorizationFailure):
            token = None

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

    # If we made it here we succeeded. Create our User!
    user = create_user_from_token(request,
                                token,
                                endpoint)

    if request is not None:
        if is_ans1_token(unscoped_token.id):
            hashed_token = hashlib.md5(unscoped_token.id).hexdigest()
            unscoped_token._info['token']['id'] = hashed_token
        request.session['unscoped_token'] = unscoped_token.id
        request.user = user
        set_session_from_user(request, request.user)

    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
Exemplo n.º 15
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.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
Exemplo n.º 16
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.ConnectionRefused 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)

        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
        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
        request = kwargs.get('request')

        if request:
            # 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
            recent_project = request.COOKIES.get('recent_project',
                                                 unscoped_auth_ref.project_id)

        # 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:
            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(endpoint_type=interface))

        if request is not None:
            request.session['unscoped_token'] = unscoped_token
            request.user = user
            timeout = getattr(settings, "SESSION_TIMEOUT", 3600)
            token_life = user.token.expires - datetime.datetime.now(pytz.utc)
            session_time = min(timeout, token_life.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
Exemplo n.º 17
0
    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
Exemplo n.º 19
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.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
Exemplo n.º 20
0
    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
Exemplo n.º 21
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