예제 #1
0
    def testInvalidCORSPreFlightRequestNoACRM(self):
        """
        The request has an Origin header but no
        Access-Control-Request-Method so check it returns a regular OPTIONS
        response.
        """
        # The origin to use in the tests
        dummyOrigin = 'http://foo.com'

        request = http.Request(DummyChannel(), False)
        request.method = 'OPTIONS'
        request.requestHeaders.setRawHeaders('Origin', [dummyOrigin])
        request._fluidDB_reqid = 'xxx'
        request.args = dict()
        request.postpath = []
        request.content = NoContent()
        resource = NamespacesResource(FakeFacadeClient(), FakeSession())
        resource._handleOptions(request, dummyOrigin)
        # 200 OK
        self.assertEqual(request.code, http.OK)
        # check we have the required headers
        headers = request.responseHeaders
        self.assertTrue(headers.hasHeader('Allow'))
        # Check the allowed methods (including and in addition to those
        # allowed for CORS)
        allowedMethods = headers.getRawHeaders('Allow')[0].split(', ')
        self.assertEqual(len(resource.allowedMethods), len(allowedMethods))
        for item in resource.allowedMethods:
            self.assertTrue(item in allowedMethods)
        # There are *NO* CORS related headers
        self.assertFalse(headers.hasHeader('Access-Control-Allow-Origin'))
        self.assertFalse(headers.hasHeader('Access-Control-Max-Age'))
        self.assertFalse(headers.hasHeader('Access-Control-Allow-Credentials'))
        self.assertFalse(headers.hasHeader('Access-Control-Allow-Methods'))
예제 #2
0
 def testRegularOptionsCall(self):
     """
     Validates that a regular non-CORS OPTIONS call returns an appropriate
     response
     """
     request = http.Request(DummyChannel(), False)
     request.method = 'OPTIONS'
     request._fluidDB_reqid = 'xxx'
     request.args = dict()
     request.postpath = []
     request.content = NoContent()
     resource = NamespacesResource(FakeFacadeClient(), FakeSession())
     resource._handleOptions(request, None)
     # 200 OK
     self.assertEqual(request.code, http.OK)
     # check we have the required headers
     headers = request.responseHeaders
     self.assertTrue(headers.hasHeader('Allow'))
     # Check the allowed methods (including and in addition to those
     # allowed for CORS)
     allowedMethods = headers.getRawHeaders('Allow')[0].split(', ')
     self.assertEqual(len(resource.allowedMethods), len(allowedMethods))
     for item in resource.allowedMethods:
         self.assertTrue(item in allowedMethods)
     # There are *NO* CORS related headers
     self.assertFalse(headers.hasHeader('Access-Control-Allow-Origin'))
     self.assertFalse(headers.hasHeader('Access-Control-Max-Age'))
     self.assertFalse(headers.hasHeader('Access-Control-Allow-Credentials'))
     self.assertFalse(headers.hasHeader('Access-Control-Allow-Methods'))
예제 #3
0
 def testCorsHeadersDoNotAppearForRegularRequests(self):
     """
     Make sure CORS related headers do NOT appear in regular non-CORS
     requests
     """
     payload = {
         'description': 'A namespace for tags I add to people',
         'name': 'people'
     }
     content = json.dumps(payload)
     contentLength = len(content)
     request = http.Request(DummyChannel(), False)
     request.method = 'POST'
     request.requestHeaders.setRawHeaders('Content-Length',
                                          [str(contentLength)])
     request.requestHeaders.setRawHeaders('Content-Type',
                                          ['application/json'])
     request.requestHeaders.setRawHeaders('Host', ['fluiddb.fluidinfo.com'])
     request._fluidDB_reqid = 'xxx'
     request.args = dict()
     request.postpath = []
     request.content = StringIO(content)
     resource = NamespacesResource(FakeFacadeClient(), FakeSession())
     resource.render(request)
     # 201 Created
     self.assertEqual(request.code, http.CREATED)
     # check we don't have the CORS related headers
     headers = request.responseHeaders
     self.assertFalse(headers.hasHeader('Access-Control-Allow-Origin'))
     self.assertFalse(headers.hasHeader('Access-Control-Allow-Credentials'))
     self.assertFalse(headers.hasHeader('Access-Control-Expose-Headers'))
예제 #4
0
 def testRegularOptionsCall(self):
     """
     Validates that a regular non-CORS OPTIONS call returns an appropriate
     response
     """
     request = http.Request(DummyChannel(), False)
     request.method = 'OPTIONS'
     request._fluidDB_reqid = 'xxx'
     request.args = dict()
     request.postpath = []
     request.content = NoContent()
     resource = NamespacesResource(FakeFacadeClient(), FakeSession())
     resource._handleOptions(request, None)
     # 200 OK
     self.assertEqual(request.code, http.OK)
     # check we have the required headers
     headers = request.responseHeaders
     self.assertTrue(headers.hasHeader('Allow'))
     # Check the allowed methods (including and in addition to those
     # allowed for CORS)
     allowedMethods = headers.getRawHeaders('Allow')[0].split(', ')
     self.assertEqual(
         len(resource.allowedMethods),
         len(allowedMethods))
     for item in resource.allowedMethods:
         self.assertTrue(item in allowedMethods)
     # There are *NO* CORS related headers
     self.assertFalse(headers.hasHeader('Access-Control-Allow-Origin'))
     self.assertFalse(headers.hasHeader('Access-Control-Max-Age'))
     self.assertFalse(
         headers.hasHeader('Access-Control-Allow-Credentials'))
     self.assertFalse(headers.hasHeader('Access-Control-Allow-Methods'))
예제 #5
0
 def testRegularCORSHeaders(self):
     """
     Validates that the headers are handled correctly for a CORS request
     that doesn't use the OPTIONS verb
     """
     # The origin to use in the tests
     dummyOrigin = 'http://foo.com'
     expectedHeaders = [
         'X-FluidDB-Error-Class', 'X-FluidDB-Path', 'X-FluidDB-Message',
         'X-FluidDB-ObjectId', 'X-FluidDB-Name', 'X-FluidDB-Category',
         'X-FluidDB-Action', 'X-FluidDB-Rangetype', 'X-FluidDB-Fieldname',
         'X-FluidDB-Argument', 'X-FluidDB-Access-Token',
         'X-FluidDB-Username', 'X-FluidDB-New-User'
     ]
     payload = {
         'description': 'A namespace for tags that I add to people',
         'name': 'people'
     }
     content = json.dumps(payload)
     contentLength = len(content)
     request = http.Request(DummyChannel(), False)
     request.method = 'POST'
     request.requestHeaders.setRawHeaders('Content-Length',
                                          [str(contentLength)])
     request.requestHeaders.setRawHeaders('Content-Type',
                                          ['application/json'])
     request.requestHeaders.setRawHeaders('Host', ['fluiddb.fluidinfo.com'])
     request.requestHeaders.setRawHeaders('Origin', [dummyOrigin])
     request._fluidDB_reqid = 'xxx'
     request.args = dict()
     request.postpath = []
     request.content = StringIO(content)
     resource = NamespacesResource(FakeFacadeClient(), FakeSession())
     resource.render(request)
     # 201 Created
     self.assertEqual(request.code, http.CREATED)
     # check we have the required headers
     headers = request.responseHeaders
     self.assertTrue(headers.hasHeader('Access-Control-Allow-Origin'))
     self.assertTrue(headers.hasHeader('Access-Control-Allow-Credentials'))
     self.assertTrue(headers.hasHeader('Access-Control-Expose-Headers'))
     # check the values of the required headers
     self.assertEqual(
         dummyOrigin,
         headers.getRawHeaders('Access-Control-Allow-Origin')[0])
     self.assertEqual(
         'true',
         headers.getRawHeaders('Access-Control-Allow-Credentials')[0])
     accessControlExposeHeaders = headers.getRawHeaders(
         'Access-Control-Expose-Headers')[0]
     # Make sure we haven't accidentally turned the header value into a
     # Python tuple by including a comma in its definition.
     self.assertTrue(isinstance(accessControlExposeHeaders, str))
     # Make sure we haven't accidentally left a comma space in the last
     # element of the Python header definition.
     self.assertFalse(accessControlExposeHeaders.endswith(', '))
     actualHeaders = accessControlExposeHeaders.split(', ')
     for header in expectedHeaders:
         self.assertTrue(header.startswith('X-FluidDB-'))
         self.assertTrue(header in actualHeaders)
예제 #6
0
 def testHeaderNotPresentWhenNoError(self):
     """
     Check the WWW-Authenticate header is not present
     when we do not hit an error.
     """
     payload = {'description': 'A new namespace', 'name': 'people'}
     content = json.dumps(payload)
     contentLength = len(content)
     request = http.Request(DummyChannel(), False)
     request.method = 'POST'
     request.requestHeaders.setRawHeaders('Content-Length',
                                          [str(contentLength)])
     request.requestHeaders.setRawHeaders('Content-Type',
                                          ['application/json'])
     request.requestHeaders.setRawHeaders('Host',
                                          ['fluiddb.fluidinfo.com'])
     request._fluidDB_reqid = 'xxx'
     request.args = dict()
     request.postpath = []
     request.content = StringIO(content)
     resource = NamespacesResource(FakeFacadeClient(), FakeSession())
     resource.render(request)
     # Check the WWW-Authenticate header is absent.
     headers = request.responseHeaders
     self.assertFalse(headers.hasHeader('WWW-Authenticate'))
예제 #7
0
 def testCorsHeadersDoNotAppearForRegularRequests(self):
     """
     Make sure CORS related headers do NOT appear in regular non-CORS
     requests
     """
     payload = {'description': 'A namespace for tags I add to people',
                'name': 'people'}
     content = json.dumps(payload)
     contentLength = len(content)
     request = http.Request(DummyChannel(), False)
     request.method = 'POST'
     request.requestHeaders.setRawHeaders('Content-Length',
                                          [str(contentLength)])
     request.requestHeaders.setRawHeaders('Content-Type',
                                          ['application/json'])
     request.requestHeaders.setRawHeaders('Host',
                                          ['fluiddb.fluidinfo.com'])
     request._fluidDB_reqid = 'xxx'
     request.args = dict()
     request.postpath = []
     request.content = StringIO(content)
     resource = NamespacesResource(FakeFacadeClient(), FakeSession())
     resource.render(request)
     # 201 Created
     self.assertEqual(request.code, http.CREATED)
     # check we don't have the CORS related headers
     headers = request.responseHeaders
     self.assertFalse(headers.hasHeader('Access-Control-Allow-Origin'))
     self.assertFalse(
         headers.hasHeader('Access-Control-Allow-Credentials'))
     self.assertFalse(
         headers.hasHeader('Access-Control-Expose-Headers'))
예제 #8
0
    def testContentMD5DoesNotMatch(self):
        """
        Checks that an incoming requests whose payload doesn't match the
        Content-MD5 header and returns a PRECONDITION FAILED (412).
        """

        payload = {"description": "A namespace for tags that I'm using to"
                                  "add to people",
                   "name": "people"}
        content = json.dumps(payload)
        contentLength = len(content)
        request = http.Request(DummyChannel(), False)
        request.method = 'POST'
        request.requestHeaders.setRawHeaders("Content-MD5", ["bad-md5"])
        request.requestHeaders.setRawHeaders("Content-Length",
                                             [str(contentLength)])
        request.requestHeaders.setRawHeaders("Content-Type",
                                             ["application/json"])
        request._fluidDB_reqid = 'xxx'
        request.args = dict()
        request.postpath = []
        request.content = StringIO(content)

        resource = NamespacesResource(FakeFacadeClient(), FakeSession())
        resource.render(request)
        self.assertEqual(request.code, http.PRECONDITION_FAILED)
예제 #9
0
    def testContentMD5OK(self):
        """
        Checks that an incoming requests whose payload matches the
        Content-MD5 header.
        """

        payload = {"description": "A namespace for tags that I'm using to"
                                  " add to people",
                   "name": "people"}
        content = json.dumps(payload)
        contentLength = len(content)
        md5Content = base64.standard_b64encode(md5(content).digest())
        request = http.Request(DummyChannel(), False)
        request.method = 'POST'
        request.requestHeaders.setRawHeaders("Content-MD5", [md5Content])
        request.requestHeaders.setRawHeaders("Content-Length",
                                             [str(contentLength)])
        request.requestHeaders.setRawHeaders("Content-Type",
                                             ["application/json"])
        request.requestHeaders.setRawHeaders("Host",
                                             ["fluiddb.fluidinfo.com"])
        request._fluidDB_reqid = 'xxx'
        request.args = dict()
        request.postpath = []
        request.content = StringIO(content)

        resource = NamespacesResource(FakeFacadeClient(), FakeSession())
        resource.render(request)
        self.assertEqual(request.code, http.CREATED)
예제 #10
0
 def testUnseekableContent(self):
     """
     Test that sending a request whose content cannot have seek called
     on it without raising a ValueError gets a 400 Bad Request status,
     with the appropriate C{X-FluidDB-Error-Class} value in the header.
     """
     request = FakeRequest('POST', 'namespaces/fluiddb')
     request.content = NoContent()
     resource = NamespacesResource(None, FakeSession())
     resource.render(request)
     self.assertFalse(request.finished)
     self.assertEqual(request.status, http.BAD_REQUEST)
     self.assertEqual(request.getResponseHeader('X-FluidDB-Error-Class'),
                      error.ContentSeekError.__name__)
예제 #11
0
    def testHeaderPresentOn401Error(self):
        """
        Check the WWW-Authenticate header is present, with the expected
        value when we hit a 401 (Unauthorized) error.
        """

        class ExplodingPermissionDeniedFacade(object):
            """
            A fake facade whose C{createNamespace} method always
            raises TPathPermissionDenied.
            """

            def createNamespace(self, *args, **kwargs):
                """
                Make something (unspecified) appear to go wrong with perms
                checking.

                @param args: Positional arguments for the new namespace.
                @param kwargs: Keyword arguments for the new namespace.
                @raise C{TPathPermissionDenied} no matter what.
                """
                raise TPathPermissionDenied()

        payload = {'description': 'A new namespace', 'name': 'people'}
        content = json.dumps(payload)
        contentLength = len(content)
        request = http.Request(DummyChannel(), False)
        request.method = 'POST'
        request.requestHeaders.setRawHeaders('Content-Length',
                                             [str(contentLength)])
        request.requestHeaders.setRawHeaders('Content-Type',
                                             ['application/json'])
        request.requestHeaders.setRawHeaders('Host', ['fluiddb.fluidinfo.com'])
        request._fluidDB_reqid = 'xxx'
        request.args = dict()
        request.postpath = []
        request.content = StringIO(content)
        resource = NamespacesResource(ExplodingPermissionDeniedFacade(),
                                      FakeSession())
        resource.render(request)
        # Check the response code and header content.
        self.assertEqual(request.code, http.UNAUTHORIZED)
        headers = request.responseHeaders
        self.assertTrue(headers.hasHeader('WWW-Authenticate'))
        self.assertEqual('Basic realm="Fluidinfo"',
                         headers.getRawHeaders('WWW-Authenticate')[0])
예제 #12
0
    def testHeaderPresentOn401Error(self):
        """
        Check the WWW-Authenticate header is present, with the expected
        value when we hit a 401 (Unauthorized) error.
        """
        class ExplodingPermissionDeniedFacade(object):
            """
            A fake facade whose C{createNamespace} method always
            raises TPathPermissionDenied.
            """
            def createNamespace(self, *args, **kwargs):
                """
                Make something (unspecified) appear to go wrong with perms
                checking.

                @param args: Positional arguments for the new namespace.
                @param kwargs: Keyword arguments for the new namespace.
                @raise C{TPathPermissionDenied} no matter what.
                """
                raise TPathPermissionDenied()

        payload = {'description': 'A new namespace', 'name': 'people'}
        content = json.dumps(payload)
        contentLength = len(content)
        request = http.Request(DummyChannel(), False)
        request.method = 'POST'
        request.requestHeaders.setRawHeaders('Content-Length',
                                             [str(contentLength)])
        request.requestHeaders.setRawHeaders('Content-Type',
                                             ['application/json'])
        request.requestHeaders.setRawHeaders('Host', ['fluiddb.fluidinfo.com'])
        request._fluidDB_reqid = 'xxx'
        request.args = dict()
        request.postpath = []
        request.content = StringIO(content)
        resource = NamespacesResource(ExplodingPermissionDeniedFacade(),
                                      FakeSession())
        resource.render(request)
        # Check the response code and header content.
        self.assertEqual(request.code, http.UNAUTHORIZED)
        headers = request.responseHeaders
        self.assertTrue(headers.hasHeader('WWW-Authenticate'))
        self.assertEqual('Basic realm="Fluidinfo"',
                         headers.getRawHeaders('WWW-Authenticate')[0])
예제 #13
0
    def testInvalidCORSPreFlightRequestBadACRM(self):
        """
        The request has an Origin header but the
        Access-Control-Request-Method header contains an invalid value so
        check it returns a regular OPTIONS response.
        """
        # The origin to use in the tests
        dummyOrigin = 'http://foo.com'

        request = http.Request(DummyChannel(), False)
        request.method = 'OPTIONS'
        request.requestHeaders.setRawHeaders('Origin', [dummyOrigin])
        request.requestHeaders.setRawHeaders(
            'Access-Control-Request-Method',
            ['FOO'])
        request._fluidDB_reqid = 'xxx'
        request.args = dict()
        request.postpath = []
        request.content = NoContent()
        resource = NamespacesResource(FakeFacadeClient(), FakeSession())
        resource._handleOptions(request, dummyOrigin)
        # 200 OK
        self.assertEqual(request.code, http.OK)
        # check we have the required headers
        headers = request.responseHeaders
        self.assertTrue(headers.hasHeader('Allow'))
        # Check the allowed methods (including and in addition to those
        # allowed for CORS)
        allowedMethods = headers.getRawHeaders('Allow')[0].split(', ')
        self.assertEqual(
            len(resource.allowedMethods),
            len(allowedMethods))
        for item in resource.allowedMethods:
            self.assertTrue(item in allowedMethods)
        # There are *NO* CORS related headers
        self.assertFalse(headers.hasHeader('Access-Control-Allow-Origin'))
        self.assertFalse(headers.hasHeader('Access-Control-Max-Age'))
        self.assertFalse(
            headers.hasHeader('Access-Control-Allow-Credentials'))
        self.assertFalse(headers.hasHeader('Access-Control-Allow-Methods'))
예제 #14
0
 def testHeaderNotPresentWhenNoError(self):
     """
     Check the WWW-Authenticate header is not present
     when we do not hit an error.
     """
     payload = {'description': 'A new namespace', 'name': 'people'}
     content = json.dumps(payload)
     contentLength = len(content)
     request = http.Request(DummyChannel(), False)
     request.method = 'POST'
     request.requestHeaders.setRawHeaders('Content-Length',
                                          [str(contentLength)])
     request.requestHeaders.setRawHeaders('Content-Type',
                                          ['application/json'])
     request.requestHeaders.setRawHeaders('Host', ['fluiddb.fluidinfo.com'])
     request._fluidDB_reqid = 'xxx'
     request.args = dict()
     request.postpath = []
     request.content = StringIO(content)
     resource = NamespacesResource(FakeFacadeClient(), FakeSession())
     resource.render(request)
     # Check the WWW-Authenticate header is absent.
     headers = request.responseHeaders
     self.assertFalse(headers.hasHeader('WWW-Authenticate'))
예제 #15
0
 def testNamespacesResource(self):
     resource = NamespacesResource(FakeFacadeClient(), FakeSession())
     self._checkCORSPreFlightRequest(resource)
예제 #16
0
 def testRegularCORSHeaders(self):
     """
     Validates that the headers are handled correctly for a CORS request
     that doesn't use the OPTIONS verb
     """
     # The origin to use in the tests
     dummyOrigin = 'http://foo.com'
     expectedHeaders = [
         'X-FluidDB-Error-Class', 'X-FluidDB-Path',
         'X-FluidDB-Message', 'X-FluidDB-ObjectId', 'X-FluidDB-Name',
         'X-FluidDB-Category', 'X-FluidDB-Action', 'X-FluidDB-Rangetype',
         'X-FluidDB-Fieldname', 'X-FluidDB-Argument',
         'X-FluidDB-Access-Token', 'X-FluidDB-Username',
         'X-FluidDB-New-User'
     ]
     payload = {'description': 'A namespace for tags that I add to people',
                'name': 'people'}
     content = json.dumps(payload)
     contentLength = len(content)
     request = http.Request(DummyChannel(), False)
     request.method = 'POST'
     request.requestHeaders.setRawHeaders('Content-Length',
                                          [str(contentLength)])
     request.requestHeaders.setRawHeaders('Content-Type',
                                          ['application/json'])
     request.requestHeaders.setRawHeaders('Host',
                                          ['fluiddb.fluidinfo.com'])
     request.requestHeaders.setRawHeaders('Origin', [dummyOrigin])
     request._fluidDB_reqid = 'xxx'
     request.args = dict()
     request.postpath = []
     request.content = StringIO(content)
     resource = NamespacesResource(FakeFacadeClient(), FakeSession())
     resource.render(request)
     # 201 Created
     self.assertEqual(request.code, http.CREATED)
     # check we have the required headers
     headers = request.responseHeaders
     self.assertTrue(headers.hasHeader('Access-Control-Allow-Origin'))
     self.assertTrue(
         headers.hasHeader('Access-Control-Allow-Credentials'))
     self.assertTrue(
         headers.hasHeader('Access-Control-Expose-Headers'))
     # check the values of the required headers
     self.assertEqual(
         dummyOrigin,
         headers.getRawHeaders('Access-Control-Allow-Origin')[0])
     self.assertEqual(
         'true',
         headers.getRawHeaders('Access-Control-Allow-Credentials')[0])
     accessControlExposeHeaders = headers.getRawHeaders(
         'Access-Control-Expose-Headers')[0]
     # Make sure we haven't accidentally turned the header value into a
     # Python tuple by including a comma in its definition.
     self.assertTrue(isinstance(accessControlExposeHeaders, str))
     # Make sure we haven't accidentally left a comma space in the last
     # element of the Python header definition.
     self.assertFalse(accessControlExposeHeaders.endswith(', '))
     actualHeaders = accessControlExposeHeaders.split(', ')
     for header in expectedHeaders:
         self.assertTrue(header.startswith('X-FluidDB-'))
         self.assertTrue(header in actualHeaders)