airbrake_user_attributes 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'rake'
4
+
5
+ gemspec
data/README.md ADDED
@@ -0,0 +1,11 @@
1
+ Airbrake - User Attributes
2
+ =======================
3
+
4
+ Adds information about the current user to error reports.
5
+ This information can only be processed and displayed by
6
+ [Errbit, the open source error catcher](https://github.com/errbit/errbit).
7
+
8
+ This gem can be used as a replacement for the `airbrake` gem,
9
+ since it loads `airbrake` as a dependency.
10
+
11
+ Copyright (c) 2012 Cloudfuji
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'bundler/gem_helper'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the airbrake_user_attributes gem.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.pattern = 'test/**/*_test.rb'
12
+ t.verbose = true
13
+ end
14
+
15
+ Bundler::GemHelper.install_tasks
16
+
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'airbrake_user_attributes/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'airbrake_user_attributes'
7
+ s.authors = ['Nathan Broadbent']
8
+ s.email = 'nathan.f77@gmail.com'
9
+ s.homepage = 'http://cloudfuji.com'
10
+ s.summary = 'Send Airbrake notifications with user attributes'
11
+ s.description = 'Adds information about the current user to error reports'
12
+ s.files = `git ls-files`.split("\n")
13
+ s.version = AirbrakeUserAttributes::VERSION
14
+
15
+ s.add_development_dependency("actionpack", "~> 2.3.8")
16
+ s.add_development_dependency("activerecord", "~> 2.3.8")
17
+ s.add_development_dependency("activesupport", "~> 2.3.8")
18
+ s.add_development_dependency("bourne", ">= 1.0")
19
+ s.add_development_dependency("fakeweb", "~> 1.3.0")
20
+ s.add_development_dependency("nokogiri", "~> 1.4.3.1")
21
+ s.add_development_dependency("rspec", "~> 2.6.0")
22
+ s.add_development_dependency("sham_rack", "~> 1.3.0")
23
+ s.add_development_dependency("shoulda", "~> 2.11.3")
24
+
25
+ s.add_dependency 'airbrake', '>= 3.0.9'
26
+
27
+ end
@@ -0,0 +1,85 @@
1
+ require 'airbrake/notice'
2
+
3
+ module Airbrake
4
+ class Notice
5
+ # User information
6
+ # - Provides information about the currently logged in user
7
+ attr_reader :user_attributes
8
+
9
+ def initialize_with_user_attributes(args)
10
+ self.user_attributes = args[:user_attributes] || {}
11
+ initialize_without_user_attributes(args)
12
+ end
13
+ alias_method_chain :initialize, :user_attributes
14
+
15
+ # Converts the given notice to XML
16
+ # Need to override whole builder to add user-attributes at end.
17
+ def to_xml
18
+ builder = Builder::XmlMarkup.new
19
+ builder.instruct!
20
+ xml = builder.notice(:version => Airbrake::API_VERSION) do |notice|
21
+ notice.tag!("api-key", api_key)
22
+ notice.notifier do |notifier|
23
+ notifier.name(notifier_name)
24
+ notifier.version(notifier_version)
25
+ notifier.url(notifier_url)
26
+ end
27
+ notice.error do |error|
28
+ error.tag!('class', error_class)
29
+ error.message(error_message)
30
+ error.backtrace do |backtrace|
31
+ self.backtrace.lines.each do |line|
32
+ backtrace.line(:number => line.number,
33
+ :file => line.file,
34
+ :method => line.method)
35
+ end
36
+ end
37
+ end
38
+ if url ||
39
+ controller ||
40
+ action ||
41
+ !parameters.blank? ||
42
+ !cgi_data.blank? ||
43
+ !session_data.blank?
44
+ notice.request do |request|
45
+ request.url(url)
46
+ request.component(controller)
47
+ request.action(action)
48
+ unless parameters.nil? || parameters.empty?
49
+ request.params do |params|
50
+ xml_vars_for(params, parameters)
51
+ end
52
+ end
53
+ unless session_data.nil? || session_data.empty?
54
+ request.session do |session|
55
+ xml_vars_for(session, session_data)
56
+ end
57
+ end
58
+ unless cgi_data.nil? || cgi_data.empty?
59
+ request.tag!("cgi-data") do |cgi_datum|
60
+ xml_vars_for(cgi_datum, cgi_data)
61
+ end
62
+ end
63
+ end
64
+ end
65
+ notice.tag!("server-environment") do |env|
66
+ env.tag!("project-root", project_root)
67
+ env.tag!("environment-name", environment_name)
68
+ env.tag!("hostname", hostname)
69
+ end
70
+
71
+ if user_attributes.present?
72
+ notice.tag!("user-attributes") do |user|
73
+ xml_vars_for(user, user_attributes)
74
+ end
75
+ end
76
+ end
77
+ xml.to_s
78
+ end
79
+
80
+ private
81
+
82
+ attr_writer :user_attributes
83
+
84
+ end
85
+ end
@@ -0,0 +1,31 @@
1
+ require 'airbrake/rails/controller_methods'
2
+
3
+ module Airbrake
4
+ module Rails
5
+ module ControllerMethods
6
+
7
+ def airbrake_request_data_with_user_attributes
8
+ data = airbrake_request_data_without_user_attributes
9
+ data[:user_attributes] = current_user_filtered_attributes if respond_to?(:current_user)
10
+ data
11
+ end
12
+ alias_method_chain :airbrake_request_data, :user_attributes
13
+
14
+ private
15
+
16
+ # Returns filtered attributes for current user (removes auth-related fields)
17
+ def current_user_filtered_attributes
18
+ attributes = current_user.attributes.reject do |k, v|
19
+ /password|token|login|sign_in|per_page|_at$/ =~ k
20
+ end
21
+ # Try to include a URL for the user, if possible.
22
+ if url_method = [:user_url, :admin_user_url].detect {|m| respond_to?(m) }
23
+ attributes[:url] = send(url_method, current_user)
24
+ end
25
+ attributes
26
+ end
27
+
28
+ end
29
+ end
30
+ end
31
+
@@ -0,0 +1,3 @@
1
+ module AirbrakeUserAttributes
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,3 @@
1
+ require 'airbrake'
2
+ require 'airbrake_overrides/notice'
3
+ require 'airbrake_overrides/rails/controller_methods'
@@ -0,0 +1,79 @@
1
+ <?xml version="1.0"?>
2
+ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
3
+
4
+ <xs:element name="notice">
5
+ <xs:complexType>
6
+ <xs:all>
7
+ <xs:element name="api-key" type="xs:string"/>
8
+ <xs:element name="notifier" type="notifier"/>
9
+ <xs:element name="error" type="error"/>
10
+ <xs:element name="request" type="request" minOccurs="0"/>
11
+ <xs:element name="server-environment" type="serverEnvironment"/>
12
+ <xs:element name="user-attributes" type="varList" minOccurs="0"/>
13
+ </xs:all>
14
+ <xs:attribute name="version" type="xs:string" use="required"/>
15
+ </xs:complexType>
16
+ </xs:element>
17
+
18
+ <xs:complexType name="notifier">
19
+ <xs:all>
20
+ <xs:element name="name" type="xs:string"/>
21
+ <xs:element name="version" type="xs:string"/>
22
+ <xs:element name="url" type="xs:string"/>
23
+ </xs:all>
24
+ </xs:complexType>
25
+
26
+ <xs:complexType name="error">
27
+ <xs:all>
28
+ <xs:element name="class" type="xs:string"/>
29
+ <xs:element name="message" type="xs:string" minOccurs="0"/>
30
+ <xs:element name="backtrace" type="backtrace"/>
31
+ </xs:all>
32
+ </xs:complexType>
33
+
34
+ <xs:complexType name="backtrace">
35
+ <xs:sequence>
36
+ <xs:element name="line" maxOccurs="unbounded">
37
+ <xs:complexType>
38
+ <xs:attribute name="file" type="xs:string" use="required"/>
39
+ <xs:attribute name="number" type="xs:string" use="required"/>
40
+ <xs:attribute name="method" type="xs:string" use="optional"/>
41
+ </xs:complexType>
42
+ </xs:element>
43
+ </xs:sequence>
44
+ </xs:complexType>
45
+
46
+ <xs:complexType name="request">
47
+ <xs:all>
48
+ <xs:element name="url" type="xs:string"/>
49
+ <xs:element name="component" type="xs:string"/>
50
+ <xs:element name="action" type="xs:string" minOccurs="0"/>
51
+ <xs:element name="params" type="varList" minOccurs="0"/>
52
+ <xs:element name="session" type="varList" minOccurs="0"/>
53
+ <xs:element name="cgi-data" type="varList" minOccurs="0"/>
54
+ </xs:all>
55
+ </xs:complexType>
56
+
57
+ <xs:complexType name="varList">
58
+ <xs:sequence>
59
+ <xs:element name="var" type="var" maxOccurs="unbounded"/>
60
+ </xs:sequence>
61
+ </xs:complexType>
62
+
63
+ <xs:complexType name="var" mixed="true">
64
+ <xs:sequence>
65
+ <xs:element name="var" type="var" minOccurs="0" maxOccurs="unbounded"/>
66
+ </xs:sequence>
67
+ <xs:attribute name="key" type="xs:string" use="required"/>
68
+ </xs:complexType>
69
+
70
+ <xs:complexType name="serverEnvironment">
71
+ <xs:sequence>
72
+ <xs:element name="project-root" type="xs:string" minOccurs="0"/>
73
+ <xs:element name="environment-name" type="xs:string"/>
74
+ <xs:element name="app-version" type="xs:string" minOccurs="0"/>
75
+ <xs:element name="hostname" type="xs:string" minOccurs="0"/>
76
+ </xs:sequence>
77
+ </xs:complexType>
78
+
79
+ </xs:schema>
data/test/helper.rb ADDED
@@ -0,0 +1,262 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+
4
+ $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
5
+
6
+ require 'thread'
7
+
8
+ require "bundler/setup"
9
+
10
+ require 'shoulda'
11
+ require 'mocha'
12
+
13
+ require 'action_controller'
14
+ require 'action_controller/test_process'
15
+ require 'active_record'
16
+ require 'active_support'
17
+ require 'nokogiri'
18
+ require 'rack'
19
+ require 'bourne'
20
+ require 'sham_rack'
21
+
22
+ require "airbrake"
23
+ require "airbrake_user_attributes"
24
+
25
+ begin require 'redgreen'; rescue LoadError; end
26
+
27
+ module TestMethods
28
+ def rescue_action e
29
+ raise e
30
+ end
31
+
32
+ def do_raise
33
+ raise "Airbrake"
34
+ end
35
+
36
+ def do_not_raise
37
+ render :text => "Success"
38
+ end
39
+
40
+ def do_raise_ignored
41
+ raise ActiveRecord::RecordNotFound.new("404")
42
+ end
43
+
44
+ def do_raise_not_ignored
45
+ raise ActiveRecord::StatementInvalid.new("Statement invalid")
46
+ end
47
+
48
+ def manual_notify
49
+ notify_airbrake(Exception.new)
50
+ render :text => "Success"
51
+ end
52
+
53
+ def manual_notify_ignored
54
+ notify_airbrake(ActiveRecord::RecordNotFound.new("404"))
55
+ render :text => "Success"
56
+ end
57
+ end
58
+
59
+ class Test::Unit::TestCase
60
+ def request(action = nil, method = :get, user_agent = nil, params = {})
61
+ @request = ActionController::TestRequest.new
62
+ @request.action = action ? action.to_s : ""
63
+
64
+ if user_agent
65
+ if @request.respond_to?(:user_agent=)
66
+ @request.user_agent = user_agent
67
+ else
68
+ @request.env["HTTP_USER_AGENT"] = user_agent
69
+ end
70
+ end
71
+ @request.query_parameters = @request.query_parameters.merge(params)
72
+ @response = ActionController::TestResponse.new
73
+ @controller.process(@request, @response)
74
+ end
75
+
76
+ # Borrowed from ActiveSupport 2.3.2
77
+ def assert_difference(expression, difference = 1, message = nil, &block)
78
+ b = block.send(:binding)
79
+ exps = Array.wrap(expression)
80
+ before = exps.map { |e| eval(e, b) }
81
+
82
+ yield
83
+
84
+ exps.each_with_index do |e, i|
85
+ error = "#{e.inspect} didn't change by #{difference}"
86
+ error = "#{message}.\n#{error}" if message
87
+ assert_equal(before[i] + difference, eval(e, b), error)
88
+ end
89
+ end
90
+
91
+ def assert_no_difference(expression, message = nil, &block)
92
+ assert_difference expression, 0, message, &block
93
+ end
94
+
95
+ def stub_sender
96
+ stub('sender', :send_to_airbrake => nil)
97
+ end
98
+
99
+ def stub_sender!
100
+ Airbrake.sender = stub_sender
101
+ end
102
+
103
+ def stub_notice
104
+ stub('notice', :to_xml => 'some yaml', :ignore? => false)
105
+ end
106
+
107
+ def stub_notice!
108
+ stub_notice.tap do |notice|
109
+ Airbrake::Notice.stubs(:new => notice)
110
+ end
111
+ end
112
+
113
+ def create_dummy
114
+ Airbrake::DummySender.new
115
+ end
116
+
117
+ def reset_config
118
+ Airbrake.configuration = nil
119
+ Airbrake.configure do |config|
120
+ config.api_key = 'abc123'
121
+ end
122
+ end
123
+
124
+ def clear_backtrace_filters
125
+ Airbrake.configuration.backtrace_filters.clear
126
+ end
127
+
128
+ def build_exception(opts = {})
129
+ backtrace = ["airbrake/test/helper.rb:132:in `build_exception'",
130
+ "airbrake/test/backtrace.rb:4:in `build_notice_data'",
131
+ "/var/lib/gems/1.8/gems/airbrake-2.4.5/rails/init.rb:2:in `send_exception'"]
132
+ opts = {:backtrace => backtrace}.merge(opts)
133
+ BacktracedException.new(opts)
134
+ end
135
+
136
+ class BacktracedException < Exception
137
+ attr_accessor :backtrace
138
+ def initialize(opts)
139
+ @backtrace = opts[:backtrace]
140
+ end
141
+ def set_backtrace(bt)
142
+ @backtrace = bt
143
+ end
144
+ end
145
+
146
+ def build_notice_data(exception = nil)
147
+ exception ||= build_exception
148
+ {
149
+ :api_key => 'abc123',
150
+ :error_class => exception.class.name,
151
+ :error_message => "#{exception.class.name}: #{exception.message}",
152
+ :backtrace => exception.backtrace,
153
+ :environment => { 'PATH' => '/bin', 'REQUEST_URI' => '/users/1' },
154
+ :request => {
155
+ :params => { 'controller' => 'users', 'action' => 'show', 'id' => '1' },
156
+ :rails_root => '/path/to/application',
157
+ :url => "http://test.host/users/1"
158
+ },
159
+ :session => {
160
+ :key => '123abc',
161
+ :data => { 'user_id' => '5', 'flash' => { 'notice' => 'Logged in successfully' } }
162
+ }
163
+ }
164
+ end
165
+
166
+ def assert_caught_and_sent
167
+ assert !Airbrake.sender.collected.empty?
168
+ end
169
+
170
+ def assert_caught_and_not_sent
171
+ assert Airbrake.sender.collected.empty?
172
+ end
173
+
174
+ def assert_array_starts_with(expected, actual)
175
+ assert_respond_to actual, :to_ary
176
+ array = actual.to_ary.reverse
177
+ expected.reverse.each_with_index do |value, i|
178
+ assert_equal value, array[i]
179
+ end
180
+ end
181
+
182
+ def assert_valid_node(document, xpath, content)
183
+ nodes = document.xpath(xpath)
184
+ assert nodes.any?{|node| node.content == content },
185
+ "Expected xpath #{xpath} to have content #{content}, " +
186
+ "but found #{nodes.map { |n| n.content }} in #{nodes.size} matching nodes." +
187
+ "Document:\n#{document.to_s}"
188
+ end
189
+
190
+ def assert_logged(expected)
191
+ assert_received(Airbrake, :write_verbose_log) do |expect|
192
+ expect.with {|actual| actual =~ expected }
193
+ end
194
+ end
195
+
196
+ def assert_not_logged(expected)
197
+ assert_received(Airbrake, :write_verbose_log) do |expect|
198
+ expect.with {|actual| actual =~ expected }.never
199
+ end
200
+ end
201
+
202
+
203
+ end
204
+
205
+ module DefinesConstants
206
+ def setup
207
+ @defined_constants = []
208
+ end
209
+
210
+ def teardown
211
+ @defined_constants.each do |constant|
212
+ Object.__send__(:remove_const, constant)
213
+ end
214
+ end
215
+
216
+ def define_constant(name, value)
217
+ Object.const_set(name, value)
218
+ @defined_constants << name
219
+ end
220
+ end
221
+
222
+ # Also stolen from AS 2.3.2
223
+ class Array
224
+ # Wraps the object in an Array unless it's an Array. Converts the
225
+ # object to an Array using #to_ary if it implements that.
226
+ def self.wrap(object)
227
+ case object
228
+ when nil
229
+ []
230
+ when self
231
+ object
232
+ else
233
+ if object.respond_to?(:to_ary)
234
+ object.to_ary
235
+ else
236
+ [object]
237
+ end
238
+ end
239
+ end
240
+
241
+ end
242
+
243
+ class CollectingSender
244
+ attr_reader :collected
245
+
246
+ def initialize
247
+ @collected = []
248
+ end
249
+
250
+ def send_to_airbrake(data)
251
+ @collected << data
252
+ end
253
+ end
254
+
255
+ class FakeLogger
256
+ def info(*args); end
257
+ def debug(*args); end
258
+ def warn(*args); end
259
+ def error(*args); end
260
+ def fatal(*args); end
261
+ end
262
+
@@ -0,0 +1,131 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class NoticeTest < Test::Unit::TestCase
4
+
5
+ include DefinesConstants
6
+
7
+ def configure
8
+ Airbrake::Configuration.new.tap do |config|
9
+ config.api_key = 'abc123def456'
10
+ end
11
+ end
12
+
13
+ def build_notice(args = {})
14
+ configuration = args.delete(:configuration) || configure
15
+ Airbrake::Notice.new(configuration.merge(args))
16
+ end
17
+
18
+ def stub_request(attrs = {})
19
+ stub('request', { :parameters => { 'one' => 'two' },
20
+ :protocol => 'http',
21
+ :host => 'some.host',
22
+ :request_uri => '/some/uri',
23
+ :session => { :to_hash => { 'a' => 'b' } },
24
+ :env => { 'three' => 'four' } }.update(attrs))
25
+ end
26
+
27
+ def hostname
28
+ `hostname`.chomp
29
+ end
30
+
31
+ def assert_valid_notice_document(document)
32
+ xsd_path = File.join(File.dirname(__FILE__), "airbrake_2_2.xsd")
33
+ schema = Nokogiri::XML::Schema.new(IO.read(xsd_path))
34
+ errors = schema.validate(document)
35
+ assert errors.empty?, errors.collect{|e| e.message }.join
36
+ end
37
+
38
+ context "a Notice turned into XML" do
39
+ setup do
40
+ Airbrake.configure do |config|
41
+ config.api_key = "1234567890"
42
+ end
43
+
44
+ @exception = build_exception
45
+
46
+ @notice = build_notice({
47
+ :notifier_name => 'a name',
48
+ :notifier_version => '1.2.3',
49
+ :notifier_url => 'http://some.url/path',
50
+ :exception => @exception,
51
+ :controller => "controller",
52
+ :action => "action",
53
+ :url => "http://url.com",
54
+ :parameters => { "paramskey" => "paramsvalue",
55
+ "nestparentkey" => { "nestkey" => "nestvalue" } },
56
+ :session_data => { "sessionkey" => "sessionvalue" },
57
+ :cgi_data => { "cgikey" => "cgivalue" },
58
+ :user_attributes => { "id" => 1234, "username" => "jsmith", "url" => "http://www.example.com/users/1234" },
59
+ :project_root => "RAILS_ROOT",
60
+ :environment_name => "RAILS_ENV"
61
+ })
62
+
63
+ @xml = @notice.to_xml
64
+
65
+ @document = Nokogiri::XML::Document.parse(@xml)
66
+ end
67
+
68
+ should "validate against the XML schema" do
69
+ assert_valid_notice_document @document
70
+ end
71
+
72
+ should "serialize a Notice to XML when sent #to_xml" do
73
+ assert_valid_node(@document, "//api-key", @notice.api_key)
74
+
75
+ assert_valid_node(@document, "//notifier/name", @notice.notifier_name)
76
+ assert_valid_node(@document, "//notifier/version", @notice.notifier_version)
77
+ assert_valid_node(@document, "//notifier/url", @notice.notifier_url)
78
+
79
+ assert_valid_node(@document, "//error/class", @notice.error_class)
80
+ assert_valid_node(@document, "//error/message", @notice.error_message)
81
+
82
+ assert_valid_node(@document, "//error/backtrace/line/@number", @notice.backtrace.lines.first.number)
83
+ assert_valid_node(@document, "//error/backtrace/line/@file", @notice.backtrace.lines.first.file)
84
+ assert_valid_node(@document, "//error/backtrace/line/@method", @notice.backtrace.lines.first.method)
85
+
86
+ assert_valid_node(@document, "//request/url", @notice.url)
87
+ assert_valid_node(@document, "//request/component", @notice.controller)
88
+ assert_valid_node(@document, "//request/action", @notice.action)
89
+
90
+ assert_valid_node(@document, "//request/params/var/@key", "paramskey")
91
+ assert_valid_node(@document, "//request/params/var", "paramsvalue")
92
+ assert_valid_node(@document, "//request/params/var/@key", "nestparentkey")
93
+ assert_valid_node(@document, "//request/params/var/var/@key", "nestkey")
94
+ assert_valid_node(@document, "//request/params/var/var", "nestvalue")
95
+ assert_valid_node(@document, "//request/session/var/@key", "sessionkey")
96
+ assert_valid_node(@document, "//request/session/var", "sessionvalue")
97
+ assert_valid_node(@document, "//request/cgi-data/var/@key", "cgikey")
98
+ assert_valid_node(@document, "//request/cgi-data/var", "cgivalue")
99
+
100
+ assert_valid_node(@document, "//server-environment/project-root", "RAILS_ROOT")
101
+ assert_valid_node(@document, "//server-environment/environment-name", "RAILS_ENV")
102
+ assert_valid_node(@document, "//server-environment/hostname", hostname)
103
+
104
+ assert_valid_node(@document, "//user-attributes/var/@key", "id")
105
+ assert_valid_node(@document, "//user-attributes/var", "1234")
106
+ assert_valid_node(@document, "//user-attributes/var/@key", "username")
107
+ assert_valid_node(@document, "//user-attributes/var", "jsmith")
108
+ assert_valid_node(@document, "//user-attributes/var/@key", "url")
109
+ assert_valid_node(@document, "//user-attributes/var", "http://www.example.com/users/1234")
110
+ end
111
+ end
112
+
113
+ should "not send empty request data" do
114
+ notice = build_notice
115
+ assert_nil notice.url
116
+ assert_nil notice.controller
117
+ assert_nil notice.action
118
+ assert_empty notice.user_attributes
119
+
120
+ xml = notice.to_xml
121
+ document = Nokogiri::XML.parse(xml)
122
+ assert_nil document.at('//request/url')
123
+ assert_nil document.at('//request/component')
124
+ assert_nil document.at('//request/action')
125
+ assert_nil document.at('//user-attributes')
126
+
127
+ assert_valid_notice_document document
128
+ end
129
+
130
+
131
+ end
metadata ADDED
@@ -0,0 +1,222 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: airbrake_user_attributes
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Nathan Broadbent
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: actionpack
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.3.8
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 2.3.8
30
+ - !ruby/object:Gem::Dependency
31
+ name: activerecord
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 2.3.8
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 2.3.8
46
+ - !ruby/object:Gem::Dependency
47
+ name: activesupport
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 2.3.8
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 2.3.8
62
+ - !ruby/object:Gem::Dependency
63
+ name: bourne
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '1.0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '1.0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: fakeweb
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: 1.3.0
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 1.3.0
94
+ - !ruby/object:Gem::Dependency
95
+ name: nokogiri
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: 1.4.3.1
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: 1.4.3.1
110
+ - !ruby/object:Gem::Dependency
111
+ name: rspec
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: 2.6.0
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: 2.6.0
126
+ - !ruby/object:Gem::Dependency
127
+ name: sham_rack
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ~>
132
+ - !ruby/object:Gem::Version
133
+ version: 1.3.0
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ~>
140
+ - !ruby/object:Gem::Version
141
+ version: 1.3.0
142
+ - !ruby/object:Gem::Dependency
143
+ name: shoulda
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ~>
148
+ - !ruby/object:Gem::Version
149
+ version: 2.11.3
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ~>
156
+ - !ruby/object:Gem::Version
157
+ version: 2.11.3
158
+ - !ruby/object:Gem::Dependency
159
+ name: airbrake
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ! '>='
164
+ - !ruby/object:Gem::Version
165
+ version: 3.0.9
166
+ type: :runtime
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ! '>='
172
+ - !ruby/object:Gem::Version
173
+ version: 3.0.9
174
+ description: Adds information about the current user to error reports
175
+ email: nathan.f77@gmail.com
176
+ executables: []
177
+ extensions: []
178
+ extra_rdoc_files: []
179
+ files:
180
+ - .gitignore
181
+ - Gemfile
182
+ - README.md
183
+ - Rakefile
184
+ - airbrake_user_attributes.gemspec
185
+ - lib/airbrake_overrides/notice.rb
186
+ - lib/airbrake_overrides/rails/controller_methods.rb
187
+ - lib/airbrake_user_attributes.rb
188
+ - lib/airbrake_user_attributes/version.rb
189
+ - test/airbrake_2_2.xsd
190
+ - test/helper.rb
191
+ - test/notice_test.rb
192
+ homepage: http://cloudfuji.com
193
+ licenses: []
194
+ post_install_message:
195
+ rdoc_options: []
196
+ require_paths:
197
+ - lib
198
+ required_ruby_version: !ruby/object:Gem::Requirement
199
+ none: false
200
+ requirements:
201
+ - - ! '>='
202
+ - !ruby/object:Gem::Version
203
+ version: '0'
204
+ segments:
205
+ - 0
206
+ hash: 311172291318117201
207
+ required_rubygems_version: !ruby/object:Gem::Requirement
208
+ none: false
209
+ requirements:
210
+ - - ! '>='
211
+ - !ruby/object:Gem::Version
212
+ version: '0'
213
+ segments:
214
+ - 0
215
+ hash: 311172291318117201
216
+ requirements: []
217
+ rubyforge_project:
218
+ rubygems_version: 1.8.24
219
+ signing_key:
220
+ specification_version: 3
221
+ summary: Send Airbrake notifications with user attributes
222
+ test_files: []