rack-twilio-validator 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,49 @@
1
+ Rack::TwilioValidator
2
+ =====================
3
+
4
+ Rack middleware for authorizing the signature on Twilio requests.
5
+ Read more about Twilio security at [Twilio Security](http://www.twilio.com/docs/security)
6
+
7
+ Why
8
+ ---
9
+
10
+ You should verify the signature in requests to your Twilio controllers for
11
+ any app. Tutorials often miss this, and it's redundant to have
12
+ to add it to the application layer for every app you build. Hence,
13
+ middleware!
14
+
15
+ Installation
16
+ ------------
17
+
18
+ install it via rubygems:
19
+
20
+ ```
21
+ gem install rack-twilio-validator
22
+ ```
23
+
24
+ or put it in your Gemfile:
25
+
26
+ ```ruby
27
+ # Gemfile
28
+
29
+ gem 'rack-twilio-validator', :require => 'rack/twilio-validator'
30
+ ```
31
+
32
+ Usage
33
+ -----
34
+
35
+ In a Sinatra application, it would be something like:
36
+
37
+ ```ruby
38
+ # app.rb
39
+
40
+ use Rack::TwilioValidator :auth_token => "your_auth_token", :protected_path => "/twilio_switchboard/"
41
+ ```
42
+
43
+ The `auth_token` is required config, whereas `protected_path` is optional but
44
+ recommended if your application talks to both end users and Twilio.
45
+
46
+ #### Copyright
47
+
48
+ Copyright (c) (2012) Brendon Murphy. See license.txt for details.
49
+
@@ -0,0 +1,5 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
@@ -0,0 +1,44 @@
1
+ require "twilio-ruby"
2
+
3
+ module Rack
4
+ class TwilioValidator
5
+ def initialize(app, options = {})
6
+ @app = app
7
+ @options = options
8
+ @auth_token = options.fetch(:auth_token)
9
+ @app
10
+ end
11
+
12
+ def call(env)
13
+ self.dup._call(env)
14
+ end
15
+
16
+ def _call(env)
17
+ @request = Rack::Request.new(env)
18
+
19
+ if unprotected_path? || request_validator.validate(@request.url, @request.params, env['HTTP_X_TWILIO_SIGNATURE'])
20
+ @app.call(env)
21
+ else
22
+ response = ::Twilio::TwiML::Response.new do |r|
23
+ r.Say("Unable to authenticate request. Please try again.")
24
+ end
25
+ [401, { "Content-Type" => "application/xml" }, [response.text]]
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def protected_path?
32
+ protected_path = @options.fetch(:protected_path, "/")
33
+ @request.path =~ %r/^#{protected_path}/
34
+ end
35
+
36
+ def unprotected_path?
37
+ ! protected_path?
38
+ end
39
+
40
+ def request_validator
41
+ @validator ||= ::Twilio::Util::RequestValidator.new(@auth_token)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,5 @@
1
+ module Rack
2
+ class TwilioValidator
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,23 @@
1
+ licensed under MIT License:
2
+
3
+ Copyright (c) 2012 Brendon Murphy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib/", __FILE__)
3
+ require "rack/twilio-validator/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "rack-twilio-validator"
7
+ s.version = Rack::TwilioValidator::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Brendon Murphy"]
10
+ s.email = ["xternal1+github@gmail.com"]
11
+ s.homepage = ""
12
+ s.summary = %q{Rack Middleware for validating twilio request signatures}
13
+ s.description = s.summary
14
+ s.licenses = ["MIT"]
15
+
16
+ s.rubyforge_project = "rack-twilio-validator"
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {spec}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.require_paths = ["lib"]
22
+
23
+ s.add_dependency 'rack'
24
+ s.add_dependency 'twilio-ruby'
25
+
26
+ s.add_development_dependency 'rspec'
27
+ s.add_development_dependency 'rack-test'
28
+ s.add_development_dependency 'rake'
29
+ end
@@ -0,0 +1,8 @@
1
+ require File.expand_path("../../lib/rack/twilio-validator", __FILE__)
2
+ require "rack/test"
3
+
4
+ RSpec.configure do |config|
5
+ config.mock_with :rspec
6
+ config.include Rack::Test::Methods
7
+ end
8
+
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rack::TwilioValidator do
4
+ let(:auth_token) { "5cc8534fb3f86ff7e52d884562bcca18" }
5
+ let(:params) { { :foo => "fizz", :bar => "buzz" } }
6
+ let(:valid_signature) { "4C3R3E2C2TwiOkEwqznWMH1k3O8=" }
7
+ let(:uri) { "/twilio/endpoint"}
8
+
9
+ let(:app) {
10
+ Rack::Builder.new do
11
+ use Rack::TwilioValidator, :auth_token => "5cc8534fb3f86ff7e52d884562bcca18"
12
+ run lambda { |env| [200, {'Content-Type' => "text/plain"}, ["OK"]] }
13
+ end
14
+ }
15
+
16
+ context "given a valid signature" do
17
+ it "is ok" do
18
+ post(uri, params, "HTTP_X_TWILIO_SIGNATURE" => valid_signature)
19
+ last_response.should be_ok
20
+ end
21
+ end
22
+
23
+ context "given an invalid signature" do
24
+ before do
25
+ post(uri, params, "HTTP_X_TWILIO_SIGNATURE" => "bad_signature")
26
+ end
27
+
28
+ it "is unauthorized" do
29
+ last_response.status.should == 401
30
+ end
31
+
32
+ it "receives a TwiML error in the response body" do
33
+ last_response.body.should include("<Response><Say>Unable to authenticate request. Please try again.</Say></Response>")
34
+ end
35
+ end
36
+
37
+ context "given no signature" do
38
+ it "is unauthorized" do
39
+ post(uri, params, "HTTP_X_TWILIO_SIGNATURE" => nil)
40
+ last_response.status.should == 401
41
+ end
42
+ end
43
+
44
+ context "with an optional supplied protected path" do
45
+ let(:app) {
46
+ Rack::Builder.new do
47
+ use Rack::TwilioValidator, :auth_token => "5cc8534fb3f86ff7e52d884562bcca18", :protected_path => "/twilio"
48
+ run lambda { |env| [200, {'Content-Type' => "text/plain"}, ["OK"]] }
49
+ end
50
+ }
51
+
52
+ it "checks actions under the protected path" do
53
+ post("/twilio/endpoint", params, "HTTP_X_TWILIO_SIGNATURE" => "bad_signature")
54
+ last_response.status.should == 401
55
+ end
56
+
57
+ it "skips actions outside the protected path" do
58
+ post("/other/endpoint", params, "HTTP_X_TWILIO_SIGNATURE" => "bad_signature")
59
+ last_response.should be_ok
60
+ end
61
+ end
62
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack-twilio-validator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Brendon Murphy
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-07-14 00:00:00.000000000 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rack
17
+ requirement: &2160793140 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *2160793140
26
+ - !ruby/object:Gem::Dependency
27
+ name: twilio-ruby
28
+ requirement: &2160792120 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: *2160792120
37
+ - !ruby/object:Gem::Dependency
38
+ name: rspec
39
+ requirement: &2160791120 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *2160791120
48
+ - !ruby/object:Gem::Dependency
49
+ name: rack-test
50
+ requirement: &2160790140 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *2160790140
59
+ - !ruby/object:Gem::Dependency
60
+ name: rake
61
+ requirement: &2160789440 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ type: :development
68
+ prerelease: false
69
+ version_requirements: *2160789440
70
+ description: Rack Middleware for validating twilio request signatures
71
+ email:
72
+ - xternal1+github@gmail.com
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - .gitignore
78
+ - Gemfile
79
+ - README.md
80
+ - Rakefile
81
+ - lib/rack/twilio-validator.rb
82
+ - lib/rack/twilio-validator/version.rb
83
+ - license.txt
84
+ - rack-twilio-validator.gemspec
85
+ - spec/spec_helper.rb
86
+ - spec/twilio_validator_spec.rb
87
+ has_rdoc: true
88
+ homepage: ''
89
+ licenses:
90
+ - MIT
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ! '>='
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ segments:
102
+ - 0
103
+ hash: -490469738546845503
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ segments:
111
+ - 0
112
+ hash: -490469738546845503
113
+ requirements: []
114
+ rubyforge_project: rack-twilio-validator
115
+ rubygems_version: 1.6.2
116
+ signing_key:
117
+ specification_version: 3
118
+ summary: Rack Middleware for validating twilio request signatures
119
+ test_files: []