rack-twilio-validator 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []