g5_authenticatable_api 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +24 -0
  3. data/.rspec +2 -0
  4. data/CHANGELOG.md +18 -0
  5. data/Gemfile +38 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +286 -0
  8. data/Rakefile +1 -0
  9. data/circle.yml +4 -0
  10. data/g5_authenticatable_api.gemspec +23 -0
  11. data/lib/g5_authenticatable_api/helpers/grape.rb +27 -0
  12. data/lib/g5_authenticatable_api/helpers/rails.rb +26 -0
  13. data/lib/g5_authenticatable_api/railtie.rb +11 -0
  14. data/lib/g5_authenticatable_api/token_validator.rb +65 -0
  15. data/lib/g5_authenticatable_api/version.rb +3 -0
  16. data/lib/g5_authenticatable_api.rb +9 -0
  17. data/spec/dummy/README.rdoc +28 -0
  18. data/spec/dummy/Rakefile +6 -0
  19. data/spec/dummy/app/api/hello_api.rb +13 -0
  20. data/spec/dummy/app/assets/images/.keep +0 -0
  21. data/spec/dummy/app/assets/javascripts/application.js +16 -0
  22. data/spec/dummy/app/assets/javascripts/articles.js +2 -0
  23. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  24. data/spec/dummy/app/assets/stylesheets/articles.css +4 -0
  25. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  26. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  27. data/spec/dummy/app/controllers/rails_api/articles_controller.rb +11 -0
  28. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  29. data/spec/dummy/app/helpers/articles_helper.rb +2 -0
  30. data/spec/dummy/app/mailers/.keep +0 -0
  31. data/spec/dummy/app/models/.keep +0 -0
  32. data/spec/dummy/app/models/article.rb +2 -0
  33. data/spec/dummy/app/models/concerns/.keep +0 -0
  34. data/spec/dummy/app/models/user.rb +3 -0
  35. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  36. data/spec/dummy/bin/bundle +3 -0
  37. data/spec/dummy/bin/rails +4 -0
  38. data/spec/dummy/bin/rake +4 -0
  39. data/spec/dummy/config/application.rb +30 -0
  40. data/spec/dummy/config/boot.rb +10 -0
  41. data/spec/dummy/config/database.yml.ci +6 -0
  42. data/spec/dummy/config/database.yml.sample +50 -0
  43. data/spec/dummy/config/environment.rb +5 -0
  44. data/spec/dummy/config/environments/development.rb +29 -0
  45. data/spec/dummy/config/environments/production.rb +80 -0
  46. data/spec/dummy/config/environments/test.rb +36 -0
  47. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  48. data/spec/dummy/config/initializers/devise.rb +254 -0
  49. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  50. data/spec/dummy/config/initializers/inflections.rb +16 -0
  51. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  52. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  53. data/spec/dummy/config/initializers/session_store.rb +3 -0
  54. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  55. data/spec/dummy/config/locales/devise.en.yml +59 -0
  56. data/spec/dummy/config/locales/en.yml +23 -0
  57. data/spec/dummy/config/routes.rb +63 -0
  58. data/spec/dummy/config.ru +4 -0
  59. data/spec/dummy/db/migrate/20140217124048_devise_create_users.rb +15 -0
  60. data/spec/dummy/db/migrate/20140223194521_create_articles.rb +11 -0
  61. data/spec/dummy/db/schema.rb +39 -0
  62. data/spec/dummy/db/seeds.rb +7 -0
  63. data/spec/dummy/lib/assets/.keep +0 -0
  64. data/spec/dummy/lib/tasks/.keep +0 -0
  65. data/spec/dummy/log/.keep +0 -0
  66. data/spec/dummy/public/404.html +58 -0
  67. data/spec/dummy/public/422.html +58 -0
  68. data/spec/dummy/public/500.html +57 -0
  69. data/spec/dummy/public/favicon.ico +0 -0
  70. data/spec/dummy/public/robots.txt +5 -0
  71. data/spec/dummy/vendor/assets/javascripts/.keep +0 -0
  72. data/spec/dummy/vendor/assets/stylesheets/.keep +0 -0
  73. data/spec/factories/user.rb +8 -0
  74. data/spec/lib/g5_authenticatable_api/token_validator_spec.rb +199 -0
  75. data/spec/lib/g5_authenticatable_api/version_spec.rb +7 -0
  76. data/spec/requests/grape_api_spec.rb +21 -0
  77. data/spec/requests/rails_api_spec.rb +13 -0
  78. data/spec/spec_helper.rb +49 -0
  79. data/spec/support/factory_girl.rb +5 -0
  80. data/spec/support/shared_contexts/invalid_access_token.rb +24 -0
  81. data/spec/support/shared_contexts/valid_access_token.rb +7 -0
  82. data/spec/support/shared_examples/token_authenticatable_api.rb +106 -0
  83. data/spec/support/shared_examples/warden_authenticatable_api.rb +31 -0
  84. data/spec/support/warden.rb +4 -0
  85. metadata +223 -0
@@ -0,0 +1,49 @@
1
+ # MUST happen before any other code is loaded
2
+ require 'simplecov'
3
+ SimpleCov.start 'test_frameworks'
4
+
5
+ require 'codeclimate-test-reporter'
6
+ CodeClimate::TestReporter.start
7
+
8
+ ENV["RAILS_ENV"] ||= 'test'
9
+ require File.expand_path("../dummy/config/environment", __FILE__)
10
+
11
+ require 'rspec/rails'
12
+ require 'rspec/http'
13
+ require 'capybara/rspec'
14
+ require 'webmock/rspec'
15
+
16
+ Rails.backtrace_cleaner.remove_silencers!
17
+
18
+ # Requires supporting ruby files with custom matchers and macros, etc,
19
+ # in spec/support/ and its subdirectories.
20
+ Dir[File.expand_path('../support/**/*.rb', __FILE__)].each { |f| require f }
21
+
22
+ RSpec.configure do |config|
23
+ # ## Mock Framework
24
+ #
25
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
26
+ #
27
+ # config.mock_with :mocha
28
+ # config.mock_with :flexmock
29
+ # config.mock_with :rr
30
+ config.mock_with :rspec
31
+
32
+ # If you're not using ActiveRecord, or you'd prefer not to run each of your
33
+ # examples within a transaction, remove the following line or assign false
34
+ # instead of true.
35
+ config.use_transactional_fixtures = true
36
+
37
+ # If true, the base class of anonymous controllers will be inferred
38
+ # automatically. This will be the default behavior in future versions of
39
+ # rspec-rails.
40
+ config.infer_base_class_for_anonymous_controllers = false
41
+
42
+ # Run specs in random order to surface order dependencies. If you find an
43
+ # order dependency and want to debug it, you can fix the order by providing
44
+ # the seed, which is printed after each run.
45
+ # --seed 1234
46
+ config.order = 'random'
47
+
48
+ config.after(:suite) { WebMock.disable! }
49
+ end
@@ -0,0 +1,5 @@
1
+ require 'factory_girl_rails'
2
+
3
+ RSpec.configure do |config|
4
+ config.include FactoryGirl::Syntax::Methods
5
+ end
@@ -0,0 +1,24 @@
1
+ shared_context 'OAuth2 error' do
2
+ before do
3
+ stub_request(:get, 'auth.g5search.com/oauth/token/info').
4
+ with(headers: {'Authorization'=>"Bearer #{token_value}"}).
5
+ to_return(status: 401,
6
+ headers: {'Content-Type' => 'application/json; charset=utf-8',
7
+ 'Cache-Control' => 'no-cache'},
8
+ body: parsed_error.to_json)
9
+ end
10
+
11
+ let(:parsed_error) { '' }
12
+ end
13
+
14
+ shared_context 'invalid access token' do
15
+ include_context 'OAuth2 error' do
16
+ let(:parsed_error) do
17
+ {'error' => error_code,
18
+ 'error_description' => error_description}
19
+ end
20
+
21
+ let(:error_code) { 'invalid_token' }
22
+ let(:error_description) { 'The access token expired' }
23
+ end
24
+ end
@@ -0,0 +1,7 @@
1
+ shared_context 'valid access token' do
2
+ before do
3
+ stub_request(:get, 'auth.g5search.com/oauth/token/info').
4
+ with(headers: {'Authorization'=>"Bearer #{token_value}"}).
5
+ to_return(status: 200, body: '', headers: {})
6
+ end
7
+ end
@@ -0,0 +1,106 @@
1
+ shared_examples_for 'token validation' do
2
+ context 'when token is valid' do
3
+ include_context 'valid access token'
4
+
5
+ before { subject }
6
+
7
+ it 'should be successful' do
8
+ expect(response).to be_success
9
+ end
10
+
11
+ it 'should validate the access token against the auth server' do
12
+ expect(a_request(:get, 'auth.g5search.com/oauth/token/info').
13
+ with(headers: {'Authorization' => "Bearer #{token_value}"})).to have_been_made
14
+ end
15
+ end
16
+
17
+ context 'when token is invalid' do
18
+ include_context 'invalid access token'
19
+
20
+ before { subject }
21
+
22
+ it 'should be unauthorized' do
23
+ expect(response).to be_http_unauthorized
24
+ end
25
+
26
+ it 'should return an authenticate header' do
27
+ expect(response.headers).to have_key('WWW-Authenticate')
28
+ end
29
+
30
+ it 'should return the authentication error' do
31
+ expect(response.headers['WWW-Authenticate']).to match("error=\"#{error_code}\"")
32
+ end
33
+
34
+ it 'should return the authentication error description' do
35
+ expect(response.headers['WWW-Authenticate']).to match("error_description=\"#{error_description}\"")
36
+ end
37
+ end
38
+
39
+ context 'when some other oauth error occurs' do
40
+ include_context 'OAuth2 error'
41
+
42
+ before { subject }
43
+
44
+ it 'should be unauthorized' do
45
+ expect(response).to be_http_unauthorized
46
+ end
47
+
48
+ it 'should return an authenticate header' do
49
+ expect(response.headers).to have_key('WWW-Authenticate')
50
+ end
51
+
52
+ it 'should return the default authentication error code' do
53
+ expect(response.headers['WWW-Authenticate']).to match('error="invalid_request"')
54
+ end
55
+ end
56
+ end
57
+
58
+ shared_examples_for 'a token authenticatable api' do
59
+ let(:token_value) { 'abc123' }
60
+
61
+ context 'with authorization header' do
62
+ let(:headers) { {'Authorization' => "Bearer #{token_value}"} }
63
+
64
+ include_examples 'token validation'
65
+ end
66
+
67
+ context 'with access token parameter' do
68
+ let(:params) { {'access_token' => token_value} }
69
+
70
+ include_examples 'token validation'
71
+ end
72
+
73
+ context 'without authentication information' do
74
+ before { subject }
75
+
76
+ it 'should be unauthorized' do
77
+ expect(response).to be_http_unauthorized
78
+ end
79
+
80
+ it 'should return an authenticate header without details' do
81
+ expect(response.headers).to include('WWW-Authenticate' => 'Bearer')
82
+ end
83
+ end
84
+
85
+ context 'with environment variables for password credentials' do
86
+ before do
87
+ ENV['G5_AUTH_USERNAME'] = 'my.user@test.host'
88
+ ENV['G5_AUTH_PASSWORD'] = 'my_secret'
89
+ end
90
+
91
+ after do
92
+ ENV['G5_AUTH_USERNAME'] = nil
93
+ ENV['G5_AUTH_PASSWORD'] = nil
94
+ end
95
+
96
+ before { subject }
97
+
98
+ it 'should be unauthorized' do
99
+ expect(response).to be_http_unauthorized
100
+ end
101
+
102
+ it 'should return an authenticate header without details' do
103
+ expect(response.headers).to include('WWW-Authenticate' => 'Bearer')
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples_for 'a warden authenticatable api' do
4
+ context 'when user is authenticated' do
5
+ let(:user) { create(:user) }
6
+
7
+ before do
8
+ login_as(user, scope: :user)
9
+ subject
10
+ end
11
+
12
+ it 'should be successful' do
13
+ expect(response).to be_success
14
+ end
15
+ end
16
+
17
+ context 'when user is not authenticated' do
18
+ before do
19
+ logout
20
+ subject
21
+ end
22
+
23
+ it 'should be unauthorized' do
24
+ expect(response).to be_http_unauthorized
25
+ end
26
+
27
+ it 'should return an authenticate header without details' do
28
+ expect(response.headers).to include('WWW-Authenticate' => 'Bearer')
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,4 @@
1
+ RSpec.configure do |config|
2
+ config.include Warden::Test::Helpers, type: :request
3
+ config.after(type: :request) { Warden.test_reset! }
4
+ end
metadata ADDED
@@ -0,0 +1,223 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: g5_authenticatable_api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Maeve Revels
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: g5_authentication_client
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.2'
41
+ description: Helpers for securing APIs with G5
42
+ email:
43
+ - maeve.revels@getg5.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".gitignore"
49
+ - ".rspec"
50
+ - CHANGELOG.md
51
+ - Gemfile
52
+ - LICENSE.txt
53
+ - README.md
54
+ - Rakefile
55
+ - circle.yml
56
+ - g5_authenticatable_api.gemspec
57
+ - lib/g5_authenticatable_api.rb
58
+ - lib/g5_authenticatable_api/helpers/grape.rb
59
+ - lib/g5_authenticatable_api/helpers/rails.rb
60
+ - lib/g5_authenticatable_api/railtie.rb
61
+ - lib/g5_authenticatable_api/token_validator.rb
62
+ - lib/g5_authenticatable_api/version.rb
63
+ - spec/dummy/README.rdoc
64
+ - spec/dummy/Rakefile
65
+ - spec/dummy/app/api/hello_api.rb
66
+ - spec/dummy/app/assets/images/.keep
67
+ - spec/dummy/app/assets/javascripts/application.js
68
+ - spec/dummy/app/assets/javascripts/articles.js
69
+ - spec/dummy/app/assets/stylesheets/application.css
70
+ - spec/dummy/app/assets/stylesheets/articles.css
71
+ - spec/dummy/app/controllers/application_controller.rb
72
+ - spec/dummy/app/controllers/concerns/.keep
73
+ - spec/dummy/app/controllers/rails_api/articles_controller.rb
74
+ - spec/dummy/app/helpers/application_helper.rb
75
+ - spec/dummy/app/helpers/articles_helper.rb
76
+ - spec/dummy/app/mailers/.keep
77
+ - spec/dummy/app/models/.keep
78
+ - spec/dummy/app/models/article.rb
79
+ - spec/dummy/app/models/concerns/.keep
80
+ - spec/dummy/app/models/user.rb
81
+ - spec/dummy/app/views/layouts/application.html.erb
82
+ - spec/dummy/bin/bundle
83
+ - spec/dummy/bin/rails
84
+ - spec/dummy/bin/rake
85
+ - spec/dummy/config.ru
86
+ - spec/dummy/config/application.rb
87
+ - spec/dummy/config/boot.rb
88
+ - spec/dummy/config/database.yml.ci
89
+ - spec/dummy/config/database.yml.sample
90
+ - spec/dummy/config/environment.rb
91
+ - spec/dummy/config/environments/development.rb
92
+ - spec/dummy/config/environments/production.rb
93
+ - spec/dummy/config/environments/test.rb
94
+ - spec/dummy/config/initializers/backtrace_silencers.rb
95
+ - spec/dummy/config/initializers/devise.rb
96
+ - spec/dummy/config/initializers/filter_parameter_logging.rb
97
+ - spec/dummy/config/initializers/inflections.rb
98
+ - spec/dummy/config/initializers/mime_types.rb
99
+ - spec/dummy/config/initializers/secret_token.rb
100
+ - spec/dummy/config/initializers/session_store.rb
101
+ - spec/dummy/config/initializers/wrap_parameters.rb
102
+ - spec/dummy/config/locales/devise.en.yml
103
+ - spec/dummy/config/locales/en.yml
104
+ - spec/dummy/config/routes.rb
105
+ - spec/dummy/db/migrate/20140217124048_devise_create_users.rb
106
+ - spec/dummy/db/migrate/20140223194521_create_articles.rb
107
+ - spec/dummy/db/schema.rb
108
+ - spec/dummy/db/seeds.rb
109
+ - spec/dummy/lib/assets/.keep
110
+ - spec/dummy/lib/tasks/.keep
111
+ - spec/dummy/log/.keep
112
+ - spec/dummy/public/404.html
113
+ - spec/dummy/public/422.html
114
+ - spec/dummy/public/500.html
115
+ - spec/dummy/public/favicon.ico
116
+ - spec/dummy/public/robots.txt
117
+ - spec/dummy/vendor/assets/javascripts/.keep
118
+ - spec/dummy/vendor/assets/stylesheets/.keep
119
+ - spec/factories/user.rb
120
+ - spec/lib/g5_authenticatable_api/token_validator_spec.rb
121
+ - spec/lib/g5_authenticatable_api/version_spec.rb
122
+ - spec/requests/grape_api_spec.rb
123
+ - spec/requests/rails_api_spec.rb
124
+ - spec/spec_helper.rb
125
+ - spec/support/factory_girl.rb
126
+ - spec/support/shared_contexts/invalid_access_token.rb
127
+ - spec/support/shared_contexts/valid_access_token.rb
128
+ - spec/support/shared_examples/token_authenticatable_api.rb
129
+ - spec/support/shared_examples/warden_authenticatable_api.rb
130
+ - spec/support/warden.rb
131
+ homepage: https://github.com/G5/g5_authenticatable_api
132
+ licenses:
133
+ - MIT
134
+ metadata: {}
135
+ post_install_message:
136
+ rdoc_options: []
137
+ require_paths:
138
+ - lib
139
+ required_ruby_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ required_rubygems_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ requirements: []
150
+ rubyforge_project:
151
+ rubygems_version: 2.2.0
152
+ signing_key:
153
+ specification_version: 4
154
+ summary: Helpers for securing APIs with G5
155
+ test_files:
156
+ - spec/dummy/README.rdoc
157
+ - spec/dummy/Rakefile
158
+ - spec/dummy/app/api/hello_api.rb
159
+ - spec/dummy/app/assets/images/.keep
160
+ - spec/dummy/app/assets/javascripts/application.js
161
+ - spec/dummy/app/assets/javascripts/articles.js
162
+ - spec/dummy/app/assets/stylesheets/application.css
163
+ - spec/dummy/app/assets/stylesheets/articles.css
164
+ - spec/dummy/app/controllers/application_controller.rb
165
+ - spec/dummy/app/controllers/concerns/.keep
166
+ - spec/dummy/app/controllers/rails_api/articles_controller.rb
167
+ - spec/dummy/app/helpers/application_helper.rb
168
+ - spec/dummy/app/helpers/articles_helper.rb
169
+ - spec/dummy/app/mailers/.keep
170
+ - spec/dummy/app/models/.keep
171
+ - spec/dummy/app/models/article.rb
172
+ - spec/dummy/app/models/concerns/.keep
173
+ - spec/dummy/app/models/user.rb
174
+ - spec/dummy/app/views/layouts/application.html.erb
175
+ - spec/dummy/bin/bundle
176
+ - spec/dummy/bin/rails
177
+ - spec/dummy/bin/rake
178
+ - spec/dummy/config.ru
179
+ - spec/dummy/config/application.rb
180
+ - spec/dummy/config/boot.rb
181
+ - spec/dummy/config/database.yml.ci
182
+ - spec/dummy/config/database.yml.sample
183
+ - spec/dummy/config/environment.rb
184
+ - spec/dummy/config/environments/development.rb
185
+ - spec/dummy/config/environments/production.rb
186
+ - spec/dummy/config/environments/test.rb
187
+ - spec/dummy/config/initializers/backtrace_silencers.rb
188
+ - spec/dummy/config/initializers/devise.rb
189
+ - spec/dummy/config/initializers/filter_parameter_logging.rb
190
+ - spec/dummy/config/initializers/inflections.rb
191
+ - spec/dummy/config/initializers/mime_types.rb
192
+ - spec/dummy/config/initializers/secret_token.rb
193
+ - spec/dummy/config/initializers/session_store.rb
194
+ - spec/dummy/config/initializers/wrap_parameters.rb
195
+ - spec/dummy/config/locales/devise.en.yml
196
+ - spec/dummy/config/locales/en.yml
197
+ - spec/dummy/config/routes.rb
198
+ - spec/dummy/db/migrate/20140217124048_devise_create_users.rb
199
+ - spec/dummy/db/migrate/20140223194521_create_articles.rb
200
+ - spec/dummy/db/schema.rb
201
+ - spec/dummy/db/seeds.rb
202
+ - spec/dummy/lib/assets/.keep
203
+ - spec/dummy/lib/tasks/.keep
204
+ - spec/dummy/log/.keep
205
+ - spec/dummy/public/404.html
206
+ - spec/dummy/public/422.html
207
+ - spec/dummy/public/500.html
208
+ - spec/dummy/public/favicon.ico
209
+ - spec/dummy/public/robots.txt
210
+ - spec/dummy/vendor/assets/javascripts/.keep
211
+ - spec/dummy/vendor/assets/stylesheets/.keep
212
+ - spec/factories/user.rb
213
+ - spec/lib/g5_authenticatable_api/token_validator_spec.rb
214
+ - spec/lib/g5_authenticatable_api/version_spec.rb
215
+ - spec/requests/grape_api_spec.rb
216
+ - spec/requests/rails_api_spec.rb
217
+ - spec/spec_helper.rb
218
+ - spec/support/factory_girl.rb
219
+ - spec/support/shared_contexts/invalid_access_token.rb
220
+ - spec/support/shared_contexts/valid_access_token.rb
221
+ - spec/support/shared_examples/token_authenticatable_api.rb
222
+ - spec/support/shared_examples/warden_authenticatable_api.rb
223
+ - spec/support/warden.rb