tripwire_notifier 0.1.1 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -1,8 +1,8 @@
1
- = Tripwire::Notifier
1
+ = TripwireNotifier
2
2
 
3
3
  Stop hurting your users!
4
4
 
5
- Tripwire captures validation errors from your Ruby on Rails application to help you identify and fix user experience issues. The Tripwire::Notifier gem makes it easy to hook up your app to the Tripwire web service.
5
+ Tripwire captures validation errors from your Ruby on Rails application to help you identify and fix user experience issues. The TripwireNotifier gem makes it easy to hook up your app to the Tripwire web service.
6
6
 
7
7
  If you haven't already signed up for a Tripwire account and set up your project, visit http://tripwireapp.com to do so now.
8
8
 
@@ -23,7 +23,9 @@ If you haven't already signed up for a Tripwire account and set up your project,
23
23
 
24
24
  * In your Rails app, create config/initializers/tripwire_notifier.rb and add the following line with the API key for your Tripwire project:
25
25
 
26
- Tripwire::Notifier.api_key = "<YOUR API KEY>"
26
+ TripwireNotifier.configure do |config|
27
+ config.api_key = "<YOUR API KEY>"
28
+ end
27
29
 
28
30
  Your validation failures will now be tracked on your create and update actions in production mode. Feel free to start script/server in production mode and trigger some of your own.
29
31
 
@@ -32,13 +34,13 @@ Your validation failures will now be tracked on your create and update actions i
32
34
 
33
35
  === Tracking custom actions
34
36
 
35
- Tripwire::Notifier assumes your app is RESTful, so it only monitors the create and update actions by default. If you're creating or updating records in non-RESTful actions, you can use an after_filter to make sure any validation failures in those actions are caught as well:
37
+ TripwireNotifier assumes your app is RESTful, so it only monitors the create and update actions by default. If you're creating or updating records in non-RESTful actions, you can use an after_filter to make sure any validation failures in those actions are caught as well:
36
38
 
37
39
  after_filter :log_validation_failures_to_tripwire, :only => [:create, :update, :my_custom_action]
38
40
 
39
41
  === Filtering params
40
42
 
41
- Tripwire::Notifier tracks the parameters submitted in actions that cause validation errors. Because your app may handle sensitive data, like passwords, credit card numbers, and nuclear launch codes, Tripwire::Notifier respects the built-in Rails parameter filtering that you enable with filter_parameter_logging in your ApplicationController. For example:
43
+ TripwireNotifier tracks the parameters submitted in actions that cause validation errors. Because your app may handle sensitive data, like passwords, credit card numbers, and nuclear launch codes, TripwireNotifier respects the built-in Rails parameter filtering that you enable with filter_parameter_logging in your ApplicationController. For example:
42
44
 
43
45
  # Scrub sensitive parameters from your log
44
46
  filter_parameter_logging :password, :secret
@@ -47,9 +49,9 @@ Per the Rails standard, those params will show up as "[FILTERED]" in the data su
47
49
 
48
50
  === Running in other environments
49
51
 
50
- Tripwire::Notifier is only enabled in the production environment by default. If you want to enable it in additional environments, such as staging, you'll need to add the following line to your initializer file:
52
+ TripwireNotifier is only enabled in the production environment by default. If you want to enable it in additional environments, such as staging, you'll need to add the following line to your Tripwire initializer:
51
53
 
52
- Tripwire::Notifier.monitored_environments << 'staging'
54
+ config.monitored_environments << 'staging'
53
55
 
54
56
 
55
57
  We plan to streamline the setup process in the future and provide additional detailed configuration options and documentation. Please feel free to contact us with feedback, questions, or suggestions about this process. Thanks!
data/Rakefile CHANGED
@@ -1,12 +1,14 @@
1
1
  require 'rubygems'
2
2
  require 'rake'
3
+ require File.dirname(__FILE__) + "/lib/tripwire_notifier/version.rb"
3
4
 
4
5
  begin
5
6
  require 'jeweler'
6
7
  Jeweler::Tasks.new do |gem|
8
+ gem.version = TripwireNotifier::VERSION
7
9
  gem.name = "tripwire_notifier"
8
10
  gem.summary = %Q{Tripwire (http://tripwireapp.com) captures validation errors from your Ruby on Rails application.}
9
- gem.description = %Q{Tripwire captures validation errors from your Ruby on Rails application to help you identify and fix user experience issues. The Tripwire::Notifier gem makes it easy to hook up your app to the Tripwire web service.}
11
+ gem.description = %Q{Tripwire captures validation errors from your Ruby on Rails application to help you identify and fix user experience issues. The TripwireNotifier gem makes it easy to hook up your app to the Tripwire web service.}
10
12
  gem.email = ""
11
13
  gem.homepage = "http://github.com/jeremyw/tripwire_notifier"
12
14
  gem.authors = ["Jeffrey Chupp", "Jeremy Weiskotten"]
@@ -44,7 +46,7 @@ task :default => :test
44
46
 
45
47
  require 'rake/rdoctask'
46
48
  Rake::RDocTask.new do |rdoc|
47
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
49
+ version = TripwireNotifier::VERSION
48
50
 
49
51
  rdoc.rdoc_dir = 'rdoc'
50
52
  rdoc.title = "tripwire_notifier #{version}"
@@ -1,107 +1,20 @@
1
1
  require 'net/http'
2
2
  require 'uri'
3
3
  require 'timeout'
4
+ require 'tripwire_notifier/version'
5
+ require 'tripwire_notifier/configuration'
6
+ require 'tripwire_notifier/rails/action_controller_monitor'
4
7
 
5
- # TODO: namespace the methods apart from log_validation_failures_to_tripwire ?
6
- module Tripwire
7
- module Notifier
8
- API_VERSION = "alpha 1"
9
- API_URL = 'http://api.tripwireapp.com/'
8
+ module TripwireNotifier
9
+ API_VERSION = "alpha 1"
10
+ API_URL = 'http://api.tripwireapp.com/'
10
11
 
11
- class << self
12
- attr_accessor :api_key, :monitored_environments, :timeout_in_seconds
13
- end
14
-
15
- def self.included(base)
16
- # set our defaults
17
- self.monitored_environments = ['production']
18
- self.timeout_in_seconds = 5
19
-
20
- base.after_filter :log_validation_failures_to_tripwire, :only => [:create, :update]
21
- end
22
-
23
- def log_validation_failures_to_tripwire
24
- if should_log_failures_to_tripwire? && records_with_errors.present?
25
- begin
26
- timeout(Tripwire::Notifier.timeout_in_seconds) do
27
- Net::HTTP.post_form(
28
- URI.parse(API_URL),
29
- tripwire_params
30
- )
31
- end
32
- rescue Exception => ex
33
- warn "Could not submit tripwireapp notification: #{ex.class} - #{ex.message}" unless Rails.env.production?
34
- end
35
- end
36
- end
37
-
38
- private
39
-
40
- def should_log_failures_to_tripwire?
41
- Tripwire::Notifier.monitored_environments.include?(Rails.env.to_s)
42
- end
43
-
44
- def records_with_errors
45
- @records_with_errors ||= begin
46
- instance_variable_names.map do |var_name|
47
- var = instance_variable_get(var_name)
48
- if var.is_a?(Array)
49
- var.select{|v| record_has_errors?(v)}
50
- else
51
- var if record_has_errors?(var)
52
- end
53
- end.flatten.compact
54
- end
55
- end
56
-
57
- def record_has_errors?(record)
58
- record.respond_to?(:errors) && record.errors.present?
59
- end
60
-
61
- # TODO: remove assumptions about being called within a rails app (request, etc.) as part of framework agnosticism
62
- def tripwire_params
63
- # TODO: limit this in size - how big?
64
- data = {:params => filtered_params} # TODO: this is going to make controller and action redundant
65
-
66
- data.merge!(:current_user => current_user) if respond_to?(:current_user)
67
- data.merge!(
68
- :user_agent => request.user_agent,
69
- :cookies => request.cookies,
70
- :session => request.session
71
- )
12
+ class << self
13
+ attr_accessor :configuration
72
14
 
73
- query = {
74
- :api_key => Tripwire::Notifier.api_key,
75
- :api_version => Tripwire::Notifier::API_VERSION,
76
- :_controller => params['controller'],
77
- :_action => params['action'],
78
- :path => request.path,
79
- :data => data.to_json
80
- }
81
-
82
- query[:failures] = records_with_errors.map do |record|
83
- record.errors.map do |field, messages|
84
- Array(messages).map do |message|
85
- {
86
- :model => record.class.to_s,
87
- :field => field,
88
- :message => message
89
- }
90
- end
91
- end
92
- end.flatten.to_json
93
-
94
- query
95
- end
96
-
97
- def filtered_params
98
- if respond_to?(:filter_parameters)
99
- filter_parameters(params)
100
- else
101
- params
102
- end
15
+ def configure
16
+ self.configuration ||= Configuration.new
17
+ yield(configuration)
103
18
  end
104
19
  end
105
20
  end
106
-
107
- ActionController::Base.send(:include, Tripwire::Notifier)
@@ -0,0 +1,14 @@
1
+ module TripwireNotifier
2
+ class Configuration
3
+ attr_accessor :notifier_version
4
+ attr_accessor :api_key
5
+ attr_accessor :monitored_environments
6
+ attr_accessor :timeout_in_seconds
7
+
8
+ def initialize
9
+ @notifier_version = VERSION
10
+ @timeout_in_seconds = 5
11
+ @monitored_environments = ['production']
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,110 @@
1
+ module TripwireNotifier
2
+ module Rails
3
+ # This module is mixed into ActionController::Base.
4
+ module ActionControllerMonitor
5
+
6
+ def self.included(base)
7
+ base.after_filter :log_validation_failures_to_tripwire, :only => [:create, :update]
8
+ end
9
+
10
+ protected
11
+
12
+ def log_validation_failures_to_tripwire
13
+ if should_log_failures_to_tripwire? && records_with_errors.present?
14
+ begin
15
+ timeout(TripwireNotifier.configuration.timeout_in_seconds) do
16
+ Net::HTTP.post_form(
17
+ URI.parse(TripwireNotifier::API_URL),
18
+ tripwire_params
19
+ )
20
+ end
21
+ rescue Exception => ex
22
+ error "Could not submit tripwireapp notification: #{ex.class} - #{ex.message}"
23
+ end
24
+ end
25
+ end
26
+
27
+ def should_log_failures_to_tripwire?
28
+ TripwireNotifier.configuration.monitored_environments.include?(::Rails.env.to_s)
29
+ end
30
+
31
+ def records_with_errors
32
+ @records_with_errors ||= begin
33
+ instance_variable_names.map do |var_name|
34
+ var = instance_variable_get(var_name)
35
+ if var.is_a?(Array)
36
+ var.select{|v| record_has_errors?(v)}
37
+ else
38
+ var if record_has_errors?(var)
39
+ end
40
+ end.flatten.compact
41
+ end
42
+ end
43
+
44
+ def record_has_errors?(record)
45
+ record.respond_to?(:errors) && record.errors.present?
46
+ end
47
+
48
+ def tripwire_params
49
+ {}.tap do |query|
50
+ query[:notifier_version] = TripwireNotifier.configuration.notifier_version
51
+ query[:api_key] = TripwireNotifier.configuration.api_key
52
+ query[:api_version] = TripwireNotifier::API_VERSION
53
+ query[:_controller] = params['controller']
54
+ query[:_action] = params['action']
55
+ query[:path] = request.path
56
+ query[:data] = request_data.to_json
57
+
58
+ query[:failures] = records_with_errors.map do |record|
59
+ error_hashes(record)
60
+ end.flatten.to_json
61
+ end
62
+ end
63
+
64
+ def error_hashes(record)
65
+ record.errors.map do |field, messages|
66
+ Array.wrap(messages).map do |message|
67
+ error_hash(record.class, field, message)
68
+ end
69
+ end
70
+ end
71
+
72
+ def error_hash(clazz, field, message)
73
+ {
74
+ :model => clazz.to_s,
75
+ :field => field,
76
+ :message => message
77
+ }
78
+ end
79
+
80
+ def request_data
81
+ {}.tap do |data|
82
+ # TODO: limit this in size - how big?
83
+ data[:params] = filtered_params # TODO: controller and action are redundant
84
+
85
+ if respond_to?(:current_user) && !current_user.nil?
86
+ data[:current_user] = current_user.id
87
+ end
88
+
89
+ data[:user_agent] = request.user_agent
90
+ data[:cookies] = request.cookies
91
+ data[:session] = request.session
92
+ end
93
+ end
94
+
95
+ def filtered_params
96
+ if respond_to?(:filter_parameters)
97
+ # pre-Rails 3
98
+ filter_parameters(params)
99
+ elsif request.respond_to?(:filtered_parameters)
100
+ # Rails 3
101
+ request.filtered_parameters
102
+ else
103
+ params
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
109
+
110
+ ActionController::Base.send(:include, TripwireNotifier::Rails::ActionControllerMonitor)
@@ -0,0 +1,3 @@
1
+ module TripwireNotifier
2
+ VERSION = '0.2.1'
3
+ end
data/test/helper.rb CHANGED
@@ -18,9 +18,16 @@ class FooController < ActionController::Base
18
18
  filter_parameter_logging :password
19
19
  end
20
20
 
21
+ class User
22
+ attr_accessor :id
23
+ def initialize
24
+ @id = 53077
25
+ end
26
+ end
27
+
21
28
  class BarController < ActionController::Base
22
29
  def current_user
23
- "joe"
30
+ User.new
24
31
  end
25
32
  end
26
33
 
@@ -17,9 +17,12 @@ class TestTripwire < Test::Unit::TestCase
17
17
 
18
18
  @foo_controller = fake_controller(FooController)
19
19
 
20
- FakeWeb.register_uri(:post, Tripwire::Notifier::API_URL, :body => "")
21
- Tripwire::Notifier.api_key = "SOME API KEY"
22
- Tripwire::Notifier.monitored_environments = ['production']
20
+ FakeWeb.register_uri(:post, TripwireNotifier::API_URL, :body => "")
21
+
22
+ TripwireNotifier.configure do |config|
23
+ config.api_key = "SOME API KEY"
24
+ config.monitored_environments = ['production']
25
+ end
23
26
 
24
27
  @model_one = OpenStruct.new(:errors => {"bar" => "is blank"})
25
28
  @model_two = OpenStruct.new(:errors => {"baz" => "is blank"})
@@ -33,27 +36,26 @@ class TestTripwire < Test::Unit::TestCase
33
36
  end
34
37
 
35
38
  should "set an api key" do
36
- Tripwire::Notifier.api_key = "Foo"
37
-
38
- assert_equal "Foo", Tripwire::Notifier.api_key
39
+ TripwireNotifier.configure { |c| c.api_key = "Foo" }
40
+ assert_equal "Foo", TripwireNotifier.configuration.api_key
39
41
  end
40
42
 
41
43
  should "set a timeout_in_seconds" do
42
- assert_equal 5, Tripwire::Notifier.timeout_in_seconds
43
- Tripwire::Notifier.timeout_in_seconds = 6
44
- assert_equal 6, Tripwire::Notifier.timeout_in_seconds
44
+ assert_equal 5, TripwireNotifier.configuration.timeout_in_seconds
45
+ TripwireNotifier.configure { |c| c.timeout_in_seconds = 6 }
46
+ assert_equal 6, TripwireNotifier.configuration.timeout_in_seconds
45
47
  end
46
48
 
47
49
  should "set monitored environments" do
48
- assert_equal ["production"], Tripwire::Notifier.monitored_environments
49
- Tripwire::Notifier.monitored_environments = ['stage', 'development']
50
- assert_equal ['stage', 'development'], Tripwire::Notifier.monitored_environments
50
+ assert_equal ["production"], TripwireNotifier.configuration.monitored_environments
51
+ TripwireNotifier.configure { |c| c.monitored_environments = ['stage', 'development'] }
52
+ assert_equal ['stage', 'development'], TripwireNotifier.configuration.monitored_environments
51
53
  end
52
54
 
53
55
  should "respect monitored environments" do
54
56
  assert @foo_controller.send(:should_log_failures_to_tripwire?)
55
57
 
56
- Tripwire::Notifier.monitored_environments = ['stage', 'development']
58
+ TripwireNotifier.configuration.monitored_environments = ['stage', 'development']
57
59
  assert !@foo_controller.send(:should_log_failures_to_tripwire?)
58
60
  end
59
61
 
@@ -77,12 +79,12 @@ class TestTripwire < Test::Unit::TestCase
77
79
  params = @foo_controller.send(:tripwire_params)
78
80
  failures = JSON.parse(params[:failures])
79
81
  assert_same_elements expected, failures
80
- assert_same_elements Tripwire::Notifier::API_VERSION, params[:api_version]
82
+ assert_same_elements TripwireNotifier::API_VERSION, params[:api_version]
81
83
  assert_same_elements "SOME API KEY", params[:api_key]
82
84
  end
83
85
 
84
86
  should "submit errors via log_validation_failures_to_tripwire" do
85
- Net::HTTP.expects(:post_form).with(URI.parse(Tripwire::Notifier::API_URL), @foo_controller.send(:tripwire_params))
87
+ Net::HTTP.expects(:post_form).with(URI.parse(TripwireNotifier::API_URL), @foo_controller.send(:tripwire_params))
86
88
  @foo_controller.send(:log_validation_failures_to_tripwire)
87
89
  end
88
90
 
@@ -101,9 +103,9 @@ class TestTripwire < Test::Unit::TestCase
101
103
  assert_equal @foo_controller.params.merge('password' => "[FILTERED]", 'password_confirmation' => '[FILTERED]'), JSON.parse(@foo_controller.send(:tripwire_params)[:data])['params']
102
104
  end
103
105
 
104
- should "log current user if the method is exposed" do
106
+ should "log current user's id if the method is exposed" do
105
107
  assert_equal nil, JSON.parse(@foo_controller.send(:tripwire_params)[:data])['current_user']
106
- assert_equal "joe", JSON.parse(fake_controller(BarController).send(:tripwire_params)[:data])['current_user']
108
+ assert_equal 53077, JSON.parse(fake_controller(BarController).send(:tripwire_params)[:data])['current_user']
107
109
  end
108
110
 
109
111
  [:cookies, :session, :user_agent].each do |kind|
@@ -5,12 +5,12 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{tripwire_notifier}
8
- s.version = "0.1.1"
8
+ s.version = "0.2.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jeffrey Chupp", "Jeremy Weiskotten"]
12
- s.date = %q{2010-07-12}
13
- s.description = %q{Tripwire captures validation errors from your Ruby on Rails application to help you identify and fix user experience issues. The Tripwire::Notifier gem makes it easy to hook up your app to the Tripwire web service.}
12
+ s.date = %q{2010-08-19}
13
+ s.description = %q{Tripwire captures validation errors from your Ruby on Rails application to help you identify and fix user experience issues. The TripwireNotifier gem makes it easy to hook up your app to the Tripwire web service.}
14
14
  s.email = %q{}
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE",
@@ -22,8 +22,10 @@ Gem::Specification.new do |s|
22
22
  "LICENSE",
23
23
  "README.rdoc",
24
24
  "Rakefile",
25
- "VERSION",
26
25
  "lib/tripwire_notifier.rb",
26
+ "lib/tripwire_notifier/configuration.rb",
27
+ "lib/tripwire_notifier/rails/action_controller_monitor.rb",
28
+ "lib/tripwire_notifier/version.rb",
27
29
  "test/helper.rb",
28
30
  "test/test_tripwire.rb",
29
31
  "tripwire_notifier.gemspec"
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tripwire_notifier
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 21
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
+ - 2
8
9
  - 1
9
- - 1
10
- version: 0.1.1
10
+ version: 0.2.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jeffrey Chupp
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2010-07-12 00:00:00 -04:00
19
+ date: 2010-08-19 00:00:00 -04:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -33,7 +33,7 @@ dependencies:
33
33
  version: "0"
34
34
  type: :development
35
35
  version_requirements: *id001
36
- description: Tripwire captures validation errors from your Ruby on Rails application to help you identify and fix user experience issues. The Tripwire::Notifier gem makes it easy to hook up your app to the Tripwire web service.
36
+ description: Tripwire captures validation errors from your Ruby on Rails application to help you identify and fix user experience issues. The TripwireNotifier gem makes it easy to hook up your app to the Tripwire web service.
37
37
  email: ""
38
38
  executables: []
39
39
 
@@ -48,8 +48,10 @@ files:
48
48
  - LICENSE
49
49
  - README.rdoc
50
50
  - Rakefile
51
- - VERSION
52
51
  - lib/tripwire_notifier.rb
52
+ - lib/tripwire_notifier/configuration.rb
53
+ - lib/tripwire_notifier/rails/action_controller_monitor.rb
54
+ - lib/tripwire_notifier/version.rb
53
55
  - test/helper.rb
54
56
  - test/test_tripwire.rb
55
57
  - tripwire_notifier.gemspec
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.1.1