def create_domain_config(self, context, domain_id, config):
     original_config = self.domain_config_api.get_config_with_sensitive_info(domain_id)
     ref = self.domain_config_api.create_config(domain_id, config)
     if original_config:
         # Return status code 200, since config already existed
         return wsgi.render_response(body={self.member_name: ref})
     else:
         return wsgi.render_response(body={self.member_name: ref}, status=("201", "Created"))
Example #2
0
    def get_versions(self, context):

        req_mime_type = v3_mime_type_best_match(context)
        if req_mime_type == MimeTypes.JSON_HOME:
            v3_json_home = request_v3_json_home("/v3")
            return wsgi.render_response(body=v3_json_home, headers=(("Content-Type", MimeTypes.JSON_HOME),))

        versions = self._get_versions_list(context)
        return wsgi.render_response(
            status=(300, "Multiple Choices"), body={"versions": {"values": list(versions.values())}}
        )
Example #3
0
 def create_domain_config(self, request, domain_id, config):
     self.resource_api.get_domain(domain_id)
     original_config = (
         self.domain_config_api.get_config_with_sensitive_info(domain_id))
     ref = self.domain_config_api.create_config(domain_id, config)
     if original_config:
         # Return status code 200, since config already existed
         return wsgi.render_response(body={self.member_name: ref})
     else:
         return wsgi.render_response(body={self.member_name: ref},
                                     status=('201', 'Created'))
Example #4
0
    def get_version_v3(self, context):
        versions = self._get_versions_list(context)
        if "v3" in _VERSIONS:
            req_mime_type = v3_mime_type_best_match(context)

            if req_mime_type == MimeTypes.JSON_HOME:
                return wsgi.render_response(
                    body=self._get_json_home_v3(), headers=(("Content-Type", MimeTypes.JSON_HOME),)
                )

            return wsgi.render_response(body={"version": versions["v3"]})
        else:
            raise exception.VersionNotFound(version="v3")
Example #5
0
    def get_version_v3(self, request):
        versions = self._get_versions_list(request.context_dict)
        if 'v3' in _VERSIONS:
            req_mime_type = v3_mime_type_best_match(request)

            if req_mime_type == MimeTypes.JSON_HOME:
                return wsgi.render_response(
                    body=self._get_json_home_v3(),
                    headers=(('Content-Type', MimeTypes.JSON_HOME),))

            return wsgi.render_response(body={
                'version': versions['v3']
            })
        else:
            raise exception.VersionNotFound(version='v3')
    def get_versions(self, context):

        req_mime_type = v3_mime_type_best_match(context)
        if req_mime_type == MimeTypes.JSON_HOME:
            v3_json_home = request_v3_json_home('/v3')
            return wsgi.render_response(
                body=v3_json_home,
                headers=(('Content-Type', MimeTypes.JSON_HOME),))

        versions = self._get_versions_list(context)
        return wsgi.render_response(status=(300, 'Multiple Choices'), body={
            'versions': {
                'values': versions.values()
            }
        })
Example #7
0
 def create_domain_config(self, request, domain_id, config):
     PROVIDERS.resource_api.get_domain(domain_id)
     original_config = (
         PROVIDERS.domain_config_api.get_config_with_sensitive_info(
             domain_id
         )
     )
     ref = PROVIDERS.domain_config_api.create_config(domain_id, config)
     if original_config:
         # Return status code 200, since config already existed
         return wsgi.render_response(body={self.member_name: ref})
     else:
         return wsgi.render_response(
             body={self.member_name: ref},
             status=(http_client.CREATED,
                     http_client.responses[http_client.CREATED]))
Example #8
0
 def create_identity_provider(self, context, idp_id, identity_provider):
     identity_provider = self._normalize_dict(identity_provider)
     identity_provider.setdefault('enabled', False)
     IdentityProvider.check_immutable_params(identity_provider)
     idp_ref = self.federation_api.create_idp(idp_id, identity_provider)
     response = IdentityProvider.wrap_member(context, idp_ref)
     return wsgi.render_response(body=response, status=('201', 'Created'))
Example #9
0
 def get_versions(self, context):
     versions = self._get_versions_list(context)
     return wsgi.render_response(status=(300, 'Multiple Choices'), body={
         'versions': {
             'values': versions.values()
         }
     })
Example #10
0
    def create_saml_assertion(self, context, auth):
        """Exchange a scoped token for a SAML assertion.

        :param auth: Dictionary that contains a token id and region id
        :returns: SAML Assertion based on properties from the token
        """

        issuer = CONF.saml.idp_entity_id
        region_id = auth['scope']['region']['id']
        region = self.catalog_api.get_region(region_id)
        recipient = region['url']

        token_id = auth['identity']['token']['id']
        token_data = self.token_provider_api.validate_token(token_id)
        token_ref = token_model.KeystoneToken(token_id, token_data)
        subject = token_ref.user_name
        roles = token_ref.role_names

        if token_ref.project_scoped:
            project = token_ref.project_name
        else:
            raise ValueError(_('Use a project scoped token when attempting to'
                               'create a SAML assertion'))

        generator = keystone_idp.SAMLGenerator()
        response = generator.samlize_token(issuer, recipient, subject, roles,
                                           project)

        return wsgi.render_response(body=response.to_string(),
                                    status=('200', 'OK'),
                                    headers=[('Content-Type', 'text/xml')])
Example #11
0
    def create_saml_assertion(self, context, auth):
        """Exchange a scoped token for a SAML assertion.

        :param auth: Dictionary that contains a token id and region id
        :returns: SAML Assertion based on properties from the token
        """

        issuer = CONF.saml.idp_entity_id
        region_id = auth["scope"]["region"]["id"]
        region = self.catalog_api.get_region(region_id)
        recipient = region["url"]

        token_id = auth["identity"]["token"]["id"]
        token_data = self.token_provider_api.validate_token(token_id)
        token_ref = token_model.KeystoneToken(token_id, token_data)
        subject = token_ref.user_name
        roles = token_ref.role_names

        if not token_ref.project_scoped:
            action = _("Use a project scoped token when attempting to create " "a SAML assertion")
            raise exception.ForbiddenAction(action=action)

        project = token_ref.project_name
        generator = keystone_idp.SAMLGenerator()
        response = generator.samlize_token(issuer, recipient, subject, roles, project)

        return wsgi.render_response(
            body=response.to_string(), status=("200", "OK"), headers=[("Content-Type", "text/xml")]
        )
Example #12
0
 def create_service_provider(self, context, sp_id, service_provider):
     service_provider = self._normalize_dict(service_provider)
     service_provider.setdefault('enabled', False)
     ServiceProvider.check_immutable_params(service_provider)
     sp_ref = self.federation_api.create_sp(sp_id, service_provider)
     response = ServiceProvider.wrap_member(context, sp_ref)
     return wsgi.render_response(body=response, status=('201', 'Created'))
Example #13
0
    def process_request(self, request):
        if request.environ.get('REMOTE_USER', None) is not None:
            # authenticated upstream
            return self.application

        if not self.is_applicable(request):
            return self.application

        params = request.environ.get(PARAMS_ENV)
        casCredentials = params["auth"]["casCredentials"]
         
        ticket = casCredentials.get("ticket", None)
        service = casCredentials.get("service", None)

        if not ticket:
            # this is asking for the server_url
            return wsgi.render_response({"cas_login_url":
                                         self._get_login_url(service)}) 

        user_ref = self._validate_cas_ticket(ticket, service)
        if not user_ref:
            # Wrong authentication? 
            return self.application

        user_name = user_ref["name"]
        try:
            self.identity_api.get_user_by_name(
                self.identity_api,
                user_name,
                self.domain)
        except exception.UserNotFound:
            if CONF.cas.autocreate_users:
                self._do_create_user(user_ref)

        request.environ['REMOTE_USER'] = user_name
Example #14
0
 def test_render_response_no_body(self):
     resp = wsgi.render_response()
     self.assertEqual(resp.status, "204 No Content")
     self.assertEqual(resp.status_int, 204)
     self.assertEqual(resp.body, b"")
     self.assertEqual(resp.headers.get("Content-Length"), "0")
     self.assertIsNone(resp.headers.get("Content-Type"))
Example #15
0
 def create_implied_role(self, request, prior_role_id, implied_role_id):
     self.role_api.create_implied_role(prior_role_id, implied_role_id)
     return wsgi.render_response(
         self.get_implied_role(request,
                               prior_role_id,
                               implied_role_id),
         status=(201, 'Created'))
Example #16
0
 def create_mapping(self, request, mapping_id, mapping):
     ref = self._normalize_dict(mapping)
     utils.validate_mapping_structure(ref)
     mapping_ref = self.federation_api.create_mapping(mapping_id, ref)
     response = MappingController.wrap_member(request.context_dict,
                                              mapping_ref)
     return wsgi.render_response(body=response, status=('201', 'Created'))
Example #17
0
 def test_render_response_no_body(self):
     resp = wsgi.render_response()
     self.assertEqual(resp.status, '204 No Content')
     self.assertEqual(resp.status_int, 204)
     self.assertEqual(resp.body, '')
     self.assertEqual(resp.headers.get('Content-Length'), '0')
     self.assertEqual(resp.headers.get('Content-Type'), None)
Example #18
0
 def create_protocol(self, context, idp_id, protocol_id, protocol):
     ref = self._normalize_dict(protocol)
     keys = self._mutable_parameters.copy()
     FederationProtocol.check_immutable_params(ref, keys=keys)
     ref = self.federation_api.create_protocol(idp_id, protocol_id, ref)
     response = FederationProtocol.wrap_member(context, ref)
     return wsgi.render_response(body=response, status=('201', 'Created'))
Example #19
0
 def test_render_response_no_body(self):
     resp = wsgi.render_response()
     self.assertEqual("204 No Content", resp.status)
     self.assertEqual(http_client.NO_CONTENT, resp.status_int)
     self.assertEqual(b"", resp.body)
     self.assertEqual("0", resp.headers.get("Content-Length"))
     self.assertIsNone(resp.headers.get("Content-Type"))
Example #20
0
    def get_versions(self, context):
        identity_url = self._get_identity_url(context)
        if not identity_url.endswith('/'):
            identity_url = identity_url + '/'

        return wsgi.render_response(status=(300, 'Multiple Choices'), body={
            "versions": {
                "values": [{
                    "id": "v2.0",
                    "status": "beta",
                    "updated": "2011-11-19T00:00:00Z",
                    "links": [{
                            "rel": "self",
                            "href": identity_url,
                        }, {
                            "rel": "describedby",
                            "type": "text/html",
                            "href": "http://docs.openstack.org/api/openstack-"
                                     "identity-service/2.0/content/"
                        }, {
                            "rel": "describedby",
                            "type": "application/pdf",
                            "href": "http://docs.openstack.org/api/openstack-"
                                     "identity-service/2.0/identity-dev-guide-"
                                     "2.0.pdf"
                        }],
                    "media-types": [{
                            "base": "application/json",
                            "type": "application/vnd.openstack.identity-v2.0"
                                     "+json"
                        }]
                }]
            }
        })
 def test_render_response_no_body(self):
     resp = wsgi.render_response()
     self.assertEqual('204 No Content', resp.status)
     self.assertEqual(http_client.NO_CONTENT, resp.status_int)
     self.assertEqual(b'', resp.body)
     self.assertEqual('0', resp.headers.get('Content-Length'))
     self.assertIsNone(resp.headers.get('Content-Type'))
Example #22
0
 def test_render_response_non_str_headers_converted(self):
     resp = wsgi.render_response(headers=[("Byte-Header", "Byte-Value"), (u"Unicode-Header", u"Unicode-Value")])
     # assert that all headers are identified.
     self.assertThat(resp.headers, matchers.HasLength(4))
     self.assertEqual("Unicode-Value", resp.headers.get("Unicode-Header"))
     # assert that unicode value is converted, the expected type is str
     # on both python2 and python3.
     self.assertEqual(str, type(resp.headers.get("Unicode-Header")))
Example #23
0
 def get_version_v3(self, context):
     versions = self._get_versions_list(context)
     if 'v3' in _VERSIONS:
         return wsgi.render_response(body={
             'version': versions['v3']
         })
     else:
         raise exception.VersionNotFound(version='v3')
Example #24
0
 def create_protocol(self, request, idp_id, protocol_id, protocol):
     validation.lazy_validate(schema.protocol_create, protocol)
     ref = self._normalize_dict(protocol)
     ref = self.federation_api.create_protocol(idp_id, protocol_id, ref)
     response = FederationProtocol.wrap_member(request.context_dict, ref)
     return wsgi.render_response(
         body=response, status=(http_client.CREATED,
                                http_client.responses[http_client.CREATED]))
Example #25
0
    def render_token_data_response(self, token_id, token_data):
        """Render token data HTTP response.

        Note: We neither want nor need to send back the token id.
        """
        status = (http_client.OK,
                  http_client.responses[http_client.OK])
        return wsgi.render_response(body=token_data, status=status)
Example #26
0
 def create_service_provider(self, context, sp_id, service_provider):
     service_provider = self._normalize_dict(service_provider)
     service_provider.setdefault("enabled", False)
     service_provider.setdefault("relay_state_prefix", CONF.saml.relay_state_prefix)
     ServiceProvider.check_immutable_params(service_provider)
     sp_ref = self.federation_api.create_sp(sp_id, service_provider)
     response = ServiceProvider.wrap_member(context, sp_ref)
     return wsgi.render_response(body=response, status=("201", "Created"))
Example #27
0
    def set_user_password(self, context, user_id, user):
        token_id = context.get("token_id")

        user_ref = self.token_manager_api.get_token(context=context,
            token_id=token_id)
        user_id_from_token = user_ref["user"]["id"]

        if user_id_from_token != user_id:
            return render_response(status=(403,"Not Authorized"),
                body={"error": {"message": "You are not authorized",
                "code": 403, "title": "Not Authorized"}})

        update_dict = sanitize_dict(user, ["id", "password"])

        self.identity_manager_api.update_user(context, user_id, update_dict)

        return render_response(status=(200,"OK"), body={"user":update_dict})
Example #28
0
    def create_region(self, context, region):
        ref = self._normalize_dict(region)

        if not ref.get("id"):
            ref = self._assign_unique_id(ref)

        ref = self.catalog_api.create_region(ref)
        return wsgi.render_response(RegionV3.wrap_member(context, ref), status=(201, "Created"))
Example #29
0
 def create_service_provider(self, request, sp_id, service_provider):
     service_provider = self._normalize_dict(service_provider)
     service_provider.setdefault('enabled', False)
     service_provider.setdefault('relay_state_prefix',
                                 CONF.saml.relay_state_prefix)
     sp_ref = self.federation_api.create_sp(sp_id, service_provider)
     response = ServiceProvider.wrap_member(request.context_dict, sp_ref)
     return wsgi.render_response(body=response, status=('201', 'Created'))
Example #30
0
 def get_version_v2(self, request):
     versions = self._get_versions_list(request.context_dict)
     if 'v2.0' in _VERSIONS:
         return wsgi.render_response(body={
             'version': versions['v2.0']
         })
     else:
         raise exception.VersionNotFound(version='v2.0')
Example #31
0
 def test_render_response_no_body(self):
     resp = wsgi.render_response()
     self.assertEqual('204 No Content', resp.status)
     self.assertEqual(http_client.NO_CONTENT, resp.status_int)
     self.assertEqual(b'', resp.body)
     self.assertIsNone(resp.headers.get('Content-Type'))
Example #32
0
 def test_render_response_head_with_body(self):
     resp = wsgi.render_response({'id': uuid.uuid4().hex}, method='HEAD')
     self.assertEqual(http_client.OK, resp.status_int)
     self.assertEqual(b'', resp.body)
     self.assertNotEqual('0', resp.headers.get('Content-Length'))
     self.assertEqual('application/json', resp.headers.get('Content-Type'))
Example #33
0
    def create_authorization_code(self, context, user_auth):
        request_validator = validator.OAuth2Validator()
        server = core.Server(request_validator)
        # Validate request
        headers = context['headers']
        body = user_auth
        uri = self.base_url(context, context['path'])
        http_method = 'POST'

        # Fetch authorized scopes from the request
        scopes = body.get('scopes')
        if not scopes:
            raise exception.ValidationError(attribute='scopes',
                                            target='request')

        # Fetch the credentials saved in the pre authorization phase
        client_id = body.get('client_id')
        if not client_id:
            raise exception.ValidationError(attribute='client_id',
                                            target='request')

        user_id = body.get('user_id')
        if not user_id:
            # Try to extract the user_id from the token
            user_id = self._extract_user_id_from_token(context['token_id'])

        credentials = self.oauth2_api.get_consumer_credentials(
            client_id, user_id)

        try:

            headers, body, status = server.create_authorization_response(
                uri, http_method, body, headers, scopes, credentials)
            # headers = {'Location': 'https://foo.com/welcome_back?code=somera
            # ndomstring&state=xyz  '}, this might change to include suggested
            # headers related to cache best practices etc.
            # body = '', this might be set in future custom grant types
            # status = 302, suggested HTTP status code

            response = wsgi.render_response(body,
                                            status=(302, 'Found'),
                                            headers=headers.items())

            LOG.info(
                'OAUTH2: Created Authorization Code to consumer %(consumer)s \
                for user %(user)s with scope %(scope)s. Redirecting to %(uri)s',
                {
                    'consumer': client_id,
                    'user': user_id,
                    'scope': scopes,
                    'uri': headers['Location']
                })

            return response
        except FatalClientError as e:
            # NOTE(garcianavalon) form the OAuthLib documentation and comments:
            # Errors during authorization where user should not be redirected back.
            # If the request fails due to a missing, invalid, or mismatching
            # redirection URI, or if the client identifier is missing or invalid,
            # the authorization server SHOULD inform the resource owner of the
            # error and MUST NOT automatically redirect the user-agent to the
            # invalid redirection URI.
            # Instead the user should be informed of the error by the provider itself.
            # Fatal errors occur when the client_id or redirect_uri is invalid or
            # missing. These must be caught by the provider and handled, how this
            # is done is outside of the scope of OAuthLib but showing an error
            # page describing the issue is a good ideaself.
            msg = e.json
            LOG.warning('OAUTH2: FatalClientError %s' % msg)
            raise exception.ValidationError(message=msg)
 def create_mapping(self, context, mapping_id, mapping):
     ref = self._normalize_dict(mapping)
     utils.validate_mapping_structure(ref)
     mapping_ref = self.federation_api.create_mapping(mapping_id, ref)
     response = MappingController.wrap_member(context, mapping_ref)
     return wsgi.render_response(body=response, status=('201', 'Created'))
Example #35
0
    def create_access_token(self, context):
        headers = context['headers']
        oauth_headers = oauth1.get_oauth_headers(headers)
        consumer_id = oauth_headers.get('oauth_consumer_key')
        request_token_id = oauth_headers.get('oauth_token')
        oauth_verifier = oauth_headers.get('oauth_verifier')

        if not consumer_id:
            raise exception.ValidationError(attribute='oauth_consumer_key',
                                            target='request')
        if not request_token_id:
            raise exception.ValidationError(attribute='oauth_token',
                                            target='request')
        if not oauth_verifier:
            raise exception.ValidationError(attribute='oauth_verifier',
                                            target='request')

        consumer = self.oauth_api._get_consumer(consumer_id)
        req_token = self.oauth_api.get_request_token(request_token_id)

        expires_at = req_token['expires_at']
        if expires_at:
            now = timeutils.utcnow()
            expires = timeutils.normalize_time(
                timeutils.parse_isotime(expires_at))
            if now > expires:
                raise exception.Unauthorized(_('Request token is expired'))

        consumer_obj = oauth1.Consumer(key=consumer['id'],
                                       secret=consumer['secret'])
        req_token_obj = oauth1.Token(key=req_token['id'],
                                     secret=req_token['request_secret'])
        req_token_obj.set_verifier(oauth_verifier)

        url = oauth1.rebuild_url(context['path'])
        oauth_request = oauth1.Request.from_request(
            http_method='POST',
            http_url=url,
            headers=context['headers'],
            query_string=context['query_string'])
        oauth_server = oauth1.Server()
        oauth_server.add_signature_method(oauth1.SignatureMethod_HMAC_SHA1())
        params = oauth_server.verify_request(oauth_request,
                                             consumer_obj,
                                             token=req_token_obj)

        if len(params) != 0:
            msg = _('There should not be any non-oauth parameters')
            raise exception.Unauthorized(message=msg)

        if req_token['consumer_id'] != consumer_id:
            msg = _('provided consumer key does not match stored consumer key')
            raise exception.Unauthorized(message=msg)

        if req_token['verifier'] != oauth_verifier:
            msg = _('provided verifier does not match stored verifier')
            raise exception.Unauthorized(message=msg)

        if req_token['id'] != request_token_id:
            msg = _('provided request key does not match stored request key')
            raise exception.Unauthorized(message=msg)

        if not req_token.get('authorizing_user_id'):
            msg = _('Request Token does not have an authorizing user id')
            raise exception.Unauthorized(message=msg)

        access_token_duration = CONF.oauth1.access_token_duration
        token_ref = self.oauth_api.create_access_token(request_token_id,
                                                       access_token_duration)

        result = ('oauth_token=%(key)s&oauth_token_secret=%(secret)s' % {
            'key': token_ref['id'],
            'secret': token_ref['access_secret']
        })

        if CONF.oauth1.access_token_duration:
            expiry_bit = '&oauth_expires_at=%s' % (token_ref['expires_at'])
            result += expiry_bit

        headers = [('Content-Type', 'application/x-www-urlformencoded')]
        response = wsgi.render_response(result,
                                        status=(201, 'Created'),
                                        headers=headers)

        return response
Example #36
0
 def create_implied_role(self, request, prior_role_id, implied_role_id):
     PROVIDERS.role_api.create_implied_role(prior_role_id, implied_role_id)
     return wsgi.render_response(self.get_implied_role(
         request, prior_role_id, implied_role_id),
                                 status=(201, 'Created'))
Example #37
0
 def update_domain_config(
         self, request, domain_id, config, group, option):
     PROVIDERS.resource_api.get_domain(domain_id)
     ref = PROVIDERS.domain_config_api.update_config(
         domain_id, config, group, option)
     return wsgi.render_response(body={self.member_name: ref})
Example #38
0
    def create_access_token(self, context):
        headers = context['headers']
        oauth_headers = oauth1.get_oauth_headers(headers)
        consumer_id = oauth_headers.get('oauth_consumer_key')
        request_token_id = oauth_headers.get('oauth_token')
        oauth_verifier = oauth_headers.get('oauth_verifier')

        if not consumer_id:
            raise exception.ValidationError(attribute='oauth_consumer_key',
                                            target='request')
        if not request_token_id:
            raise exception.ValidationError(attribute='oauth_token',
                                            target='request')
        if not oauth_verifier:
            raise exception.ValidationError(attribute='oauth_verifier',
                                            target='request')

        req_token = self.oauth_api.get_request_token(request_token_id)

        expires_at = req_token['expires_at']
        if expires_at:
            now = timeutils.utcnow()
            expires = timeutils.normalize_time(
                timeutils.parse_isotime(expires_at))
            if now > expires:
                raise exception.Unauthorized(_('Request token is expired'))

        url = self.base_url(context, context['path'])

        access_verifier = oauth1.AccessTokenEndpoint(
            request_validator=validator.OAuthValidator(),
            token_generator=oauth1.token_generator)
        h, b, s = access_verifier.create_access_token_response(
            url,
            http_method='POST',
            body=context['query_string'],
            headers=headers)
        params = oauth1.extract_non_oauth_params(b)
        if len(params) != 0:
            msg = _('There should not be any non-oauth parameters')
            raise exception.Unauthorized(message=msg)

        if req_token['consumer_id'] != consumer_id:
            msg = _('provided consumer key does not match stored consumer key')
            raise exception.Unauthorized(message=msg)

        if req_token['verifier'] != oauth_verifier:
            msg = _('provided verifier does not match stored verifier')
            raise exception.Unauthorized(message=msg)

        if req_token['id'] != request_token_id:
            msg = _('provided request key does not match stored request key')
            raise exception.Unauthorized(message=msg)

        if not req_token.get('authorizing_user_id'):
            msg = _('Request Token does not have an authorizing user id')
            raise exception.Unauthorized(message=msg)

        access_token_duration = CONF.oauth1.access_token_duration
        initiator = notifications._get_request_audit_info(context)
        token_ref = self.oauth_api.create_access_token(request_token_id,
                                                       access_token_duration,
                                                       initiator)

        result = ('oauth_token=%(key)s&oauth_token_secret=%(secret)s' % {
            'key': token_ref['id'],
            'secret': token_ref['access_secret']
        })

        if CONF.oauth1.access_token_duration:
            expiry_bit = '&oauth_expires_at=%s' % (token_ref['expires_at'])
            result += expiry_bit

        headers = [('Content-Type', 'application/x-www-urlformencoded')]
        response = wsgi.render_response(result,
                                        status=(201, 'Created'),
                                        headers=headers)

        return response
 def create_protocol(self, context, idp_id, protocol_id, protocol):
     ref = self._normalize_dict(protocol)
     FederationProtocol.check_immutable_params(ref)
     ref = self.federation_api.create_protocol(idp_id, protocol_id, ref)
     response = FederationProtocol.wrap_member(context, ref)
     return wsgi.render_response(body=response, status=('201', 'Created'))
 def create_identity_provider(self, context, idp_id, identity_provider):
     identity_provider = self._normalize_dict(identity_provider)
     identity_provider.setdefault('enabled', False)
     idp_ref = self.federation_api.create_idp(idp_id, identity_provider)
     response = IdentityProvider.wrap_member(context, idp_ref)
     return wsgi.render_response(body=response, status=('201', 'Created'))
Example #41
0
    def create_access_token(self, context, token_request):
        request_validator = validator.OAuth2Validator()
        server = core.Server(request_validator)

        # Validate request
        headers = context['headers']
        # NOTE(garcianavalon) Work around the keystone limitation with content types
        # Keystone only accepts JSON bodies while OAuth2.0 (RFC 6749) requires
        # x-www-form-urlencoded
        # We leave it like this to support future versions where the use of
        # x-www-form-urlencoded is accepted
        if headers['Content-Type'] == 'application/x-www-form-urlencoded':
            body = context['query_string']
        elif headers['Content-Type'] == 'application/json':
            # TODO(garcianavalon) are these checks really necessary or
            # can we delegate them to oauthlib?
            grant_type = token_request.get('grant_type', None)
            if not grant_type:
                msg = _('grant_type missing in request body: {0}').format(
                    token_request)
                raise exception.ValidationError(message=msg)
            if (grant_type == 'authorization_code'
                    and not 'code' in token_request):

                msg = _('code missing in request body: %s') % token_request
                raise exception.ValidationError(message=msg)

            body = urllib.urlencode(token_request)
        else:
            msg = _(
                'Content-Type: %s is not supported') % headers['Content-Type']
            raise exception.ValidationError(message=msg)

        # check headers for authentication
        authmethod, auth = headers['Authorization'].split(' ', 1)
        if authmethod.lower() != 'basic':
            msg = _('Authorization error: %s. Only HTTP Basic is supported'
                    ) % headers['Authorization']
            raise exception.ValidationError(message=msg)

        uri = self.base_url(context, context['path'])
        http_method = 'POST'

        # Extra credentials you wish to include
        credentials = None  # TODO(garcianavalon)

        headers, body, status = server.create_token_response(
            uri, http_method, body, headers, credentials)

        # headers will contain some suggested headers to add to your response
        # {
        #     'Content-Type': 'application/json',
        #     'Cache-Control': 'no-store',
        #     'Pragma': 'no-cache',
        # }
        # body will contain the token in json format and expiration from now
        # in seconds.
        # {
        #     'access_token': 'sldafh309sdf',
        #     'refresh_token': 'alsounguessablerandomstring',
        #     'expires_in': 3600,
        #     'scope': 'https://example.com/userProfile https://example.com/pictures',
        #     'token_type': 'Bearer'
        # }
        # body will contain an error code and possibly an error description if
        # the request failed, also in json format.
        # {
        #     'error': 'invalid_grant_type',
        #     'description': 'athorizatoin_coed is not a valid grant type'
        # }
        # status will be a suggested status code, 200 on ok, 400 on bad request
        # and 401 if client is trying to use an invalid authorization code,
        # fail to authenticate etc.

        # NOTE(garcianavalon) oauthlib returns the body as a JSON string already,
        # and the Keystone base controlers expect a dictionary
        body = json.loads(body)
        # TODO(garcianavalon) body contains scope instead of scopes and is only a
        # space separated string instead of a list. We can wait for a change in
        # Oauthlib or implement our own TokenProvider
        if status == 200:
            response = wsgi.render_response(body,
                                            status=(status, 'OK'),
                                            headers=headers.items())
            LOG.info('OAUTH2: Created Access Token %s' % body['access_token'])
            return response
        # Build the error message and raise the corresponding error
        msg = _(body['error'])
        if hasattr(body, 'description'):
            msg = msg + ': ' + _(body['description'])
        LOG.warning('OAUTH2: Error creating Access Token %s' % msg)
        if status == 400:
            raise exception.ValidationError(message=msg)
        elif status == 401:
            # TODO(garcianavalon) custom exception class
            raise exception.Unauthorized(message=msg)
Example #42
0
 def test_render_response_custom_status(self):
     resp = wsgi.render_response(
         status=(http_client.NOT_IMPLEMENTED,
                 http_client.responses[http_client.NOT_IMPLEMENTED]))
     self.assertEqual('501 Not Implemented', resp.status)
     self.assertEqual(http_client.NOT_IMPLEMENTED, resp.status_int)
Example #43
0
 def update_domain_config(self, context, domain_id, config, group, option):
     self.resource_api.get_domain(domain_id)
     ref = self.domain_config_api.update_config(domain_id, config, group,
                                                option)
     return wsgi.render_response(body={self.member_name: ref})
Example #44
0
    def create_request_token(self, context):
        headers = context['headers']
        oauth_headers = oauth1.get_oauth_headers(headers)
        consumer_id = oauth_headers.get('oauth_consumer_key')
        requested_role_ids = headers.get('Requested-Role-Ids')
        requested_project_id = headers.get('Requested-Project-Id')
        if not consumer_id:
            raise exception.ValidationError(attribute='oauth_consumer_key',
                                            target='request')
        if not requested_role_ids:
            raise exception.ValidationError(attribute='requested_role_ids',
                                            target='request')
        if not requested_project_id:
            raise exception.ValidationError(attribute='requested_project_id',
                                            target='request')

        req_role_ids = requested_role_ids.split(',')
        consumer_ref = self.oauth_api._get_consumer(consumer_id)
        consumer = oauth1.Consumer(key=consumer_ref['id'],
                                   secret=consumer_ref['secret'])

        url = oauth1.rebuild_url(context['path'])
        oauth_request = oauth1.Request.from_request(
            http_method='POST',
            http_url=url,
            headers=context['headers'],
            query_string=context['query_string'],
            parameters={
                'requested_role_ids': requested_role_ids,
                'requested_project_id': requested_project_id
            })
        oauth_server = oauth1.Server()
        oauth_server.add_signature_method(oauth1.SignatureMethod_HMAC_SHA1())
        params = oauth_server.verify_request(oauth_request,
                                             consumer,
                                             token=None)

        project_params = params['requested_project_id']
        if project_params != requested_project_id:
            msg = _('Non-oauth parameter - project, do not match')
            raise exception.Unauthorized(message=msg)

        roles_params = params['requested_role_ids']
        roles_params_list = roles_params.split(',')
        if roles_params_list != req_role_ids:
            msg = _('Non-oauth parameter - roles, do not match')
            raise exception.Unauthorized(message=msg)

        req_role_list = list()
        all_roles = self.identity_api.list_roles()
        for role in all_roles:
            for req_role in req_role_ids:
                if role['id'] == req_role:
                    req_role_list.append(role)

        if len(req_role_list) == 0:
            msg = _('could not find matching roles for provided role ids')
            raise exception.Unauthorized(message=msg)

        json_roles = jsonutils.dumps(req_role_list)
        request_token_duration = CONF.oauth1.request_token_duration
        token_ref = self.oauth_api.create_request_token(
            consumer_id, json_roles, requested_project_id,
            request_token_duration)

        result = ('oauth_token=%(key)s&oauth_token_secret=%(secret)s' % {
            'key': token_ref['id'],
            'secret': token_ref['request_secret']
        })

        if CONF.oauth1.request_token_duration:
            expiry_bit = '&oauth_expires_at=%s' % token_ref['expires_at']
            result += expiry_bit

        headers = [('Content-Type', 'application/x-www-urlformencoded')]
        response = wsgi.render_response(result,
                                        status=(201, 'Created'),
                                        headers=headers)

        return response
Example #45
0
 def get_version_v3(self, context):
     versions = self._get_versions_list(context)
     if 'v3' in _VERSIONS:
         return wsgi.render_response(body={'version': versions['v3']})
     else:
         raise exception.VersionNotFound(version='v3')
Example #46
0
 def get_version_v2(self, request):
     versions = self._get_versions_list(request.context_dict)
     if 'v2.0' in _VERSIONS:
         return wsgi.render_response(body={'version': versions['v2.0']})
     else:
         raise exception.VersionNotFound(version='v2.0')
Example #47
0
 def test_render_response_custom_status(self):
     resp = wsgi.render_response(status=(501, 'Not Implemented'))
     self.assertEqual(resp.status, '501 Not Implemented')
     self.assertEqual(resp.status_int, 501)
Example #48
0
 def test_render_response_custom_headers(self):
     resp = wsgi.render_response(headers=[('Custom-Header', 'Some-Value')])
     self.assertEqual(resp.headers.get('Custom-Header'), 'Some-Value')
     self.assertEqual(resp.headers.get('Vary'), 'X-Auth-Token')
Example #49
0
    def create_access_token(self, request):
        oauth_headers = oauth1.get_oauth_headers(request.headers)
        consumer_id = oauth_headers.get('oauth_consumer_key')
        request_token_id = oauth_headers.get('oauth_token')
        oauth_verifier = oauth_headers.get('oauth_verifier')

        if not consumer_id:
            raise exception.ValidationError(attribute='oauth_consumer_key',
                                            target='request')
        if not request_token_id:
            raise exception.ValidationError(attribute='oauth_token',
                                            target='request')
        if not oauth_verifier:
            raise exception.ValidationError(attribute='oauth_verifier',
                                            target='request')

        req_token = PROVIDERS.oauth_api.get_request_token(request_token_id)

        expires_at = req_token['expires_at']
        if expires_at:
            now = timeutils.utcnow()
            expires = timeutils.normalize_time(
                timeutils.parse_isotime(expires_at))
            if now > expires:
                raise exception.Unauthorized(_('Request token is expired'))

        url = self._update_url_scheme(request)
        access_verifier = oauth1.AccessTokenEndpoint(
            request_validator=validator.OAuthValidator(),
            token_generator=oauth1.token_generator)
        try:
            h, b, s = access_verifier.create_access_token_response(
                url,
                http_method='POST',
                body=request.params,
                headers=request.headers)
        except NotImplementedError:
            # Client key or request token validation failed, since keystone
            # does not yet support dummy client or dummy request token,
            # so we will raise Unauthorized exception instead.
            try:
                PROVIDERS.oauth_api.get_consumer(consumer_id)
            except exception.NotFound:
                msg = _('Provided consumer does not exist.')
                LOG.warning(msg)
                raise exception.Unauthorized(message=msg)
            if req_token['consumer_id'] != consumer_id:
                msg = _('Provided consumer key does not match stored '
                        'consumer key.')
                LOG.warning(msg)
                raise exception.Unauthorized(message=msg)
        # The response body is empty since either one of the following reasons
        if not b:
            if req_token['verifier'] != oauth_verifier:
                msg = _('Provided verifier does not match stored verifier')
            else:
                msg = _('Invalid signature.')
            LOG.warning(msg)
            raise exception.Unauthorized(message=msg)
        # show the details of the failure.
        oauth1.validate_oauth_params(b)
        if not req_token.get('authorizing_user_id'):
            msg = _('Request Token does not have an authorizing user id.')
            LOG.warning(msg)
            raise exception.Unauthorized(message=msg)

        access_token_duration = CONF.oauth1.access_token_duration
        token_ref = PROVIDERS.oauth_api.create_access_token(
            request_token_id,
            access_token_duration,
            initiator=request.audit_initiator)

        result = ('oauth_token=%(key)s&oauth_token_secret=%(secret)s' % {
            'key': token_ref['id'],
            'secret': token_ref['access_secret']
        })

        if CONF.oauth1.access_token_duration > 0:
            expiry_bit = '&oauth_expires_at=%s' % (token_ref['expires_at'])
            result += expiry_bit

        headers = [('Content-Type', 'application/x-www-form-urlencoded')]
        response = wsgi.render_response(
            result,
            status=(http_client.CREATED,
                    http_client.responses[http_client.CREATED]),
            headers=headers)

        return response
Example #50
0
 def test_render_response_head_with_body(self):
     resp = wsgi.render_response({'id': uuid.uuid4().hex}, method='HEAD')
     self.assertEqual(resp.status_int, 200)
     self.assertEqual(resp.body, b'')
     self.assertNotEqual(resp.headers.get('Content-Length'), '0')
     self.assertEqual(resp.headers.get('Content-Type'), 'application/json')
Example #51
0
 def create_implied_role(self, context, prior_role_id, implied_role_id):
     self.role_api.create_implied_role(prior_role_id, implied_role_id)
     return wsgi.render_response(self.get_implied_role(
         context, prior_role_id, implied_role_id),
                                 status=(201, 'Created'))