Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Add wrapper over WebHooks #17

Merged
merged 2 commits into from

2 participants

@stevenharman
Collaborator
  • Provide idiomatic Ruby access to posted attributes.
  • Encapsulate the algorithm for validating a WebHook.
stevenharman added some commits
@stevenharman stevenharman Upgrade to latest rspec for expect syntax 5a04472
@stevenharman stevenharman Add wrapper over WebHooks
* Provide idiomatic Ruby access to posted attributes.
* Encapsulate the algorithm for validating a WebHook.
05c0282
@tylerhunt tylerhunt merged commit 28211ff into from
@stevenharman stevenharman deleted the branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 27, 2012
  1. @stevenharman
  2. @stevenharman

    Add wrapper over WebHooks

    stevenharman authored
    * Provide idiomatic Ruby access to posted attributes.
    * Encapsulate the algorithm for validating a WebHook.
This page is out of date. Refresh to see the latest.
View
50 README.md
@@ -72,6 +72,56 @@ brewery_db.styles.all
brewery_db.styles.find(1)
```
+### WebHooks
+
+The BreweryDB API also provides [WebHooks][webhooks] which can be use to:
+
+> keep your local data stores in sync with the main BreweryDB API. Instead of
+> having to constantly query the API, webhooks will send you a message when
+> something changes.
+
+This library provides a simple abstraction over the data posted by those
+webhooks.
+
+```ruby
+webhook = BreweryDB::WebHook.new(webhook_params_hash)
+```
+
+#### Validating a WebHook
+
+The `webhook_params_hash` should contain the `key`, `nonce`, `action`, etc.
+sent as the payload of the webhook. A `BreweryDB::WebHook` object can validate
+the posted data by SHA1 hashing your API key with the `nonce` value and
+comparing it to the `key` value (as per the [docs][webhooks]).
+
+```ruby
+webhook.valid?(API_KEY) #=> true or false
+```
+
+#### Idiomatic wrapper over WebHook parameters
+
+The `BreweryDB::WebHook` object also provides an idiomatic Ruby wrapper over
+the parameters. For example, one of the parameters posted in a webhook is
+`attributeId`, which is the BreweryDB id for a brewery, beer, etc. This
+parameter is exposed by an instance of `BreweryDB::WebHook` via
+
+```ruby
+webhook.attribute_id #=> 'x6bRxw'
+```
+
+The full list of parameters available are:
+
+```ruby
+webhook.action #=> 'insert'
+webhook.attribute #=> 'beer'
+webhook.attribute_id #=> 'x6bRxw'
+webhook.key #=> 'some-long-key-value-here'
+webhook.nonce #=> 'some-long-nonce-value-here'
+webhook.sub_action #=> 'none'
+webhook.timestamp #=> '1350573527'
+```
+
+[webhooks]: http://developer.pintlabs.com/brewerydb/webhooks/
## Contributing
View
2  brewery_db.gemspec
@@ -13,7 +13,7 @@ Gem::Specification.new do |gem|
gem.add_dependency 'faraday_middleware', '~> 0.8'
gem.add_dependency 'hashie', '~> 1.1'
gem.add_development_dependency 'pry'
- gem.add_development_dependency 'rspec', '~> 2.0'
+ gem.add_development_dependency 'rspec', '~> 2.11'
gem.add_development_dependency 'vcr', '~> 2.0'
gem.files = `git ls-files`.split($\)
View
30 lib/brewery_db/web_hook.rb
@@ -0,0 +1,30 @@
+require 'digest/sha1'
+
+module BreweryDB
+ class WebHook
+
+ attr_reader :action, :attribute, :attribute_id, :key, :nonce, :sub_action,
+ :timestamp
+
+ def initialize(args)
+ @action = args[:action]
+ @attribute = args[:attribute]
+ @attribute_id = args[:attributeId]
+ @key = args[:key]
+ @nonce = args[:nonce]
+ @sub_action = args[:subAction]
+ @timestamp = args[:timestamp]
+ end
+
+ def valid?(api_key)
+ hash(api_key) == key
+ end
+
+ def hash(api_key)
+ Digest::SHA1.hexdigest("#{api_key}#{nonce}")
+ end
+ private :hash
+
+ end
+end
+
View
70 spec/brewery_db/web_hook_spec.rb
@@ -0,0 +1,70 @@
+require 'spec_helper'
+require 'brewery_db/web_hook'
+
+describe BreweryDB::WebHook do
+ subject(:web_hook) { described_class.new(brewery_db_payload) }
+ let(:action) { 'edit' }
+ let(:attribute) { 'beer' }
+ let(:attribute_id) { 'x6bRxw' }
+ let(:key) { 'cfae72cf7db09b7508905573c174baf1f026c051' }
+ let(:nonce) { '576a8003ab8936d99fb104401141d613' }
+ let(:sub_action) { 'none' }
+ let(:timestamp) { '1350573527' }
+ let(:brewery_db_payload) { { key: key, nonce: nonce, attribute: attribute,
+ attributeId: attribute_id, action: action,
+ subAction: sub_action, timestamp: timestamp } }
+
+ describe '.new' do
+ it 'extracts the action' do
+ expect(web_hook.action).to eq(action)
+ end
+
+ it 'extracts the attribute' do
+ expect(web_hook.attribute).to eq(attribute)
+ end
+
+ it 'extracts the attributeId' do
+ expect(web_hook.attribute_id).to eq(attribute_id)
+ end
+
+ it 'extracts the key' do
+ expect(web_hook.key).to eq(key)
+ end
+
+ it 'extracts the nonce' do
+ expect(web_hook.nonce).to eq(nonce)
+ end
+
+ it 'extracts the subAction' do
+ expect(web_hook.sub_action).to eq(sub_action)
+ end
+
+ it 'extracts the timestamp' do
+ expect(web_hook.timestamp).to eq(timestamp)
+ end
+ end
+
+ describe '#valid?' do
+ let(:api_key) { ENV['BREWERY_DB_API_KEY'] }
+
+ it 'is valid for a legit key and nonce' do
+ expect(web_hook).to be_valid(api_key)
+ end
+
+ context 'invalid nonce' do
+ let(:nonce) { '316d141104401bf99d6398ba3008a675' }
+
+ it 'is not valid' do
+ expect(web_hook).to_not be_valid(api_key)
+ end
+ end
+
+ context 'invalid key' do
+ let(:key) { '150c620f1fab471c3755098057b90bd7fc27eafc' }
+
+ it 'is not valid' do
+ expect(web_hook).to_not be_valid(api_key)
+ end
+ end
+ end
+end
Something went wrong with that request. Please try again.