Exemple #1
0
    def get_auth_ref(self, session, **kwargs):
        headers = {'Accept': 'application/json'}
        url = self.auth_url.rstrip('/') + '/tokens'
        params = {'auth': self.get_auth_data(headers)}

        if self.tenant_id:
            params['auth']['tenantId'] = self.tenant_id
        elif self.tenant_name:
            params['auth']['tenantName'] = self.tenant_name
        if self.trust_id:
            params['auth']['trust_id'] = self.trust_id

        _logger.debug('Making authentication request to %s', url)
        resp = session.post(url,
                            json=params,
                            headers=headers,
                            authenticated=False,
                            log=False)

        try:
            resp_data = resp.json()
        except ValueError:
            raise exceptions.InvalidResponse(response=resp)

        if 'access' not in resp_data:
            raise exceptions.InvalidResponse(response=resp)

        return access.AccessInfoV2(resp_data)
Exemple #2
0
    def get_auth_ref(self, session, **kwargs):
        """Obtain a token from a v1 endpoint.

        This function should not be called independently and is expected to be
        invoked via the do_authenticate function.

        This function will be invoked if the AcessInfo object cached by the
        plugin is not valid. Thus plugins should always fetch a new AccessInfo
        when invoked. If you are looking to just retrieve the current auth
        data then you should use get_access.

        :param session: A session object that can be used for communication.

        :returns: Token access information.
        """
        headers = {'X-Auth-User': self.user,
                   'X-Auth-Key': self.key}

        resp = session.get(self.auth_url, headers=headers,
                           authenticated=False, log=False)

        if resp.status_code // 100 != 2:
            raise exceptions.InvalidResponse(response=resp)

        if 'X-Storage-Url' not in resp.headers:
            raise exceptions.InvalidResponse(response=resp)

        if 'X-Auth-Token' not in resp.headers and \
                'X-Storage-Token' not in resp.headers:
            raise exceptions.InvalidResponse(response=resp)
        token = resp.headers.get('X-Storage-Token',
                                 resp.headers.get('X-Auth-Token'))
        return AccessInfoV1(
            auth_url=self.auth_url,
            storage_url=resp.headers['X-Storage-Url'],
            account=self.account,
            username=self.user,
            auth_token=token,
            token_life=resp.headers.get('X-Auth-Token-Expires'))
Exemple #3
0
    def _get_ecp_assertion(self, session):
        body = {
            'auth': {
                'identity': {
                    'methods': ['token'],
                    'token': {
                        'id': self._local_cloud_plugin.get_token(session)
                    }
                },
                'scope': {
                    'service_provider': {
                        'id': self._sp_id
                    }
                }
            }
        }

        endpoint_filter = {
            'version': (3, 0),
            'interface': plugin.AUTH_INTERFACE
        }

        headers = {'Accept': 'application/json'}

        resp = session.post(self.REQUEST_ECP_URL,
                            json=body,
                            auth=self._local_cloud_plugin,
                            endpoint_filter=endpoint_filter,
                            headers=headers,
                            authenticated=False,
                            raise_exc=False)

        # NOTE(marek-denis): I am not sure whether disabling exceptions in the
        # Session object and testing if resp.ok is sufficient. An alternative
        # would be catching locally all exceptions and reraising with custom
        # warning.
        if not resp.ok:
            msg = ("Error while requesting ECP wrapped assertion: response "
                   "exit code: %(status_code)d, reason: %(err)s")
            msg = msg % {'status_code': resp.status_code, 'err': resp.reason}
            raise exceptions.AuthorizationFailure(msg)

        if not resp.text:
            raise exceptions.InvalidResponse(resp)

        return six.text_type(resp.text)
Exemple #4
0
    def _get_ecp_assertion(self, session):
        url = self._local_cloud_plugin.get_endpoint(
            session, interface=plugin.AUTH_INTERFACE)
        body = self._ecp_assertion_request(session)

        resp = session.post(url=url + self.REQUEST_ECP_URL,
                            json=body,
                            raise_exc=False)

        # NOTE(marek-denis): I am not sure whether disabling exceptions in the
        # Session object and testing if resp.ok is sufficient. An alternative
        # would be catching locally all exceptions and reraising with custom
        # warning.
        if not resp.ok:
            msg = ("Error while requesting ECP wrapped assertion: response "
                   "exit code: %(status_code)d, reason: %(err)s")
            msg = msg % {'status_code': resp.status_code, 'err': resp.reason}
            raise exceptions.AuthorizationFailure(msg)

        if not resp.text:
            raise exceptions.InvalidResponse(resp)

        return six.text_type(resp.text)
Exemple #5
0
    def get_auth_ref(self, session, **kwargs):
        headers = {'Accept': 'application/json'}
        body = {'auth': {'identity': {}}}
        ident = body['auth']['identity']
        rkwargs = {}

        for method in self.auth_methods:
            name, auth_data = method.get_auth_data(session,
                                                   self,
                                                   headers,
                                                   request_kwargs=rkwargs)
            ident.setdefault('methods', []).append(name)
            ident[name] = auth_data

        if not ident:
            raise exceptions.AuthorizationFailure(
                'Authentication method required (e.g. password)')

        mutual_exclusion = [
            bool(self.domain_id or self.domain_name),
            bool(self.project_id or self.project_name),
            bool(self.trust_id),
            bool(self.unscoped)
        ]

        if sum(mutual_exclusion) > 1:
            raise exceptions.AuthorizationFailure(
                'Authentication cannot be scoped to multiple targets. Pick '
                'one of: project, domain, trust or unscoped')

        if self.domain_id:
            body['auth']['scope'] = {'domain': {'id': self.domain_id}}
        elif self.domain_name:
            body['auth']['scope'] = {'domain': {'name': self.domain_name}}
        elif self.project_id:
            body['auth']['scope'] = {'project': {'id': self.project_id}}
        elif self.project_name:
            scope = body['auth']['scope'] = {'project': {}}
            scope['project']['name'] = self.project_name

            if self.project_domain_id:
                scope['project']['domain'] = {'id': self.project_domain_id}
            elif self.project_domain_name:
                scope['project']['domain'] = {'name': self.project_domain_name}
        elif self.trust_id:
            body['auth']['scope'] = {'OS-TRUST:trust': {'id': self.trust_id}}
        elif self.unscoped:
            body['auth']['scope'] = {'unscoped': {}}

        # NOTE(jamielennox): we add nocatalog here rather than in token_url
        # directly as some federation plugins require the base token_url
        token_url = self.token_url
        if not self.include_catalog:
            token_url += '?nocatalog'

        _logger.debug('Making authentication request to %s', token_url)
        resp = session.post(token_url,
                            json=body,
                            headers=headers,
                            authenticated=False,
                            log=False,
                            **rkwargs)

        try:
            _logger.debug(json.dumps(resp.json()))
            resp_data = resp.json()
        except ValueError:
            raise exceptions.InvalidResponse(response=resp)

        if 'token' not in resp_data:
            raise exceptions.InvalidResponse(response=resp)

        return access.AccessInfoV3(auth_token=resp.headers['X-Subject-Token'],
                                   body=resp_data)
    def get_auth_ref(self, session, **kwargs):
        headers = {'Accept': 'application/json'}
        body = {'auth': {'identity': {}}}
        ident = body['auth']['identity']
        rkwargs = {}

        for method in self.auth_methods:
            name, auth_data = method.get_auth_data(session,
                                                   self,
                                                   headers,
                                                   request_kwargs=rkwargs)
            ident.setdefault('methods', []).append(name)
            ident[name] = auth_data

        if not ident:
            raise exceptions.AuthorizationFailure(
                'Authentication method required (e.g. password)')

        mutual_exclusion = [
            bool(self.domain_id or self.domain_name),
            bool(self.project_id or self.project_name),
            bool(self.trust_id),
            bool(self.unscoped)
        ]

        if sum(mutual_exclusion) > 1:
            raise exceptions.AuthorizationFailure(
                'Authentication cannot be scoped to multiple targets. Pick '
                'one of: project, domain, trust or unscoped')

        if self.domain_id:
            body['auth']['scope'] = {'domain': {'id': self.domain_id}}
        elif self.domain_name:
            body['auth']['scope'] = {'domain': {'name': self.domain_name}}
        elif self.project_id:
            body['auth']['scope'] = {'project': {'id': self.project_id}}
        elif self.project_name:
            scope = body['auth']['scope'] = {'project': {}}
            scope['project']['name'] = self.project_name

            if self.project_domain_id:
                scope['project']['domain'] = {'id': self.project_domain_id}
            elif self.project_domain_name:
                scope['project']['domain'] = {'name': self.project_domain_name}
        elif self.trust_id:
            body['auth']['scope'] = {'OS-TRUST:trust': {'id': self.trust_id}}
        elif self.unscoped:
            body['auth']['scope'] = 'unscoped'
        elif self.system_scope:
            # NOTE(lbragstad): Right now it's only possible to have role
            # assignments on the entire system. In the future that might change
            # so that users and groups can have roles on parts of the system,
            # like a specific service in a specific region. If that happens,
            # this will have to be accounted for here. Until then we'll only
            # support scoping to the entire system.
            if self.system_scope == 'all':
                body['auth']['scope'] = {'system': {'all': True}}

        # NOTE(jamielennox): we add nocatalog here rather than in token_url
        # directly as some federation plugins require the base token_url
        token_url = self.token_url
        if not self.include_catalog:
            token_url += '?nocatalog'

        _logger.debug('Making authentication request to %s', token_url)
        resp = session.post(token_url,
                            json=body,
                            headers=headers,
                            authenticated=False,
                            log=False,
                            **rkwargs)

        try:
            _logger.debug(json.dumps(resp.json()))
            resp_data = resp.json()
        except ValueError:
            raise exceptions.InvalidResponse(response=resp)

        if 'token' not in resp_data:
            raise exceptions.InvalidResponse(response=resp)

        return access.AccessInfoV3(auth_token=resp.headers['X-Subject-Token'],
                                   body=resp_data)
    def get_auth_ref(self, session, **kwargs):
        # First do regular authorization
        auth_access = super(Agency, self).get_auth_ref(session, **kwargs)
        # And now reauth with another scope
        headers = {
            'Accept': 'application/json',
            'X-Auth-Token': auth_access._auth_token
        }
        body = {'auth': {'identity': {}}}
        ident = body['auth']['identity']
        rkwargs = {}

        for method in self.auth_methods:
            name, auth_data = method.get_assume_role_auth_data(
                session, self, headers, request_kwargs=rkwargs)
            # NOTE(adriant): Methods like ReceiptMethod don't
            # want anything added to the request data, so they
            # explicitly return None, which we check for.
            if name:
                ident.setdefault('methods', []).append(name)
                ident[name] = auth_data

        if not ident:
            raise exceptions.AuthorizationFailure(
                'Authentication method required (e.g. password)')

        if self.target_project_id:
            body['auth']['scope'] = {'project': {'id': self.target_project_id}}
        elif self.target_project_name:
            scope = body['auth']['scope'] = {'project': {}}
            scope['project']['name'] = self.target_project_name
        # If project is not set - get a domain scope
        elif self.target_domain_id:
            body['auth']['scope'] = {'domain':
                                     {'id': self.target_domain_id}}
        elif self.target_domain_name:
            body['auth']['scope'] = {'domain':
                                     {'name': self.target_domain_name}}

        token_url = self.token_url

        if not self.auth_url.rstrip('/').endswith('v3'):
            token_url = '%s/v3/auth/tokens' % self.auth_url.rstrip('/')

        if not self.include_catalog:
            token_url += '?nocatalog'

        _logger.debug('Making authentication request to %s', token_url)
        resp = session.post(token_url, json=body, headers=headers,
                            authenticated=False, log=False, **rkwargs)

        try:
            _logger.debug(json.dumps(resp.json()))
            resp_data = resp.json()
        except ValueError:
            raise exceptions.InvalidResponse(response=resp)

        if 'token' not in resp_data:
            raise exceptions.InvalidResponse(response=resp)

        return access.AccessInfoV3(auth_token=resp.headers['X-Subject-Token'],
                                   body=resp_data)