Esempio n. 1
0
 def test_excludes_disabled(self):
     """Excludes disabled webhooks"""
     WebhookFactory.create(enabled=True)
     wh = WebhookFactory.create(enabled=False)
     qs = Webhook.active.all()
     assert qs.count() == 1
     assert wh not in qs
Esempio n. 2
0
 def test_includes_enabled(self):
     """Includes enabled webhooks"""
     wh = WebhookFactory.create(enabled=True)
     WebhookFactory.create(enabled=False)
     qs = Webhook.active.all()
     assert qs.count() == 1
     assert wh in qs
Esempio n. 3
0
 def test_no_post_if_no_webhook_method(self):
     """
     If there's no to_webhook method, don't attempt to serialize.
     """
     WebhookFactory.create(url="http://example.org")
     user = User.objects.create()
     with mock.patch('webhooks.tasks.requests', autospec=True) as mock_requests:
         publish_webhook('auth.User', 'pk', user.pk)
         assert mock_requests.post.call_count == 0
Esempio n. 4
0
 def test_lookup_by_nonexistent_field(self):
     """
     Properly handles error if non-existent field provided.
     """
     WebhookFactory.create(url="http://example.org")
     course = CourseFactory.create()
     with mock.patch('webhooks.tasks.requests', autospec=True):
         with pytest.raises(FieldError):
             publish_webhook('courses.Course', 'asdf', course.pk)
Esempio n. 5
0
 def test_lookup_by_non_pk(self):
     """
     Should be able to look things up by uuid too.
     """
     WebhookFactory.create(url="http://example.org")
     course = CourseFactory.create()
     with mock.patch('webhooks.tasks.requests', autospec=True) as mock_requests:
         publish_webhook('courses.Course', 'uuid', course.uuid)
         assert mock_requests.post.call_count == 1
Esempio n. 6
0
 def test_no_model_sends_delete(self):
     """
     If there's no model, send a delete.
     """
     WebhookFactory.create(url="http://example.org")
     with mock.patch('webhooks.tasks.requests', autospec=True) as mock_requests:
         publish_webhook('courses.Course', 'pk', 1)
         assert mock_requests.post.call_count == 1
         _, kwargs = mock_requests.post.call_args
         assert kwargs['json']['action'] == 'delete'
Esempio n. 7
0
 def test_model_posts_to_endpoint(self):
     """
     Happy case of posting.
     """
     WebhookFactory.create(url="http://example.org")
     course = CourseFactory.create()
     with mock.patch('webhooks.tasks.requests', autospec=True) as mock_requests:
         publish_webhook('courses.Course', 'pk', course.pk)
         assert mock_requests.post.call_count == 1
         _, kwargs = mock_requests.post.call_args
         payload = kwargs['json']
         assert isinstance(payload, dict)
         assert payload['action'] == 'update'
Esempio n. 8
0
 def test_one_post_of_many_failing(self):
     """
     Validates that if one post fails they don't all fail.
     """
     WebhookFactory.create(url="http://example.org")
     WebhookFactory.create(url="http://example.com")
     course = CourseFactory.create()
     with mock.patch('webhooks.tasks.requests', autospec=True) as mock_requests:
         response = Response()
         response._content = b""  # pylint: disable=protected-access
         response.status_code = 400
         mock_requests.post.side_effect = [RequestException("couldn't post"), response]
         publish_webhook('courses.Course', 'pk', course.pk)
         assert mock_requests.post.call_count == 2
Esempio n. 9
0
    def test_secure_header_verification(self):
        """
        Verifies that we sign each webhook request.
        """
        wh = WebhookFactory.create(url="http://example.org")
        course = CourseFactory.create()
        with mock.patch('webhooks.tasks.requests', autospec=True) as mock_requests:
            publish_webhook('courses.Course', 'pk', course.pk)
            assert mock_requests.post.call_count == 1
            _, kwargs = mock_requests.post.call_args
            assert kwargs['json']['action'] == 'update'

            # This constant_time_compare is important for implementations to
            # ensure they're not vulnerable to timing attacks.
            assert constant_time_compare(
                kwargs['headers']['X-CCXCon-Signature'], hmac.new(
                    force_bytes(wh.secret), force_bytes(json.dumps(kwargs['json'])),
                    hashlib.sha1).hexdigest())