safety_goggles 2.1.1

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