safety_goggles 2.1.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,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2ec032ed55d989245c79a5f98fc0cc27c0a6043c243aa188bd0b45cbb295ab30
4
+ data.tar.gz: d72e853e0e1a2267ed597c7f90b9eb08672a1c85d9932158145f3543e6048ac7
5
+ SHA512:
6
+ metadata.gz: a4129ce1067e1bdeeb674df2d23a4cfeb9473c14364ba3024027895fecd907781397b04dbd31fc956fefc934c7db5095678d0543fe56b4bc939de653db2c35f2
7
+ data.tar.gz: b017b7d621ef2456cafec1c21956d68569d483c7d87ec96de2a7c83fec266ae8a36bdac0de2adac7907f08750787ca936479e7e9b5c1e7a2c73a170b8ae59d15
@@ -0,0 +1,23 @@
1
+ # EditorConfig is awesome: http://EditorConfig.org
2
+
3
+ # top-most EditorConfig file
4
+ root = true
5
+
6
+ # Unix-style newlines with a newline ending every file
7
+ [*]
8
+ charset = utf-8
9
+ indent_size = 2
10
+ indent_style = space
11
+ tab_width = 2
12
+
13
+ end_of_line = lf # Not supported in RubyMine
14
+ insert_final_newline = true # Not supported in RubyMine
15
+ trim_trailing_whitespace = true # Not supported in RubyMine
16
+
17
+ [Makefile]
18
+ indent_style = tab
19
+ indent_size = 8
20
+
21
+ [*.{py,js,css}]
22
+ indent_size = 4
23
+ tab_width = 4
@@ -0,0 +1,100 @@
1
+ .byebug_history
2
+ certs/
3
+ deploy/production/production.yml
4
+ deploy/staging/staging.yml
5
+ development/
6
+ .DS_Store
7
+ .env
8
+ *.gem
9
+ .idea/
10
+ pkg/
11
+ production.secret.env
12
+ .ruby-env
13
+ staging.secret.env
14
+ .ruby-version
15
+
16
+ # Created by https://www.gitignore.io/api/rails,rubymine
17
+
18
+ ### Rails ###
19
+ *.rbc
20
+ capybara-*.html
21
+ /log
22
+ /tmp
23
+ /db/*.sqlite3
24
+ /db/*.sqlite3-journal
25
+ /public/system
26
+ /coverage/
27
+ /spec/tmp
28
+ **.orig
29
+ rerun.txt
30
+ pickle-email-*.html
31
+
32
+
33
+ ## Environment normalization:
34
+ /.bundle
35
+ /vendor/bundle
36
+
37
+ # these should all be checked in to normalize the environment:
38
+ # Gemfile.lock, .ruby-version, .ruby-gemset
39
+
40
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
41
+ .rvmrc
42
+
43
+ # if using bower-rails ignore default bower_components path bower.json files
44
+ /vendor/assets/bower_components
45
+ *.bowerrc
46
+ bower.json
47
+
48
+ # Ignore pow environment settings
49
+ .powenv
50
+
51
+ # Ignore Byebug command history file.
52
+ .byebug_history
53
+
54
+
55
+ ### RubyMine ###
56
+ # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
57
+ # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
58
+
59
+ # User-specific stuff:
60
+ .idea/workspace.xml
61
+ .idea/tasks.xml
62
+ .idea/dictionaries
63
+ .idea/vcs.xml
64
+ .idea/jsLibraryMappings.xml
65
+
66
+ # Sensitive or high-churn files:
67
+ .idea/dataSources.ids
68
+ .idea/dataSources.xml
69
+ .idea/dataSources.local.xml
70
+ .idea/sqlDataSources.xml
71
+ .idea/dynamic.xml
72
+ .idea/uiDesigner.xml
73
+
74
+ # Gradle:
75
+ .idea/gradle.xml
76
+ .idea/libraries
77
+
78
+ # Mongo Explorer plugin:
79
+ .idea/mongoSettings.xml
80
+
81
+ ## File-based project format:
82
+ *.iws
83
+
84
+ ## Plugin-specific files:
85
+
86
+ # IntelliJ
87
+ /out/
88
+
89
+ # mpeltonen/sbt-idea plugin
90
+ .idea_modules/
91
+
92
+ # JIRA plugin
93
+ atlassian-ide-plugin.xml
94
+
95
+ # Crashlytics plugin (for Android Studio and IntelliJ)
96
+ com_crashlytics_export_strings.xml
97
+ crashlytics.properties
98
+ crashlytics-build.properties
99
+ fabric.properties
100
+
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1,90 @@
1
+ # inherit_from: ../.rubocop.yml
2
+
3
+ # Common configuration.
4
+ AllCops:
5
+ # Include gemspec and Rakefile
6
+ Include:
7
+ - '**/Gemfile'
8
+ - '**/Rakefile'
9
+ - '**/*.gemspec'
10
+ - '**/*.jbuilder'
11
+ - '**/*.rb'
12
+ Exclude:
13
+ - 'bin/bundle'
14
+ - 'bin/rails'
15
+ - 'bin/rake'
16
+ - 'bin/setup'
17
+ - 'bin/spring'
18
+ - 'bin/update'
19
+ - 'config.ru'
20
+ - 'config/application.rb'
21
+ - 'config/boot.rb'
22
+ - 'config/environment.rb'
23
+ - 'db/migrate/**/*'
24
+ - 'db/schema.rb'
25
+ - 'secure_rails'
26
+ - 'test/**/*'
27
+ - 'tmp/**/*'
28
+ - 'vendor/**/*'
29
+
30
+ Rails:
31
+ Enabled: true
32
+
33
+ # # Not compatible with Rails < 4
34
+ # ActionFilter:
35
+ # Enabled: false
36
+
37
+ AlignParameters:
38
+ EnforcedStyle: with_fixed_indentation
39
+
40
+ ClassLength:
41
+ Max: 300
42
+
43
+ Encoding:
44
+ Enabled: false
45
+
46
+ IndentHash:
47
+ EnforcedStyle: consistent
48
+
49
+ HasAndBelongsToMany:
50
+ Enabled: false
51
+
52
+ Layout/AlignHash:
53
+ # Alignment of entries using colon as separator. Valid values are:
54
+ #
55
+ # key - left alignment of keys
56
+ # a: 0
57
+ # bb: 1
58
+ # separator - alignment of colons, keys are right aligned
59
+ # a: 0
60
+ # bb: 1
61
+ # table - left alignment of keys and values
62
+ # a: 0
63
+ # bb: 1
64
+ EnforcedColonStyle: table
65
+
66
+ Layout/SpaceBeforeFirstArg:
67
+ Enabled: false
68
+
69
+ LineLength:
70
+ Max: 120
71
+
72
+ # Default 10
73
+ MethodLength:
74
+ Max: 30
75
+
76
+ # Default 15
77
+ Metrics/AbcSize:
78
+ Max: 30
79
+
80
+ StringLiterals:
81
+ EnforcedStyle: double_quotes
82
+
83
+ Style/AsciiComments:
84
+ Enabled: false
85
+
86
+ Style/Documentation:
87
+ Enabled: false
88
+
89
+ Style/CommandLiteral:
90
+ EnforcedStyle: percent_x
@@ -0,0 +1,32 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ rvm:
5
+ - 2.3.7
6
+
7
+ cache:
8
+ # - apt
9
+ - bundler
10
+
11
+ before_install:
12
+ - gem install bundler -v 1.16.2
13
+ - gem install bundler-audit -v 0.6.0
14
+
15
+ # We don't want deployment mode
16
+ # It gets confusing when the gem we're building is part of the Gemfile.lock
17
+ install: bundle install --jobs=3 --retry=3 --path vendor/bundle
18
+
19
+ script:
20
+ - bundle audit --update
21
+ - bundle exec rubocop -D Gemfile safety_goggles.gemspec lib/
22
+ - bundle exec rake spec
23
+
24
+ deploy:
25
+ provider: script
26
+ script: ci/push.sh
27
+ on:
28
+ tags: true
29
+
30
+ notifications:
31
+ slack:
32
+ secure: "IEvcFxI8CddcjTjRPQYlh4SSyedYV55RRRyFBfuT9bpb0WRdmsOfsdyzCyJ2LjcqKlJ9IJIXd2oS9RQniSLgoc77KRyFhyX3ZnYr/v+d2Dk/IVWF7gDyMZ1UaYMhmnyXgX3SrUnu3uL5ID3KjsfQh5C7fATlj+M6k1qBLrpSJ8Q2rSkDEGOdtLKNAPp/eamXXizZcNUXmLXqqKhtOB8hvAtzVaXNxypfSkYQu9YpqS8GWwnK9EWgjMw0axPJ80iE9wlXDcOax5DdROfhbz9E8NZjaCSjadqPij3OebINI0ToRYlCvtjOQ32nx3av1rJV5rZ33/vn2Uq15RBOW/dkTI4ilQ+6ymlKVuDs+PsLzpYXmkT2XZJo+KXENUc+1MYxhpewmtio/KpV/1ecbtpzWFeFM/beLmrASePoKOgiNvH66b+ifSP4sQsFBZMhccF5px6+kiW3i8A1jY3mEyO9Ubh0jRl4bRdhaMqS5CqM5B7Vs86xiWoZqF+XEE4CPTT5oKTWptLEdXKTkJHkOLHohjjYKu2YT41Bm7jIng3CXD2Ej26bg65VHs78v/g/z5qimxrBgW1VgbUST+PpCyjb2CPNoAU++QgdstHX8Z4usPi2PpvP/zm+hGH4yCIDKvbSapGyC/aemlNQm2v7Pe+qNNFpqv/eVAn9YBS2kmMeNfA="
@@ -0,0 +1,72 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
6
+ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased][]
9
+
10
+ ## [2.1.1][] - 2018-07-13
11
+
12
+ ### Fixed
13
+
14
+ - Fixed loading the module.
15
+
16
+ ## [2.1.0][] - 2018-07-12
17
+
18
+ ### Added
19
+
20
+ - Added support for `Net::LDAP::Error` as a 422.
21
+
22
+ ## [2.0.10][] - 2017-09-05
23
+
24
+ ### Changed
25
+
26
+ - Removed ExceptionNotifier integration; just use Sentry
27
+ - Renamed `dswb-error_handler` to `safety_goggles`
28
+ - Renamed `Dswb:ErrorHandler` to `SafetyGoggles::Handler`
29
+ - Integrated with Travis CI and Artifactory
30
+ - Updated Ruby from `2.3.1` to `2.3.4`
31
+ - Only require relevant parts of Rails
32
+
33
+ ## [1.2.2][] - 2017-04-27
34
+
35
+ ### Changed
36
+
37
+ - Handle `ActiveRecord::RecordNotUnique` as a 422
38
+
39
+ ### Fixed
40
+
41
+ - Swap RecordNotFound and Unauthorized error definitions
42
+
43
+ ## 1.1.0 - 2017-03-09
44
+
45
+ ### Changed
46
+
47
+ - More resilience
48
+ - Handle `Dswb::RecordNotFoundError` as a 404
49
+
50
+ # 1.0.6
51
+
52
+ ### Changed
53
+
54
+ - Removed runtime dependency on Rails
55
+
56
+ # 1.0.3
57
+
58
+ ### Changed
59
+
60
+ - SecurityError is a 403
61
+
62
+ # 1.0.1
63
+
64
+ ### Changed
65
+
66
+ - Fix for environment check
67
+
68
+ [unreleased]: https://github.ibm.com/cognitive-class-labs/safety_goggles/compare/2.1.1...HEAD
69
+ [2.1.1]: https://github.ibm.com/cognitive-class-labs/safety_goggles/compare/2.1.0...2.1.1
70
+ [2.1.0]: https://github.ibm.com/cognitive-class-labs/safety_goggles/compare/2.0.10...2.1.0
71
+ [2.0.10]: https://github.ibm.com/cognitive-class-labs/safety_goggles/compare/v1.2.2...2.0.10
72
+ [1.2.2]: https://github.ibm.com/cognitive-class-labs/safety_goggles/compare/v1.1.0...v1.2.2
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,164 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ safety_goggles (2.1.1)
5
+ sentry-raven (~> 2.6)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ actionpack (5.2.0)
11
+ actionview (= 5.2.0)
12
+ activesupport (= 5.2.0)
13
+ rack (~> 2.0)
14
+ rack-test (>= 0.6.3)
15
+ rails-dom-testing (~> 2.0)
16
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
17
+ actionview (5.2.0)
18
+ activesupport (= 5.2.0)
19
+ builder (~> 3.1)
20
+ erubi (~> 1.4)
21
+ rails-dom-testing (~> 2.0)
22
+ rails-html-sanitizer (~> 1.0, >= 1.0.3)
23
+ activemodel (5.2.0)
24
+ activesupport (= 5.2.0)
25
+ activerecord (5.2.0)
26
+ activemodel (= 5.2.0)
27
+ activesupport (= 5.2.0)
28
+ arel (>= 9.0)
29
+ activesupport (5.2.0)
30
+ concurrent-ruby (~> 1.0, >= 1.0.2)
31
+ i18n (>= 0.7, < 2)
32
+ minitest (~> 5.1)
33
+ tzinfo (~> 1.1)
34
+ addressable (2.4.0)
35
+ arel (9.0.0)
36
+ ast (2.4.0)
37
+ backports (3.11.3)
38
+ builder (3.2.3)
39
+ bundler-audit (0.6.0)
40
+ bundler (~> 1.2)
41
+ thor (~> 0.18)
42
+ concurrent-ruby (1.0.5)
43
+ crass (1.0.4)
44
+ diff-lcs (1.3)
45
+ docile (1.3.1)
46
+ erubi (1.7.1)
47
+ ethon (0.11.0)
48
+ ffi (>= 1.3.0)
49
+ faraday (0.15.2)
50
+ multipart-post (>= 1.2, < 3)
51
+ faraday_middleware (0.12.2)
52
+ faraday (>= 0.7.4, < 1.0)
53
+ ffi (1.9.25)
54
+ gh (0.15.1)
55
+ addressable (~> 2.4.0)
56
+ backports
57
+ faraday (~> 0.8)
58
+ multi_json (~> 1.0)
59
+ net-http-persistent (~> 2.9)
60
+ net-http-pipeline
61
+ highline (1.7.10)
62
+ i18n (1.0.1)
63
+ concurrent-ruby (~> 1.0)
64
+ jaro_winkler (1.5.1)
65
+ json (2.1.0)
66
+ launchy (2.4.3)
67
+ addressable (~> 2.3)
68
+ loofah (2.2.2)
69
+ crass (~> 1.0.2)
70
+ nokogiri (>= 1.5.9)
71
+ mini_portile2 (2.3.0)
72
+ minitest (5.11.3)
73
+ multi_json (1.13.1)
74
+ multipart-post (2.0.0)
75
+ net-http-persistent (2.9.4)
76
+ net-http-pipeline (1.0.1)
77
+ net-ldap (0.16.1)
78
+ nokogiri (1.8.4)
79
+ mini_portile2 (~> 2.3.0)
80
+ parallel (1.12.1)
81
+ parser (2.5.1.2)
82
+ ast (~> 2.4.0)
83
+ powerpack (0.1.2)
84
+ pusher-client (0.6.2)
85
+ json
86
+ websocket (~> 1.0)
87
+ rack (2.0.5)
88
+ rack-test (1.0.0)
89
+ rack (>= 1.0, < 3)
90
+ rails-dom-testing (2.0.3)
91
+ activesupport (>= 4.2.0)
92
+ nokogiri (>= 1.6)
93
+ rails-html-sanitizer (1.0.4)
94
+ loofah (~> 2.2, >= 2.2.2)
95
+ rainbow (3.0.0)
96
+ rake (12.3.1)
97
+ rspec (3.7.0)
98
+ rspec-core (~> 3.7.0)
99
+ rspec-expectations (~> 3.7.0)
100
+ rspec-mocks (~> 3.7.0)
101
+ rspec-core (3.7.1)
102
+ rspec-support (~> 3.7.0)
103
+ rspec-expectations (3.7.0)
104
+ diff-lcs (>= 1.2.0, < 2.0)
105
+ rspec-support (~> 3.7.0)
106
+ rspec-mocks (3.7.0)
107
+ diff-lcs (>= 1.2.0, < 2.0)
108
+ rspec-support (~> 3.7.0)
109
+ rspec-support (3.7.1)
110
+ rubocop (0.58.1)
111
+ jaro_winkler (~> 1.5.1)
112
+ parallel (~> 1.10)
113
+ parser (>= 2.5, != 2.5.1.1)
114
+ powerpack (~> 0.1)
115
+ rainbow (>= 2.2.2, < 4.0)
116
+ ruby-progressbar (~> 1.7)
117
+ unicode-display_width (~> 1.0, >= 1.0.1)
118
+ ruby-progressbar (1.9.0)
119
+ sentry-raven (2.7.4)
120
+ faraday (>= 0.7.6, < 1.0)
121
+ simplecov (0.16.1)
122
+ docile (~> 1.1)
123
+ json (>= 1.8, < 3)
124
+ simplecov-html (~> 0.10.0)
125
+ simplecov-html (0.10.2)
126
+ thor (0.20.0)
127
+ thread_safe (0.3.6)
128
+ travis (1.8.8)
129
+ backports
130
+ faraday (~> 0.9)
131
+ faraday_middleware (~> 0.9, >= 0.9.1)
132
+ gh (~> 0.13)
133
+ highline (~> 1.6)
134
+ launchy (~> 2.1)
135
+ pusher-client (~> 0.4)
136
+ typhoeus (~> 0.6, >= 0.6.8)
137
+ typhoeus (0.8.0)
138
+ ethon (>= 0.8.0)
139
+ tzinfo (1.2.5)
140
+ thread_safe (~> 0.1)
141
+ unicode-display_width (1.4.0)
142
+ websocket (1.2.8)
143
+
144
+ PLATFORMS
145
+ ruby
146
+
147
+ DEPENDENCIES
148
+ actionpack (~> 5.0, >= 5.0.2)
149
+ activemodel (~> 5.0, >= 5.0.2)
150
+ activerecord (~> 5.0, >= 5.0.2)
151
+ bundler-audit (~> 0.6)
152
+ loofah (~> 2.2, >= 2.2.1)
153
+ net-ldap (~> 0.16)
154
+ nokogiri (~> 1.8, >= 1.8.3)
155
+ rails-html-sanitizer (~> 1.0, >= 1.0.4)
156
+ rake (~> 12.0)
157
+ rspec (~> 3.4)
158
+ rubocop (~> 0.49)
159
+ safety_goggles!
160
+ simplecov (~> 0.11, >= 0.11.1)
161
+ travis (~> 1.8)
162
+
163
+ BUNDLED WITH
164
+ 1.16.2
@@ -0,0 +1,26 @@
1
+ .PHONY: build clean precommit publish spec
2
+
3
+ VERSION:=$(shell cat VERSION)
4
+
5
+ build: precommit tag
6
+ gem build *.gemspec
7
+ gem install *.gem --ignore-dependencies
8
+
9
+ clean:
10
+ rm *.gem
11
+
12
+ publish: build
13
+ gem inabox *.gem
14
+ make clean
15
+
16
+ precommit:
17
+ -@gem install geminabox
18
+ -rubocop -Da
19
+ -bundle
20
+ -bundle-audit check --update
21
+
22
+ spec:
23
+ bundle exec rspec
24
+
25
+ tag:
26
+ git tag -f v$(VERSION)
@@ -0,0 +1,73 @@
1
+ # Error Handler
2
+
3
+ This library wraps invocation of Sentry and exception notification for
4
+ convenience.
5
+
6
+ You still need to configure Sentry and ExceptionNotification gems
7
+ separately. This gem is for invocation, not configuration.
8
+
9
+ ## Installation
10
+
11
+ ```ruby
12
+ source "https://na.artifactory.swg-devops.com/artifactory/api/gems/apset-ruby" do
13
+ # Report errors to Sentry
14
+ gem "safety_goggles", "~> 2.0"
15
+ end
16
+ ```
17
+
18
+ ## Sample Usage
19
+
20
+ In a controller such as `application_controller.rb`:
21
+
22
+ ```ruby
23
+ rescue_from Exception, with: :render_error
24
+
25
+ def render_error(error)
26
+ require "safety_goggles"
27
+ code = SafetyGoggles::Handler.handle_error(error)
28
+
29
+ render status: code, json: { code: code, message: error.to_s }
30
+ end
31
+ ```
32
+
33
+ If you'd like to configure HTTP Basic Auth to throw exceptions and trigger
34
+ the above code path, you can do this in the controller:
35
+
36
+ ```ruby
37
+ include ActionController::HttpAuthentication::Basic::ControllerMethods
38
+
39
+ MY_USERNAME = ENV.fetch("MY_USERNAME")
40
+ MY_PASSWORD = ENV.fetch("MY_PASSWORD")
41
+
42
+ before_action do
43
+ success = authenticate_with_http_basic do |name, password|
44
+ # This comparison uses & so that it doesn't short circuit and
45
+ # uses `variable_size_secure_compare` so that length information
46
+ # isn't leaked.
47
+ ActiveSupport::SecurityUtils.variable_size_secure_compare(name, MY_USERNAME) &
48
+ ActiveSupport::SecurityUtils.variable_size_secure_compare(password, MY_PASSWORD)
49
+ end
50
+
51
+ require "safety_goggles/unauthorized_error"
52
+ raise SafetyGoggles::UnauthorizedError, "HTTP Basic: Access denied." unless success
53
+
54
+ success
55
+ end
56
+ ```
57
+
58
+ ## Build as a Gem
59
+
60
+ - Travis CI will build and publish a new version of the gem
61
+ whenever you push a new tag:
62
+
63
+ ```
64
+ git tag -a 2.0.0 -m v2.0.0 && git push --tags
65
+ ```
66
+
67
+ - Should the need arise, you can install a local version as
68
+ follows:
69
+
70
+ ```
71
+ gem build *.gemspec
72
+ gem install *.gem --ignore-dependencies
73
+ ```
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 2.1.1
@@ -0,0 +1,21 @@
1
+ # CI
2
+
3
+
4
+ The following commands were used to configure CI with Travis (one-time setup).
5
+
6
+ ```shell
7
+ travis env set ART_URL <...>
8
+ travis env set ART_USERNAME <...>
9
+ travis env set ART_API_KEY <...>
10
+ ```
11
+
12
+ Note: If your username has an `@`, change it to `%40`
13
+
14
+ You can also set these values through the Travis web gui
15
+
16
+ The value for `notifications/slack/secure` is obtained by running the following
17
+ command.
18
+
19
+ ```sh
20
+ travis encrypt "<SLACK_TEAM_SUB_DOMAIN>:<SLACK_TOKEN>" --add notifications.slack
21
+ ```
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Exit immediately if a command exits with a non-zero status.
4
+ set -e
5
+
6
+ echo "Clean the environment"
7
+ rm -f *.gem
8
+
9
+ echo "Building gem"
10
+ gem build *.gemspec
11
+
12
+ # Log into Artifactory
13
+ echo "Getting repository api key"
14
+ curl -fsu "${ART_USERNAME:?}:${ART_API_KEY:?}" "${ART_URL:?}/api/v1/api_key.yaml" >> ~/.gem/credentials
15
+
16
+ echo "Setting credential permissions"
17
+ chmod 0600 ~/.gem/credentials
18
+
19
+ echo "Publishing gem"
20
+ gem push *.gem --host "$ART_URL"
21
+
22
+ echo "Gem published"
@@ -0,0 +1,3 @@
1
+ require "safety_goggles/handler"
2
+ require "safety_goggles/unauthorized_error"
3
+ require "safety_goggles/record_not_found_error"
@@ -0,0 +1,72 @@
1
+ module SafetyGoggles
2
+ class Handler
3
+ ERROR_CODES = {
4
+ "ActionController::ParameterMissing" => 422,
5
+ "ActionController::UnpermittedParameters" => 422,
6
+ "ActiveModel::ValidationError" => 422,
7
+ "ActiveRecord::RecordInvalid" => 422,
8
+ "ActiveRecord::RecordNotFound" => 404,
9
+ "ActiveRecord::RecordNotUnique" => 422,
10
+ "ArgumentError" => 422,
11
+ "Net::LDAP::Error" => 422,
12
+ "SafetyGoggles::RecordNotFoundError" => 404,
13
+ "SafetyGoggles::UnauthorizedError" => 401,
14
+ "SecurityError" => 403
15
+ }.freeze
16
+
17
+ SEVERITIES = {
18
+ 500 => "fatal",
19
+ 401 => "error",
20
+ 403 => "error"
21
+ }.freeze
22
+
23
+ def self.handle_error(error, env = Handler.guess_env)
24
+ logger.debug("::handle_error called with #{error}, #{env}")
25
+ code = ERROR_CODES.fetch(error.class.to_s, 500) if code.nil?
26
+
27
+ logger.error("ERROR: #{code} \n#{error.class} \n#{error}")
28
+ logger.error(get_backtrace(error).join("\n"))
29
+
30
+ handle_serious_error(error, code, env) if serious_env?
31
+
32
+ code
33
+ end
34
+
35
+ # :nocov:
36
+ def self.handle_serious_error(error, code, env)
37
+ logger.debug("::handle_serious_error called with #{error}, #{code}, #{env}")
38
+ severity = SEVERITIES.fetch(code, "warning")
39
+
40
+ Raven.capture_exception(error,
41
+ extra: { nice_backtrace: get_backtrace(error) },
42
+ level: severity,
43
+ tags: { code: code, class: error.class })
44
+ end
45
+ # :nocov:
46
+
47
+ def self.serious_env?
48
+ return false unless defined?(Rails)
49
+ # :nocov:
50
+ # rubocop:disable Rails/UnknownEnv
51
+ Rails.env.production? || Rails.env.staging?
52
+ # rubocop:enable Rails/UnknownEnv
53
+ # :nocov:
54
+ end
55
+
56
+ def self.get_backtrace(error)
57
+ return [] unless error.respond_to?(:backtrace)
58
+ return [] if error.backtrace.nil?
59
+ error.backtrace.reject { |line| %r{/gems/}.match(line).present? }
60
+ end
61
+
62
+ def self.logger
63
+ return Rails.logger if defined?(Rails) && Rails.respond_to?(:logger) && Rails.logger.present?
64
+ Logger.new(STDOUT)
65
+ end
66
+
67
+ def self.guess_env
68
+ return Rails.env if defined?(Rails) && Rails.respond_to?(:env)
69
+ "development"
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,4 @@
1
+ module SafetyGoggles
2
+ class RecordNotFoundError < StandardError
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module SafetyGoggles
2
+ class UnauthorizedError < StandardError
3
+ end
4
+ end
@@ -0,0 +1,62 @@
1
+ # coding: utf-8
2
+
3
+ lib = File.expand_path("lib", __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ # rubocop:disable Metrics/BlockLength
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "safety_goggles"
9
+ spec.version = File.open("VERSION", "r").read.strip
10
+ spec.authors = ["Leons Petrazickis"]
11
+ spec.email = ["leonsp@ca.ibm.com"]
12
+ spec.summary = "Rails error handler"
13
+ spec.description = "Rails error handler that integrates with Sentry and generates 4xx error responses"
14
+ spec.homepage = "http://cognitiveclass.ai"
15
+ spec.license = "Nonstandard"
16
+
17
+ # TODO: Remove dependency on git.
18
+ spec.files = %x(git ls-files).split($INPUT_RECORD_SEPARATOR)
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
+ spec.require_paths = ["lib"]
22
+
23
+ # Install geminabox on the system but don't include it here
24
+ # so that Sinatra doesn't conflict with Rails5 stuff
25
+
26
+ # Force dependency update because of vulnerabilities
27
+ spec.add_development_dependency "loofah", "~> 2.2", ">= 2.2.1"
28
+ spec.add_development_dependency "nokogiri", "~> 1.8", ">= 1.8.3"
29
+ spec.add_development_dependency "rails-html-sanitizer", "~> 1.0", ">= 1.0.4"
30
+
31
+ # ActionController, ActiveRecord, and ActiveModel error definitions
32
+ spec.add_development_dependency "actionpack", "~> 5.0", ">= 5.0.2"
33
+ spec.add_development_dependency "activemodel", "~> 5.0", ">= 5.0.2"
34
+ spec.add_development_dependency "activerecord", "~> 5.0", ">= 5.0.2"
35
+
36
+ spec.add_development_dependency "bundler-audit", "~> 0.6"
37
+
38
+ # LDAP errors
39
+ spec.add_development_dependency "net-ldap", "~> 0.16"
40
+
41
+ # To install the gem locally:
42
+ # bundle exec rake install
43
+ spec.add_development_dependency "rake", "~> 12.0"
44
+
45
+ # Unit tests
46
+ spec.add_development_dependency "rspec", "~> 3.4"
47
+
48
+ # Test coverage report
49
+ spec.add_development_dependency "simplecov", "~> 0.11", ">= 0.11.1"
50
+
51
+ # Continuous Integration
52
+ spec.add_development_dependency "travis", "~> 1.8"
53
+
54
+ # Automatic Ruby code style checking tool. Aims to enforce the community-driven
55
+ # Ruby Style Guide.
56
+ # https://github.com/bbatsov/rubocop
57
+ spec.add_development_dependency "rubocop", "~> 0.49"
58
+
59
+ # Also send stacktraces
60
+ spec.add_runtime_dependency "sentry-raven", "~> 2.6"
61
+ end
62
+ # rubocop:enable Metrics/BlockLength
@@ -0,0 +1,79 @@
1
+ require "action_controller"
2
+ require "active_model"
3
+ require "active_model/validations"
4
+ require "active_model/validator"
5
+ require "active_record"
6
+
7
+ require "net/ldap"
8
+
9
+ require "safety_goggles/handler"
10
+ require "safety_goggles/record_not_found_error"
11
+ require "safety_goggles/unauthorized_error"
12
+
13
+ # rubocop:disable Metrics/BlockLength
14
+ RSpec.describe(SafetyGoggles::Handler) do
15
+ describe :handle_error do
16
+ it "doesn't throw any errors" do
17
+ begin
18
+ raise SafetyGoggles::UnauthorizedError, "Just testing"
19
+ rescue StandardError => error
20
+ expect { SafetyGoggles::Handler.handle_error(error) }.not_to raise_error
21
+ end
22
+ end
23
+
24
+ ERROR_CODES = {
25
+ ActionController::ParameterMissing => 422,
26
+ ActionController::UnpermittedParameters => 422,
27
+ ActiveModel::ValidationError => 422,
28
+ ActiveRecord::RecordInvalid => 422,
29
+ ActiveRecord::RecordNotFound => 404,
30
+ ActiveRecord::RecordNotUnique => 422,
31
+ ArgumentError => 422,
32
+ SafetyGoggles::RecordNotFoundError => 404,
33
+ SafetyGoggles::UnauthorizedError => 401,
34
+ SecurityError => 403
35
+ }.freeze
36
+
37
+ it "handles 401s" do
38
+ expect(SafetyGoggles::Handler.handle_error(SafetyGoggles::UnauthorizedError.new("Hi"))).to eq(401)
39
+ end
40
+
41
+ it "handles 403s" do
42
+ expect(SafetyGoggles::Handler.handle_error(SecurityError.new("Hi"))).to eq(403)
43
+ end
44
+
45
+ it "handles 404s" do
46
+ expect(SafetyGoggles::Handler.handle_error(ActiveRecord::RecordNotFound.new("Hi"))).to eq(404)
47
+ expect(SafetyGoggles::Handler.handle_error(SafetyGoggles::RecordNotFoundError.new("Hi"))).to eq(404)
48
+ end
49
+
50
+ it "handles 422s" do
51
+ expect(SafetyGoggles::Handler.handle_error(ActionController::ParameterMissing.new("Hi"))).to eq(422)
52
+ expect(SafetyGoggles::Handler.handle_error(ActiveRecord::RecordNotUnique.new("Hi"))).to eq(422)
53
+ expect(SafetyGoggles::Handler.handle_error(ActionController::UnpermittedParameters.new(["Hi"]))).to eq(422)
54
+ expect(SafetyGoggles::Handler.handle_error(ArgumentError.new("Hi"))).to eq(422)
55
+ expect(SafetyGoggles::Handler.handle_error(Net::LDAP::Error.new("Hi"))).to eq(422)
56
+ end
57
+
58
+ it "handles 422s with ActiveModel" do
59
+ model = double("model")
60
+ allow(model).to receive_message_chain(:errors, :full_messages) { [] }
61
+ allow(model).to receive_message_chain(:class, :i18n_scope) { "" }
62
+
63
+ # TODO: Figure out how to fake one of these
64
+ expect(SafetyGoggles::Handler.handle_error(ActiveModel::ValidationError.new(model))).to eq(422)
65
+ expect(SafetyGoggles::Handler.handle_error(ActiveRecord::RecordInvalid.new(model))).to eq(422)
66
+ end
67
+
68
+ it "handles 500s" do
69
+ expect(SafetyGoggles::Handler.handle_error(StandardError.new("Hi"))).to eq(500)
70
+ end
71
+ end
72
+
73
+ describe :serious_env? do
74
+ it "takes url as a parameter" do
75
+ expect([true, false]).to include(SafetyGoggles::Handler.serious_env?)
76
+ end
77
+ end
78
+ end
79
+ # rubocop:enable Metrics/BlockLength
@@ -0,0 +1,11 @@
1
+ require "safety_goggles/record_not_found_error"
2
+
3
+ RSpec.describe(SafetyGoggles::RecordNotFoundError) do
4
+ describe :new do
5
+ it "can be thrown" do
6
+ expect { raise SafetyGoggles::RecordNotFoundError, "This is an error" }.to(
7
+ raise_error(SafetyGoggles::RecordNotFoundError)
8
+ )
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require "safety_goggles/unauthorized_error"
2
+
3
+ RSpec.describe(SafetyGoggles::UnauthorizedError) do
4
+ describe :new do
5
+ it "can be thrown" do
6
+ expect { raise SafetyGoggles::UnauthorizedError, "This is an error" }.to(
7
+ raise_error(SafetyGoggles::UnauthorizedError)
8
+ )
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,88 @@
1
+ require "simplecov"
2
+ SimpleCov.start do
3
+ add_filter "/spec/"
4
+ end
5
+
6
+ # This file was generated by the `rails generate rspec:install` command. Conventionally, all
7
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
8
+ # The generated `.rspec` file contains `--require spec_helper` which will cause this
9
+ # file to always be loaded, without a need to explicitly require it in any files.
10
+ #
11
+ # Given that it is always loaded, you are encouraged to keep this file as
12
+ # light-weight as possible. Requiring heavyweight dependencies from this file
13
+ # will add to the boot time of your test suite on EVERY test run, even for an
14
+ # individual file that may not need all of that loaded. Instead, consider making
15
+ # a separate helper file that requires the additional dependencies and performs
16
+ # the additional setup, and require it from the spec files that actually need it.
17
+ #
18
+ # The `.rspec` file also contains a few flags that are not defaults but that
19
+ # users commonly want.
20
+ #
21
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
22
+ RSpec.configure do |config|
23
+ # rspec-expectations config goes here. You can use an alternate
24
+ # assertion/expectation library such as wrong or the stdlib/minitest
25
+ # assertions if you prefer.
26
+ config.expect_with :rspec do |expectations|
27
+ # This option will default to `true` in RSpec 4. It makes the `description`
28
+ # and `failure_message` of custom matchers include text for helper methods
29
+ # defined using `chain`, e.g.:
30
+ # be_bigger_than(2).and_smaller_than(4).description
31
+ # # => "be bigger than 2 and smaller than 4"
32
+ # ...rather than:
33
+ # # => "be bigger than 2"
34
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
35
+ end
36
+
37
+ # rspec-mocks config goes here. You can use an alternate test double
38
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
39
+ config.mock_with :rspec do |mocks|
40
+ # Prevents you from mocking or stubbing a method that does not exist on
41
+ # a real object. This is generally recommended, and will default to
42
+ # `true` in RSpec 4.
43
+ mocks.verify_partial_doubles = true
44
+ end
45
+
46
+ # The settings below are suggested to provide a good initial experience
47
+ # with RSpec, but feel free to customize to your heart's content.
48
+ # # These two settings work together to allow you to limit a spec run
49
+ # # to individual examples or groups you care about by tagging them with
50
+ # # `:focus` metadata. When nothing is tagged with `:focus`, all examples
51
+ # # get run.
52
+ # config.filter_run :focus
53
+ # config.run_all_when_everything_filtered = true
54
+ #
55
+ # # Limits the available syntax to the non-monkey patched syntax that is recommended.
56
+ # # For more details, see:
57
+ # # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
58
+ # # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
59
+ # # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
60
+ # config.disable_monkey_patching!
61
+ #
62
+ # # Many RSpec users commonly either run the entire suite or an individual
63
+ # # file, and it's useful to allow more verbose output when running an
64
+ # # individual spec file.
65
+ # if config.files_to_run.one?
66
+ # # Use the documentation formatter for detailed output,
67
+ # # unless a formatter has already been configured
68
+ # # (e.g. via a command-line flag).
69
+ # config.default_formatter = 'doc'
70
+ # end
71
+ #
72
+ # # Print the 10 slowest examples and example groups at the
73
+ # # end of the spec run, to help surface which specs are running
74
+ # # particularly slow.
75
+ # config.profile_examples = 10
76
+ #
77
+ # # Run specs in random order to surface order dependencies. If you find an
78
+ # # order dependency and want to debug it, you can fix the order by providing
79
+ # # the seed, which is printed after each run.
80
+ # # --seed 1234
81
+ # config.order = :random
82
+ #
83
+ # # Seed global randomization in this process using the `--seed` CLI option.
84
+ # # Setting this allows you to use `--seed` to deterministically reproduce
85
+ # # test failures related to randomization by passing the same `--seed` value
86
+ # # as the one that triggered the failure.
87
+ # Kernel.srand config.seed
88
+ end
metadata ADDED
@@ -0,0 +1,310 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: safety_goggles
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Leons Petrazickis
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-07-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: loofah
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.2'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 2.2.1
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '2.2'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 2.2.1
33
+ - !ruby/object:Gem::Dependency
34
+ name: nokogiri
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.8'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 1.8.3
43
+ type: :development
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '1.8'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 1.8.3
53
+ - !ruby/object:Gem::Dependency
54
+ name: rails-html-sanitizer
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '1.0'
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 1.0.4
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '1.0'
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 1.0.4
73
+ - !ruby/object:Gem::Dependency
74
+ name: actionpack
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: '5.0'
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 5.0.2
83
+ type: :development
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '5.0'
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 5.0.2
93
+ - !ruby/object:Gem::Dependency
94
+ name: activemodel
95
+ requirement: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - "~>"
98
+ - !ruby/object:Gem::Version
99
+ version: '5.0'
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: 5.0.2
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '5.0'
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: 5.0.2
113
+ - !ruby/object:Gem::Dependency
114
+ name: activerecord
115
+ requirement: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - "~>"
118
+ - !ruby/object:Gem::Version
119
+ version: '5.0'
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: 5.0.2
123
+ type: :development
124
+ prerelease: false
125
+ version_requirements: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - "~>"
128
+ - !ruby/object:Gem::Version
129
+ version: '5.0'
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: 5.0.2
133
+ - !ruby/object:Gem::Dependency
134
+ name: bundler-audit
135
+ requirement: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - "~>"
138
+ - !ruby/object:Gem::Version
139
+ version: '0.6'
140
+ type: :development
141
+ prerelease: false
142
+ version_requirements: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - "~>"
145
+ - !ruby/object:Gem::Version
146
+ version: '0.6'
147
+ - !ruby/object:Gem::Dependency
148
+ name: net-ldap
149
+ requirement: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - "~>"
152
+ - !ruby/object:Gem::Version
153
+ version: '0.16'
154
+ type: :development
155
+ prerelease: false
156
+ version_requirements: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - "~>"
159
+ - !ruby/object:Gem::Version
160
+ version: '0.16'
161
+ - !ruby/object:Gem::Dependency
162
+ name: rake
163
+ requirement: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - "~>"
166
+ - !ruby/object:Gem::Version
167
+ version: '12.0'
168
+ type: :development
169
+ prerelease: false
170
+ version_requirements: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - "~>"
173
+ - !ruby/object:Gem::Version
174
+ version: '12.0'
175
+ - !ruby/object:Gem::Dependency
176
+ name: rspec
177
+ requirement: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - "~>"
180
+ - !ruby/object:Gem::Version
181
+ version: '3.4'
182
+ type: :development
183
+ prerelease: false
184
+ version_requirements: !ruby/object:Gem::Requirement
185
+ requirements:
186
+ - - "~>"
187
+ - !ruby/object:Gem::Version
188
+ version: '3.4'
189
+ - !ruby/object:Gem::Dependency
190
+ name: simplecov
191
+ requirement: !ruby/object:Gem::Requirement
192
+ requirements:
193
+ - - "~>"
194
+ - !ruby/object:Gem::Version
195
+ version: '0.11'
196
+ - - ">="
197
+ - !ruby/object:Gem::Version
198
+ version: 0.11.1
199
+ type: :development
200
+ prerelease: false
201
+ version_requirements: !ruby/object:Gem::Requirement
202
+ requirements:
203
+ - - "~>"
204
+ - !ruby/object:Gem::Version
205
+ version: '0.11'
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: 0.11.1
209
+ - !ruby/object:Gem::Dependency
210
+ name: travis
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - "~>"
214
+ - !ruby/object:Gem::Version
215
+ version: '1.8'
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - "~>"
221
+ - !ruby/object:Gem::Version
222
+ version: '1.8'
223
+ - !ruby/object:Gem::Dependency
224
+ name: rubocop
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - "~>"
228
+ - !ruby/object:Gem::Version
229
+ version: '0.49'
230
+ type: :development
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - "~>"
235
+ - !ruby/object:Gem::Version
236
+ version: '0.49'
237
+ - !ruby/object:Gem::Dependency
238
+ name: sentry-raven
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - "~>"
242
+ - !ruby/object:Gem::Version
243
+ version: '2.6'
244
+ type: :runtime
245
+ prerelease: false
246
+ version_requirements: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - "~>"
249
+ - !ruby/object:Gem::Version
250
+ version: '2.6'
251
+ description: Rails error handler that integrates with Sentry and generates 4xx error
252
+ responses
253
+ email:
254
+ - leonsp@ca.ibm.com
255
+ executables: []
256
+ extensions: []
257
+ extra_rdoc_files: []
258
+ files:
259
+ - ".editorconfig"
260
+ - ".gitignore"
261
+ - ".rspec"
262
+ - ".rubocop.yml"
263
+ - ".travis.yml"
264
+ - CHANGELOG.md
265
+ - Gemfile
266
+ - Gemfile.lock
267
+ - Makefile
268
+ - README.md
269
+ - Rakefile
270
+ - VERSION
271
+ - ci/README.md
272
+ - ci/push.sh
273
+ - lib/safety_goggles.rb
274
+ - lib/safety_goggles/handler.rb
275
+ - lib/safety_goggles/record_not_found_error.rb
276
+ - lib/safety_goggles/unauthorized_error.rb
277
+ - safety_goggles.gemspec
278
+ - spec/lib/handler_spec.rb
279
+ - spec/lib/record_not_found_error_spec.rb
280
+ - spec/lib/unauthorized_error_spec.rb
281
+ - spec/spec_helper.rb
282
+ homepage: http://cognitiveclass.ai
283
+ licenses:
284
+ - Nonstandard
285
+ metadata: {}
286
+ post_install_message:
287
+ rdoc_options: []
288
+ require_paths:
289
+ - lib
290
+ required_ruby_version: !ruby/object:Gem::Requirement
291
+ requirements:
292
+ - - ">="
293
+ - !ruby/object:Gem::Version
294
+ version: '0'
295
+ required_rubygems_version: !ruby/object:Gem::Requirement
296
+ requirements:
297
+ - - ">="
298
+ - !ruby/object:Gem::Version
299
+ version: '0'
300
+ requirements: []
301
+ rubyforge_project:
302
+ rubygems_version: 2.7.6
303
+ signing_key:
304
+ specification_version: 4
305
+ summary: Rails error handler
306
+ test_files:
307
+ - spec/lib/handler_spec.rb
308
+ - spec/lib/record_not_found_error_spec.rb
309
+ - spec/lib/unauthorized_error_spec.rb
310
+ - spec/spec_helper.rb