g5_authenticatable 0.9.1.pre.2 → 1.0.0.pre.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.ruby-version +1 -1
- data/.travis.yml +23 -9
- data/Appraisals +17 -0
- data/CHANGELOG.md +14 -0
- data/Gemfile +11 -14
- data/README.md +40 -13
- data/app/controllers/concerns/g5_authenticatable/authorization.rb +4 -1
- data/app/controllers/g5_authenticatable/application_controller.rb +3 -0
- data/app/controllers/g5_authenticatable/error_controller.rb +3 -2
- data/app/controllers/g5_authenticatable/failure_app.rb +35 -0
- data/app/controllers/g5_authenticatable/sessions_controller.rb +7 -3
- data/app/helpers/g5_authenticatable/application_helper.rb +3 -0
- data/app/models/g5_authenticatable/role.rb +5 -2
- data/app/models/g5_authenticatable/user.rb +12 -5
- data/app/policies/g5_authenticatable/base_policy.rb +75 -58
- data/app/policies/g5_updatable/client_policy.rb +5 -5
- data/app/policies/g5_updatable/location_policy.rb +6 -5
- data/app/policies/g5_updatable/selectable_client_policy.rb +6 -7
- data/app/services/g5_authenticatable/impersonate_sessionable.rb +12 -7
- data/config/initializers/devise.rb +4 -0
- data/config/initializers/impersonate_strategy.rb +5 -2
- data/config/initializers/rolify.rb +2 -0
- data/config/routes.rb +3 -1
- data/g5_authenticatable.gemspec +11 -7
- data/gemfiles/rails_4.1.gemfile +28 -0
- data/gemfiles/rails_4.2.gemfile +28 -0
- data/gemfiles/rails_5.0.gemfile +28 -0
- data/gemfiles/rails_5.1.gemfile +28 -0
- data/lib/g5_authenticatable.rb +3 -1
- data/lib/g5_authenticatable/engine.rb +5 -2
- data/lib/g5_authenticatable/rspec.rb +2 -0
- data/lib/g5_authenticatable/test/controller_helpers.rb +14 -9
- data/lib/g5_authenticatable/test/env_helpers.rb +3 -0
- data/lib/g5_authenticatable/test/factories/client_users.rb +45 -0
- data/lib/g5_authenticatable/test/factories/global_users.rb +43 -0
- data/lib/g5_authenticatable/test/factories/location_users.rb +45 -0
- data/lib/g5_authenticatable/test/factories/roles.rb +63 -0
- data/lib/g5_authenticatable/test/factory.rb +7 -59
- data/lib/g5_authenticatable/test/feature_helpers.rb +31 -17
- data/lib/g5_authenticatable/test/request_helpers.rb +5 -1
- data/lib/g5_authenticatable/test/token_validation_helpers.rb +15 -10
- data/lib/g5_authenticatable/version.rb +3 -1
- data/lib/generators/g5_authenticatable/install/install_generator.rb +49 -37
- data/lib/generators/g5_authenticatable/install/templates/application_policy.rb +2 -0
- data/lib/generators/g5_authenticatable/install/templates/initializer.rb +2 -0
- data/lib/generators/g5_authenticatable/install/templates/migrate/add_g5_authenticatable_users_contact_info.rb +3 -1
- data/lib/generators/g5_authenticatable/install/templates/migrate/create_g5_authenticatable_roles.rb +3 -1
- data/lib/generators/g5_authenticatable/install/templates/migrate/create_g5_authenticatable_users.rb +3 -1
- data/lib/tasks/g5_authenticatable/purge_users.rake +2 -0
- data/spec/config/application_spec.rb +7 -4
- data/spec/controllers/application_controller_spec.rb +10 -5
- data/spec/controllers/concerns/g5_authenticatable/{authorization.rb → authorization_spec.rb} +11 -6
- data/spec/dummy/app/controllers/home_controller.rb +5 -5
- data/spec/dummy/app/controllers/rails_api/secure_resources_controller.rb +6 -4
- data/spec/dummy/app/models/post.rb +1 -1
- data/spec/dummy/config/environments/test.rb +25 -4
- data/spec/dummy/config/initializers/rails_compatibility.rb +10 -0
- data/spec/dummy/db/migrate/20140206070137_create_g5_authenticatable_users.rb +3 -1
- data/spec/dummy/db/migrate/20150428182339_add_g5_authenticatable_users_contact_info.rb +3 -1
- data/spec/dummy/db/migrate/20150429212919_create_g5_authenticatable_roles.rb +2 -1
- data/spec/dummy/db/migrate/20150509061150_create_posts.rb +3 -1
- data/spec/dummy/db/migrate/20150603224032_create_g5_updatable_clients_and_locations.g5_updatable.rb +3 -1
- data/spec/dummy/db/migrate/20150603224033_create_integration_setting.g5_updatable.rb +3 -1
- data/spec/dummy/db/migrate/20150603224034_remove_integration_setting.g5_updatable.rb +3 -1
- data/spec/dummy/db/migrate/20150603224035_add_name_to_clients_and_locations.g5_updatable.rb +3 -1
- data/spec/dummy/db/migrate/20150603224036_update_names.g5_updatable.rb +3 -1
- data/spec/dummy/db/migrate/20170613201430_add_latitude_and_longitude_to_location.g5_updatable.rb +7 -0
- data/spec/dummy/db/migrate/20170613201431_copy_lat_long_props_to_lat_long_columns.g5_updatable.rb +20 -0
- data/spec/dummy/db/migrate/20170613201432_add_latitude_longitude_indexes_to_location.g5_updatable.rb +7 -0
- data/spec/dummy/db/migrate/{20161122070749_add_amenities.rb → 20170613201433_add_amenities.g5_updatable.rb} +2 -1
- data/spec/dummy/db/migrate/{20161209070749_add_client_urn_to_locations.rb → 20170613201434_add_client_urn_to_locations.g5_updatable.rb} +2 -1
- data/spec/dummy/db/migrate/20170613201435_add_points_of_interest.g5_updatable.rb +21 -0
- data/spec/dummy/db/migrate/20170613201436_add_unique_urn_indexes.g5_updatable.rb +11 -0
- data/spec/dummy/db/schema.rb +73 -61
- data/spec/factories/post.rb +2 -0
- data/spec/features/auth_error_path_spec.rb +3 -3
- data/spec/features/default_role_authorization_spec.rb +8 -4
- data/spec/features/sign_in_spec.rb +23 -13
- data/spec/features/token_validation_spec.rb +4 -2
- data/spec/g5_authenticatable/version_spec.rb +3 -1
- data/spec/lib/generators/g5_authenticatable/install_generator_spec.rb +73 -28
- data/spec/models/g5_authenticatable/role_spec.rb +8 -4
- data/spec/models/g5_authenticatable/user_spec.rb +119 -84
- data/spec/models/post_spec.rb +4 -2
- data/spec/policies/application_policy_spec.rb +80 -47
- data/spec/policies/client_policy_spec.rb +8 -5
- data/spec/policies/location_policy_spec.rb +21 -8
- data/spec/policies/selectable_client_policy_spec.rb +26 -15
- data/spec/rails_helper.rb +41 -0
- data/spec/requests/default_role_authorization_spec.rb +18 -14
- data/spec/requests/grape_api_spec.rb +7 -5
- data/spec/requests/rails_api_spec.rb +11 -9
- data/spec/requests/sign_out_spec.rb +10 -6
- data/spec/requests/token_validation_spec.rb +9 -5
- data/spec/routing/auth_error_routing_spec.rb +7 -6
- data/spec/routing/sign_out_routing_spec.rb +7 -5
- data/spec/services/g5_authenticatable/impersonate_sessionable_spec.rb +41 -18
- data/spec/spec_helper.rb +78 -45
- data/spec/support/devise.rb +3 -1
- data/spec/support/safe_request_helpers.rb +36 -0
- data/spec/support/shared_contexts/rake.rb +10 -4
- data/spec/support/shared_examples/super_admin_authorizer.rb +3 -1
- data/spec/tasks/purge_users_spec.rb +3 -1
- metadata +75 -39
- data/spec/controllers/.gitkeep +0 -0
@@ -1,5 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module G5Authenticatable
|
2
4
|
module Test
|
5
|
+
# Helper methods for login/logout during request specs
|
3
6
|
module RequestHelpers
|
4
7
|
include Warden::Test::Helpers
|
5
8
|
|
@@ -14,7 +17,7 @@ module G5Authenticatable
|
|
14
17
|
end
|
15
18
|
end
|
16
19
|
|
17
|
-
shared_context 'auth request'
|
20
|
+
RSpec.shared_context 'auth request' do
|
18
21
|
include G5Authenticatable::Test::RequestHelpers
|
19
22
|
|
20
23
|
let(:user) { FactoryGirl.create(:g5_authenticatable_user) }
|
@@ -30,4 +33,5 @@ end
|
|
30
33
|
RSpec.configure do |config|
|
31
34
|
config.include G5Authenticatable::Test::RequestHelpers, type: :request
|
32
35
|
config.after { Warden.test_reset! }
|
36
|
+
config.include_context 'auth request', auth_request: true
|
33
37
|
end
|
@@ -1,20 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module G5Authenticatable
|
2
4
|
module Test
|
5
|
+
# Helpers for stubbing token validation requests
|
3
6
|
module TokenValidationHelpers
|
4
7
|
def stub_valid_access_token(token_value)
|
5
|
-
stub_request(:get, "#{ENV['G5_AUTH_ENDPOINT']}/oauth/token/info")
|
6
|
-
with(headers: {'Authorization'=>"Bearer #{token_value}"})
|
7
|
-
to_return(status: 200, body: '', headers: {})
|
8
|
+
stub_request(:get, "#{ENV['G5_AUTH_ENDPOINT']}/oauth/token/info")
|
9
|
+
.with(headers: { 'Authorization' => "Bearer #{token_value}" })
|
10
|
+
.to_return(status: 200, body: '', headers: {})
|
8
11
|
end
|
9
12
|
|
10
13
|
def stub_invalid_access_token(token_value)
|
11
|
-
stub_request(:get, "#{ENV['G5_AUTH_ENDPOINT']}/oauth/token/info")
|
12
|
-
with(headers: {'Authorization'=>"Bearer #{token_value}"})
|
13
|
-
to_return(status: 401,
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
stub_request(:get, "#{ENV['G5_AUTH_ENDPOINT']}/oauth/token/info")
|
15
|
+
.with(headers: { 'Authorization' => "Bearer #{token_value}" })
|
16
|
+
.to_return(status: 401,
|
17
|
+
headers: { 'Content-Type' => 'application/json;' \
|
18
|
+
' charset=utf-8',
|
19
|
+
'Cache-Control' => 'no-cache' },
|
20
|
+
body: { 'error' => 'invalid_token',
|
21
|
+
'error_description' => 'The access token expired' }
|
22
|
+
.to_json)
|
18
23
|
end
|
19
24
|
end
|
20
25
|
end
|
@@ -1,51 +1,63 @@
|
|
1
|
-
|
2
|
-
include Rails::Generators::Migration
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
3
|
+
module G5Authenticatable
|
4
|
+
class InstallGenerator < Rails::Generators::Base
|
5
|
+
include Rails::Generators::Migration
|
5
6
|
|
6
|
-
|
7
|
-
def self.next_migration_number(dirname)
|
8
|
-
next_migration_number = current_migration_number(dirname) + 1
|
9
|
-
ActiveRecord::Migration.next_migration_number(next_migration_number)
|
10
|
-
end
|
7
|
+
source_root File.expand_path('../templates', __FILE__)
|
11
8
|
|
12
|
-
|
13
|
-
|
14
|
-
|
9
|
+
# Required for Rails::Generators::Migrations
|
10
|
+
def self.next_migration_number(dirname)
|
11
|
+
next_migration_number = current_migration_number(dirname) + 1
|
12
|
+
ActiveRecord::Migration.next_migration_number(next_migration_number)
|
13
|
+
end
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
def mount_engine
|
16
|
+
route "mount G5Authenticatable::Engine => '/g5_auth'"
|
17
|
+
end
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
def create_initializer
|
20
|
+
template 'initializer.rb', 'config/initializers/g5_authenticatable.rb'
|
21
|
+
end
|
23
22
|
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
def create_users_migration
|
24
|
+
copy_migration('create_g5_authenticatable_users')
|
25
|
+
end
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
def users_contact_info_migration
|
28
|
+
copy_migration('add_g5_authenticatable_users_contact_info')
|
29
|
+
end
|
31
30
|
|
32
|
-
|
33
|
-
|
34
|
-
after: "class ApplicationController < ActionController::Base\n" do
|
35
|
-
" include G5Authenticatable::Authorization\n"
|
31
|
+
def create_roles_migration
|
32
|
+
copy_migration('create_g5_authenticatable_roles')
|
36
33
|
end
|
37
|
-
end
|
38
34
|
|
39
|
-
|
40
|
-
|
41
|
-
|
35
|
+
def include_authorization
|
36
|
+
inject_into_file 'app/controllers/application_controller.rb',
|
37
|
+
after: "class ApplicationController < ActionController::Base\n" do
|
38
|
+
" include G5Authenticatable::Authorization\n"
|
39
|
+
end
|
40
|
+
end
|
42
41
|
|
43
|
-
|
44
|
-
|
45
|
-
|
42
|
+
def create_application_policy
|
43
|
+
template 'application_policy.rb', 'app/policies/application_policy.rb'
|
44
|
+
end
|
46
45
|
|
47
|
-
|
48
|
-
|
49
|
-
|
46
|
+
def create_403_error_page
|
47
|
+
template '403.html', 'public/403.html'
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def copy_migration(name)
|
53
|
+
migration_template("migrate/#{name}.rb",
|
54
|
+
"db/migrate/#{name}.rb",
|
55
|
+
migration_version: migration_version)
|
56
|
+
end
|
57
|
+
|
58
|
+
def migration_version
|
59
|
+
return unless Rails.version.starts_with?('5')
|
60
|
+
"[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
|
61
|
+
end
|
50
62
|
end
|
51
63
|
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class AddG5AuthenticatableUsersContactInfo < ActiveRecord::Migration<%= migration_version %>
|
2
4
|
def change
|
3
5
|
change_table(:g5_authenticatable_users) do |t|
|
4
6
|
t.string :first_name
|
@@ -1,7 +1,10 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe 'Application Configuration' do
|
6
|
+
it 'appends access_token to the implementing apps filter_parameters' do
|
7
|
+
expect(Dummy::Application.config.filter_parameters)
|
8
|
+
.to include(:access_token)
|
6
9
|
end
|
7
10
|
end
|
@@ -1,20 +1,25 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe ::ApplicationController do
|
4
6
|
it 'should have the correct new_session_path for users' do
|
5
7
|
expect(controller.new_session_path(:user)).to eq('/g5_auth/users/sign_in')
|
6
8
|
end
|
7
9
|
|
8
10
|
it 'should have the correct destroy_session_path for users' do
|
9
|
-
expect(controller.destroy_session_path(:user))
|
11
|
+
expect(controller.destroy_session_path(:user))
|
12
|
+
.to eq('/g5_auth/users/sign_out')
|
10
13
|
end
|
11
14
|
|
12
15
|
it 'should have the correct g5_authorize_path for users' do
|
13
|
-
expect(controller.g5_authorize_path(:user))
|
16
|
+
expect(controller.g5_authorize_path(:user))
|
17
|
+
.to eq('/g5_auth/users/auth/g5')
|
14
18
|
end
|
15
19
|
|
16
20
|
it 'should have the correct g5_callback_path for users' do
|
17
|
-
expect(controller.g5_callback_path(:user))
|
21
|
+
expect(controller.g5_callback_path(:user))
|
22
|
+
.to eq('/g5_auth/users/auth/g5/callback')
|
18
23
|
end
|
19
24
|
|
20
25
|
context 'when strict token validation is enabled' do
|
data/spec/controllers/concerns/g5_authenticatable/{authorization.rb → authorization_spec.rb}
RENAMED
@@ -1,11 +1,14 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe G5Authenticatable::Authorization, type: :controller do
|
4
6
|
controller(ActionController::Base) do
|
5
7
|
include G5Authenticatable::Authorization
|
6
8
|
|
7
9
|
def index
|
8
|
-
raise Pundit::NotAuthorizedError.new(query: 'index?',
|
10
|
+
raise Pundit::NotAuthorizedError.new(query: 'index?',
|
11
|
+
record: 'mock_record')
|
9
12
|
end
|
10
13
|
end
|
11
14
|
|
@@ -18,7 +21,7 @@ describe G5Authenticatable::Authorization, type: :controller do
|
|
18
21
|
end
|
19
22
|
|
20
23
|
describe '#user_not_authorized' do
|
21
|
-
subject(:user_not_authorized) {
|
24
|
+
subject(:user_not_authorized) { safe_get :index, format: format }
|
22
25
|
|
23
26
|
context 'when format is json' do
|
24
27
|
let(:format) { :json }
|
@@ -30,7 +33,7 @@ describe G5Authenticatable::Authorization, type: :controller do
|
|
30
33
|
|
31
34
|
it 'renders the json error message' do
|
32
35
|
user_not_authorized
|
33
|
-
expect(JSON.parse(response.body)).to eq(
|
36
|
+
expect(JSON.parse(response.body)).to eq('error' => 'Access forbidden')
|
34
37
|
end
|
35
38
|
end
|
36
39
|
|
@@ -43,7 +46,9 @@ describe G5Authenticatable::Authorization, type: :controller do
|
|
43
46
|
|
44
47
|
it 'renders the static 403.html' do
|
45
48
|
user_not_authorized
|
46
|
-
expect(response).to
|
49
|
+
expect(response.body).to include(
|
50
|
+
'<title>Access forbidden (403)</title>'
|
51
|
+
)
|
47
52
|
end
|
48
53
|
end
|
49
54
|
end
|
@@ -1,9 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class HomeController < ApplicationController
|
2
|
-
|
4
|
+
before_action :authenticate_user!, only: :show
|
3
5
|
|
4
|
-
def index
|
5
|
-
end
|
6
|
+
def index; end
|
6
7
|
|
7
|
-
def show
|
8
|
-
end
|
8
|
+
def show; end
|
9
9
|
end
|
@@ -1,16 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RailsApi
|
2
4
|
class SecureResourcesController < ApplicationController
|
3
|
-
|
4
|
-
|
5
|
+
before_action :authenticate_api_user!, unless: :is_navigational_format?
|
6
|
+
before_action :authenticate_user!, if: :is_navigational_format?
|
5
7
|
|
6
8
|
def create
|
7
|
-
render json: {secure: 'data'}
|
9
|
+
render json: { secure: 'data' }
|
8
10
|
end
|
9
11
|
|
10
12
|
def show
|
11
13
|
respond_to do |format|
|
12
14
|
format.html { render }
|
13
|
-
format.json { render json: {secure: 'data'} }
|
15
|
+
format.json { render json: { secure: 'data' } }
|
14
16
|
end
|
15
17
|
end
|
16
18
|
end
|
@@ -1,5 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
Dummy::Application.configure do
|
2
|
-
# Settings specified here will take precedence over those in
|
4
|
+
# Settings specified here will take precedence over those in
|
5
|
+
# config/application.rb
|
3
6
|
|
4
7
|
# The test environment is used exclusively to run your application's
|
5
8
|
# test suite. You never need to work with it otherwise. Remember that
|
@@ -8,8 +11,26 @@ Dummy::Application.configure do
|
|
8
11
|
config.cache_classes = true
|
9
12
|
|
10
13
|
# Configure static asset server for tests with Cache-Control for performance
|
11
|
-
|
12
|
-
|
14
|
+
cache_header_value = 'public, max-age=3600'
|
15
|
+
|
16
|
+
if config.respond_to?(:public_file_server)
|
17
|
+
# Rails 5.x
|
18
|
+
config.public_file_server.enabled = true
|
19
|
+
config.public_file_server.headers = {
|
20
|
+
'Cache-Control' => cache_header_value
|
21
|
+
}
|
22
|
+
else
|
23
|
+
# Rails 4.x
|
24
|
+
config.static_cache_control = cache_header_value
|
25
|
+
|
26
|
+
if config.respond_to?(:serve_static_files=)
|
27
|
+
# Rails 4.2
|
28
|
+
config.serve_static_files = true
|
29
|
+
else
|
30
|
+
# Rails 4.1
|
31
|
+
config.serve_static_assets = true
|
32
|
+
end
|
33
|
+
end
|
13
34
|
|
14
35
|
# Show full error reports and disable caching
|
15
36
|
config.consider_all_requests_local = true
|
@@ -19,7 +40,7 @@ Dummy::Application.configure do
|
|
19
40
|
config.action_dispatch.show_exceptions = false
|
20
41
|
|
21
42
|
# Disable request forgery protection in test environment
|
22
|
-
config.action_controller.allow_forgery_protection
|
43
|
+
config.action_controller.allow_forgery_protection = false
|
23
44
|
|
24
45
|
# Tell Action Mailer not to deliver emails to the real world.
|
25
46
|
# The :test delivery method accumulates sent emails in the
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Support migration version syntax in rails 4
|
4
|
+
ActiveSupport.on_load(:active_record) do
|
5
|
+
unless ActiveRecord::Migration.respond_to?(:[])
|
6
|
+
ActiveRecord::Migration.define_singleton_method(:[]) do |version|
|
7
|
+
self if version.to_s.starts_with?('4')
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|