Ejemplo n.º 1
0
    def _make_request(self, reqmeth, url, *args, **kwargs):
        # copy base request options and update with any keyword args
        rqst_options = self.request_options.copy()
        rqst_options.update(kwargs)
        start = time.time()
        response = reqmeth(self.prep_url(url), *args, **rqst_options)
        logger.debug('%s %s=>%d: %f sec' %
                     (reqmeth.__name__.upper(), url, response.status_code,
                      time.time() - start))

        # NOTE: currently doesn't do anything with 3xx  responses
        # (likely handled for us by requests)
        if response.status_code >= requests.codes.bad:  # 400 or worse
            # separate out 401 and 403 (permission errors) to enable
            # special handling in client code.
            if response.status_code in (requests.codes.unauthorized,
                                        requests.codes.forbidden):
                raise PermissionDenied(response)
            elif response.status_code == requests.codes.server_error:
                # check response content to determine if this is a
                # ChecksumMismatch or a more generic error
                if 'Checksum Mismatch' in response.text:
                    raise ChecksumMismatch(response)
                else:
                    raise RequestFailed(response)
            else:
                raise RequestFailed(response)
        return response
Ejemplo n.º 2
0
    def test_parse_fedora_access(self):
        TEMPLATE_TEXT = """
            {% load fedora %}
            {% fedora_access %}
                {{ test_obj.value }}
            {% permission_denied %}
                permission fallback
            {% fedora_failed %}
                connection fallback
            {% end_fedora_access %}
        """
        t = Template(TEMPLATE_TEXT)
        test_obj = MockFedoraObject()
        ctx = Context({'test_obj': test_obj})

        val = t.render(ctx)
        self.assertEqual(val.strip(), 'sample text')

        response = Mock()
        response.status_code = 401
        response.headers = {'content-type': 'text/plain'}
        response.content = ''
        test_obj._value = PermissionDenied(
            response)  # force test_obj.value to fail
        val = t.render(ctx)
        self.assertEqual(val.strip(), 'permission fallback')

        response.status_code = 500
        test_obj._value = RequestFailed(
            response)  # force test_obj.value to fail
        val = t.render(ctx)
        self.assertEqual(val.strip(), 'connection fallback')
Ejemplo n.º 3
0
    def test_create_save_errors(self):
        'Test fedora error handling when saving a collection object'
        # simulate fedora errors with mock objects

        # log in as repository editor
        self.client.post(settings.LOGIN_URL, ADMIN_CREDENTIALS)

        testobj = Mock(name='MockDigitalObject')
        testobj.dc.content = DublinCore()
        # Create a RequestFailed exception to simulate Fedora error
        # - eulcore.fedora wrap around an httplib response
        err_resp = Mock()
        err_resp.status = 500
        err_resp.read.return_value = 'error message'
        # generate Fedora error on object save
        testobj.save.side_effect = RequestFailed(err_resp)

        # valid form data to post
        test_data = {'title': 'foo', 'description': 'bar'}

        # 500 error / request failed
        # patch the repository class to return the mock object instead of a real one
        with patch.object(Repository,
                          'get_object',
                          new=Mock(return_value=testobj)):
            response = self.client.post(self.new_coll_url,
                                        test_data,
                                        follow=True)
            expected, code = 500, response.status_code
            self.assertEqual(
                code, expected,
                'Expected %s but returned %s for %s (Fedora 500 error)' %
                (expected, code, self.new_coll_url))
            messages = [str(msg) for msg in response.context['messages']]
            self.assert_(
                'error communicating with the repository' in messages[0])

        # update the mock error to generate a permission denied error
        err_resp.status = 401
        err_resp.read.return_value = 'denied'
        # generate Fedora error on object save
        testobj.save.side_effect = PermissionDenied(err_resp)

        # 401 error -  permission denied
        with patch.object(Repository,
                          'get_object',
                          new=Mock(return_value=testobj)):
            response = self.client.post(self.new_coll_url,
                                        test_data,
                                        follow=True)
            expected, code = 401, response.status_code
            self.assertEqual(
                code, expected,
                'Expected %s but returned %s for %s (Fedora 401 error)' %
                (expected, code, self.new_coll_url))
            messages = [str(msg) for msg in response.context['messages']]
            self.assert_("You don't have permission to create a collection" in
                         messages[0])
Ejemplo n.º 4
0
    def _make_request(self, reqmeth, url, *args, **kwargs):
        # copy base request options and update with any keyword args
        rqst_options = self.request_options.copy()
        rqst_options.update(kwargs)
        start = time.time()
        response = reqmeth(self.prep_url(url), *args, **rqst_options)
        total_time = time.time() - start
        logger.debug('%s %s=>%d: %f sec', reqmeth.__name__.upper(), url,
                     response.status_code, total_time)

        # if django signals are available, send api called
        if api_called is not None:
            api_called.send(sender=self.__class__,
                            time_taken=total_time,
                            method=reqmeth,
                            url=url,
                            response=response,
                            args=args,
                            kwargs=kwargs)

        # NOTE: currently doesn't do anything with 3xx  responses
        # (likely handled for us by requests)
        if response.status_code >= requests.codes.bad:  # 400 or worse
            # separate out 401 and 403 (permission errors) to enable
            # special handling in client code.
            if response.status_code in (requests.codes.unauthorized,
                                        requests.codes.forbidden):
                raise PermissionDenied(response)
            elif response.status_code == requests.codes.server_error:
                # check response content to determine if this is a
                # ChecksumMismatch or a more generic error
                if 'Checksum Mismatch' in response.text:
                    raise ChecksumMismatch(response)
                elif 'Changing attributes on deleted datastreams is forbidden.' in response.text:
                    raise DatastreamDeleted(response)
                else:
                    raise RequestFailed(response)
            else:
                raise RequestFailed(response)
        return response
Ejemplo n.º 5
0
    def test_edit_save_errors(self):
        self.client.post(settings.LOGIN_URL, ADMIN_CREDENTIALS)
        data = self.edit_mgmt_data.copy()
        data.update({'title': 'foo', 'description': 'bar', 'creator': 'baz', 'file_name': 'foo.txt'})
        # simulate fedora errors with mock objects
        testobj = Mock(spec=FileObject, name='MockDigitalObject')
        # django templates recognize this as a callable; set to return itself when called
        testobj.return_value = testobj
        # create a Mock object, but use a DublinCore instance for xmlobjectform to inspect
        testobj.dc.content = DublinCore()
        testobj.pid = 'pid:1'	# required for url generation 
        # Create a RequestFailed exception to simulate Fedora error 
        # - eulcore.fedora wrap around an httplib response
        err_resp = Mock()
        err_resp.status = 500
   	err_resp.read.return_value = 'error message'
        # generate Fedora error on object save
        testobj.save.side_effect = RequestFailed(err_resp)

        # 500 error / request failed
        # patch the repository class to return the mock object instead of a real one
	#with patch.object(Repository, 'get_object', new=Mock(return_value=testobj)):
        with patch('genrepo.file.views.init_by_cmodel', new=Mock(return_value=testobj)):            
            response = self.client.post(self.edit_url, data, follow=True)
            expected, code = 500, response.status_code
            self.assertEqual(code, expected,
            	'Expected %s but returned %s for %s (Fedora 500 error)'
                % (expected, code, self.edit_url))
            messages = [ str(msg) for msg in response.context['messages'] ]
            self.assert_('error communicating with the repository' in messages[0])

        # update the mock object to generate a permission denied error
        err_resp.status = 401
        err_resp.read.return_value = 'denied'
        # generate Fedora error on object save
        testobj.save.side_effect = PermissionDenied(err_resp)
        
        # 401 error -  permission denied
	#with patch.object(Repository, 'get_object', new=Mock(return_value=testobj)):            
        with patch('genrepo.file.views.init_by_cmodel', new=Mock(return_value=testobj)):
            response = self.client.post(self.edit_url, data, follow=True)
            expected, code = 401, response.status_code
            self.assertEqual(code, expected,
            	'Expected %s but returned %s for %s (Fedora 401 error)'
                % (expected, code, self.edit_url))
            messages = [ str(msg) for msg in response.context['messages'] ]
            self.assert_("You don't have permission to modify this object"
                         in messages[0])