Skip to content
This repository has been archived by the owner on May 5, 2021. It is now read-only.

Add auth field #26

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions rest_hooks/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class Migration(migrations.Migration):
('event', models.CharField(max_length=64, verbose_name=b'Event', db_index=True)),
('target', models.URLField(max_length=255, verbose_name=b'Target URL')),
('user', models.ForeignKey(related_name='hooks', to=settings.AUTH_USER_MODEL)),
('authorization', models.CharField(max_length=200, verbose_name=b'Authorization', null=True, blank=True)),

],
options={
},
Expand Down
7 changes: 6 additions & 1 deletion rest_hooks/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ class Hook(models.Model):
db_index=True,
choices=[(e, e) for e in HOOK_EVENTS.keys()])
target = models.URLField('Target URL', max_length=255)
authorization = models.CharField('Authorization', max_length=200,
null=True, blank=True)

def dict(self):
return {
Expand Down Expand Up @@ -87,10 +89,13 @@ def deliver_hook(self, instance, payload_override=None):
deliverer = get_module(settings.HOOK_DELIVERER)
deliverer(self.target, payload, instance=instance, hook=self)
else:
headers = {'Content-Type': 'application/json'}
if self.authorization is not None:
headers["Authorization"] = self.authorization
client.post(
url=self.target,
data=json.dumps(payload, cls=serializers.json.DjangoJSONEncoder),
headers={'Content-Type': 'application/json'}
headers=headers
)

signals.hook_sent_event.send_robust(sender=self.__class__, payload=payload, instance=instance, hook=self)
Expand Down
6 changes: 4 additions & 2 deletions rest_hooks/south_migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ def forwards(self, orm):
('user', self.gf('django.db.models.fields.related.ForeignKey')(related_name='hooks', to=orm['auth.User'])),
('event', self.gf('django.db.models.fields.CharField')(max_length=64, db_index=True)),
('target', self.gf('django.db.models.fields.URLField')(max_length=255)),
('authorization', self.gf('django.db.models.fields.CharField')(max_length=200, blank=True, null=True)),
))
db.send_create_signal('rest_hooks', ['Hook'])

Expand Down Expand Up @@ -69,8 +70,9 @@ def backwards(self, orm):
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'target': ('django.db.models.fields.URLField', [], {'max_length': '255'}),
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'hooks'", 'to': "orm['auth.User']"})
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'hooks'", 'to': "orm['auth.User']"}),
'authorization': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True', 'null': 'True'})
}
}

complete_apps = ['rest_hooks']
complete_apps = ['rest_hooks']
7 changes: 6 additions & 1 deletion rest_hooks/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@


class DeliverHook(Task):
def run(self, target, payload, instance=None, hook_id=None, **kwargs):
def run(self, target, payload, instance=None, hook_id=None,
authorization=None, **kwargs):
"""
target: the url to receive the payload.
payload: a python primitive data structure
instance: a possibly null "trigger" instance
hook: the defining Hook object (useful for removing)
"""
headers = {'Content-Type': 'application/json'}
if authorization is not None:
headers["Authorization"] = authorization
response = requests.post(
url=target,
data=json.dumps(payload, cls=DjangoJSONEncoder),
Expand All @@ -28,6 +32,7 @@ def run(self, target, payload, instance=None, hook_id=None, **kwargs):

# would be nice to log this, at least for a little while...


def deliver_hook_wrapper(target, payload, instance=None, hook=None, **kwargs):
if hook:
kwargs['hook_id'] = hook.id
Expand Down
40 changes: 40 additions & 0 deletions rest_hooks/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@ def make_hook(self, event, target):
target=target
)

def make_hook_with_auth(self, event, target, authorization):
return Hook.objects.create(
user=self.user,
event=event,
target=target,
authorization=authorization
)

#############
### TESTS ###
#############
Expand Down Expand Up @@ -100,6 +108,24 @@ def perform_create_request_cycle(self, method_mock):

return hook, comment, json.loads(method_mock.call_args_list[0][1]['data'])

@patch('requests.post', autospec=True)
def perform_create_request_cycle_authorized(self, method_mock):
method_mock.return_value = None

target = 'http://example.com/perform_create_request_cycle'
auth = 'Token 0639e26b-a9df-4fb7-9c40-10d7f62e6e06'
hook = self.make_hook_with_auth('comment.added', target, auth)

comment = Comment.objects.create(
site=self.site,
content_object=self.user,
user=self.user,
comment='Hello world!'
)
# time.sleep(1) # should change a setting to turn off async

return hook, comment, json.loads(method_mock.call_args_list[0][1]['data'])

def test_simple_comment_hook(self):
"""
Uses the default serializer.
Expand All @@ -114,6 +140,20 @@ def test_simple_comment_hook(self):
self.assertEquals('Hello world!', payload['data']['fields']['comment'])
self.assertEquals(comment.user.id, payload['data']['fields']['user'])

def test_simple_comment_hook_authorized(self):
"""
Uses the default serializer.
"""
hook, comment, payload = self.perform_create_request_cycle_authorized()

self.assertEquals(hook.id, payload['hook']['id'])
self.assertEquals('comment.added', payload['hook']['event'])
self.assertEquals(hook.target, payload['hook']['target'])

self.assertEquals(comment.id, payload['data']['pk'])
self.assertEquals('Hello world!', payload['data']['fields']['comment'])
self.assertEquals(comment.user.id, payload['data']['fields']['user'])

def test_comment_hook_serializer_method(self):
"""
Use custom serialize_hook on the Comment model.
Expand Down