Ejemplo n.º 1
0
    def _create_auth_plugin(self):
        if self.auth_token_info:
            auth_ref = access.AccessInfoV3(self.auth_token_info,
                                           auth_token=self.auth_token)
            return access_plugin.AccessInfoPlugin(
                auth_url=self.keystone_v3_endpoint,
                auth_ref=auth_ref)

        if self.auth_token:
            # FIXME(jamielennox): This is broken but consistent. If you
            # only have a token but don't load a service catalog then
            # url_for wont work. Stub with the keystone endpoint so at
            # least it might be right.
            return token_endpoint.Token(endpoint=self.keystone_v3_endpoint,
                                        token=self.auth_token)

        if self.password:
            return v3.Password(username=self.username,
                               password=self.password,
                               project_id=self.tenant_id,
                               user_domain_id=self.user_domain,
                               auth_url=self.keystone_v3_endpoint)

        LOG.error(_LE("Keystone v3 API connection failed, no password "
                      "trust or auth_token!"))
        raise exception.AuthorizationFailure()
Ejemplo n.º 2
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)