omniauth-rails 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +47 -3
- data/Rakefile +1 -0
- data/app/assets/stylesheets/omniauth/rails/application.css +11 -12
- data/app/controllers/omniauth/rails/{require_authentication.rb → authentication_concern.rb} +13 -3
- data/app/controllers/omniauth/rails/{require_authorization.rb → authorization_concern.rb} +13 -4
- data/app/controllers/omniauth/rails/controllers_concern.rb +11 -0
- data/app/controllers/omniauth/rails/flash.rb +2 -21
- data/app/models/omniauth/rails/authentication_request.rb +5 -2
- data/app/views/omniauth/rails/forbidden.html +1 -0
- data/app/views/omniauth/rails/sessions/destroy.html.erb +3 -3
- data/config/initializers/omniauth_rails.rb +1 -34
- data/lib/omniauth/rails.rb +2 -0
- data/lib/omniauth/rails/configuration.rb +5 -1
- data/lib/omniauth/rails/configurator.rb +103 -0
- data/lib/omniauth/rails/engine.rb +13 -0
- data/lib/omniauth/rails/provider.rb +20 -0
- data/lib/omniauth/rails/provider/google_oauth2.rb +34 -0
- data/lib/omniauth/rails/version.rb +1 -1
- data/lib/tasks/mutant.rake +8 -0
- data/spec/controllers/application_controller_spec.rb +0 -1
- data/spec/controllers/authentication_concern_spec.rb +40 -0
- data/spec/examples.txt +20 -15
- data/spec/lib/omniauth/rails/configurator_spec.rb +45 -0
- data/spec/models/omniauth/rails/authorization_types/emails_spec.rb +0 -2
- data/spec/models/omniauth/rails/authorization_types/regex_spec.rb +0 -2
- data/spec/rails_helper_for_engine.rb +1 -1
- data/spec/spec_helper.rb +2 -0
- data/spec/test_app/app/controllers/private_controller.rb +0 -1
- data/spec/test_app/config/application.rb +1 -0
- data/spec/test_app/config/omniauth_rails.yml +6 -0
- data/spec/test_app/config/routes.rb +0 -3
- data/spec/test_app/log/development.log +2333 -0
- data/spec/test_app/log/test.log +50737 -0
- data/spec/test_app/spec/requests/private_controller_spec.rb +33 -6
- data/spec/test_app/spec/requests/sessions_controller_spec.rb +11 -9
- data/spec/test_app/tmp/cache/assets/sprockets/v3.0/7w/7wvYXBtPYrpJ0AsySxiCGKfyqkX-mahHfSlLe8bkKLg.cache +1 -0
- data/spec/test_app/tmp/cache/assets/sprockets/v3.0/Em/EmJbUP6PHR0uxNqWjp0TDKiG2j-89vsmX0dfwbmvzkc.cache +0 -0
- data/spec/test_app/tmp/cache/assets/sprockets/v3.0/HS/HScCeVhpnmJmuQX7s7oOUbEmBL2KWC40o78iLC-3e3M.cache +1 -0
- data/spec/test_app/tmp/cache/assets/sprockets/v3.0/O7/O7W_v6SN36f1tRfV6clZc10p24T7-Ihb3_totn6VrVA.cache +0 -0
- data/spec/test_app/tmp/cache/assets/sprockets/v3.0/S-/S-cHz0vJ4VrdXCUiB5fP9TR5Viz885rz10Wgix-urAA.cache +0 -0
- data/spec/test_app/tmp/cache/assets/sprockets/v3.0/WJ/WJhc1q0sGH7WcpvF09oA0iw4iAdiQkHerW6hdCHwxHo.cache +0 -0
- data/spec/test_app/tmp/cache/assets/sprockets/v3.0/jK/jK2TgENQlNR4Qvt28Euq9dEK5k_UQuVSbofD4vWeTno.cache +0 -0
- data/spec/test_app/tmp/cache/assets/sprockets/v3.0/n0/n0Kk2o2xNYUkuiXPYuld9V2t6GRLzY5YfDfnqdfKlRo.cache +1 -0
- data/spec/test_app/tmp/cache/assets/sprockets/v3.0/nF/nFB84MNiFDrMN0WelMUdomScBrhYdJ4b8LPhXT3v8C4.cache +1 -0
- data/spec/test_app/tmp/cache/assets/sprockets/v3.0/xW/xW2O0qRLEOz9w_8VDiVMAztr-N8UrUvx8v5EEV7mFBU.cache +0 -0
- data/spec/test_app/tmp/cache/assets/sprockets/v3.0/yb/ybtAnaaqo1s0ZXeIKLc5sW1EovhL83HYrgFcKGHUa0Q.cache +1 -0
- data/spec/test_app/tmp/pids/server.pid +1 -1
- metadata +50 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 059f75d1200dc3b91d801bd9123a59735abf41c7
|
4
|
+
data.tar.gz: fafa8b4b4d0a349c4af547544057b98e4653fa5b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 773c1f3d104401f4f59158cd9cc2d237368a3e94643e6e7bec0d56fc445e90b4bf9c619be862b758a5277e6a125c4e2ab011d2be765800fedf8a45f0fc5b72f4
|
7
|
+
data.tar.gz: 2ae36708dd6e522bdb7ebc20a30577bed4c53674d0fc10892ceeb78d4f66300f4fe50d1cc7a811ef5a772575d853ece0a69aba661d6712036b955c7b483ea59b
|
data/README.md
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
# Omniauth::Rails
|
2
|
+
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/omniauth-rails.svg)](https://badge.fury.io/rb/omniauth-rails)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/danrabinowitz/omniauth-rails/badges/gpa.svg)](https://codeclimate.com/github/danrabinowitz/omniauth-rails)
|
5
|
+
[![Build Status](https://travis-ci.org/danrabinowitz/omniauth-rails.svg?branch=master)](https://travis-ci.org/danrabinowitz/omniauth-rails)
|
6
|
+
[![Test Coverage](https://codeclimate.com/github/danrabinowitz/omniauth-rails/badges/coverage.svg)](https://codeclimate.com/github/danrabinowitz/omniauth-rails/coverage)
|
7
|
+
|
2
8
|
A Rails Engine to make it as easy as possible to add oauth authentication to a Rails app.
|
3
9
|
|
10
|
+
|
4
11
|
The canonical use case is this:
|
5
12
|
You build a simple Rails app for your company. It is for internal use only. Your company uses Google Apps for gmail.
|
6
13
|
|
@@ -14,9 +21,8 @@ Authorization is handled separately.
|
|
14
21
|
|
15
22
|
## TODO
|
16
23
|
|
17
|
-
* Add a
|
18
|
-
|
19
|
-
* Search for "TODO" in the code.
|
24
|
+
* Add a new AuthorizationType for groups of email addresses
|
25
|
+
* Run ```rake mutant``` and add all the specs.
|
20
26
|
|
21
27
|
## Usage
|
22
28
|
|
@@ -56,6 +62,33 @@ production:
|
|
56
62
|
include Omniauth::Rails::RequireAuthentication
|
57
63
|
```
|
58
64
|
|
65
|
+
## Additional configuration
|
66
|
+
|
67
|
+
### Automount
|
68
|
+
By default, Omniauth::Rails sets automount to true. You can override this in the omniauth_rails.yml configuration file.
|
69
|
+
|
70
|
+
When automount is true (the default), the engine's routes are mounted in the host application's routes.
|
71
|
+
|
72
|
+
When automount is false, you need to add this line to your routes.rb:
|
73
|
+
```ruby
|
74
|
+
mount Omniauth::Rails::Engine => OmniAuth.config.path_prefix
|
75
|
+
```
|
76
|
+
|
77
|
+
### path_prefix
|
78
|
+
The default path_prefix for Omniauth is "/auth". In the unlikely event that this
|
79
|
+
causes a conflict, it can be changed with the path_prefix configuration parameter.
|
80
|
+
|
81
|
+
### autoload_in_application_controller
|
82
|
+
The default value of autoload_in_application_controller is true.
|
83
|
+
|
84
|
+
When it is true, the controller concerns are automatically included in ActionController::Base.
|
85
|
+
|
86
|
+
If there is a conflict in having those methods in all controllers, set autoload_in_application_controller to
|
87
|
+
false and manually add this line to any controllers which require authentication or authorization:
|
88
|
+
```ruby
|
89
|
+
include Omniauth::Rails::ControllersConcern
|
90
|
+
```
|
91
|
+
|
59
92
|
## Logging out
|
60
93
|
|
61
94
|
In general, there's not much point in "logging out". It wipes the Omniauth::Rails session,
|
@@ -64,8 +97,19 @@ but the browser is still logged in to the provider, which has granted access to
|
|
64
97
|
|
65
98
|
Bottom line: There's usually no reason to have a logout button when using Omniauth::Rails
|
66
99
|
|
100
|
+
## Mutation Testing
|
101
|
+
|
102
|
+
Run ```rake mutant```
|
103
|
+
The output will appear on STDOUT and also in coverage/mutant.out
|
104
|
+
|
105
|
+
More info on reading the reports is here: https://github.com/mbj/mutant#reading-reports
|
106
|
+
|
67
107
|
## Contributing
|
68
108
|
PRs are welcome!
|
69
109
|
|
110
|
+
## Credit
|
111
|
+
Thanks to [Paul De Goes](https://github.com/pauldegoes) for the idea for this gem. He
|
112
|
+
built a similar gem for internal use at LivingSocial.
|
113
|
+
|
70
114
|
## License
|
71
115
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
CHANGED
@@ -1,19 +1,18 @@
|
|
1
1
|
form.button_to {
|
2
2
|
display: inline;
|
3
|
-
margin: 0;
|
4
3
|
padding: 0;
|
5
4
|
}
|
6
5
|
form.button_to div { display: inline; }
|
7
6
|
form.button_to input[type=submit] {
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
7
|
+
margin: 0;
|
8
|
+
padding: 0;
|
9
|
+
-webkit-appearance: caret;
|
10
|
+
-moz-appearance: caret;
|
11
|
+
background: none;
|
12
|
+
border: none;
|
13
|
+
font-size: inherit;
|
14
|
+
font-family: inherit;
|
15
|
+
cursor: pointer;
|
16
|
+
text-decoration: underline;
|
17
|
+
color: #0000FF;
|
19
18
|
}
|
@@ -1,19 +1,29 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module Omniauth
|
3
3
|
module Rails
|
4
|
-
module
|
4
|
+
module AuthenticationConcern
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
7
|
included do
|
8
8
|
include Omniauth::Rails::ApplicationHelper
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
private
|
9
13
|
|
10
|
-
|
11
|
-
|
14
|
+
def require_authentication
|
15
|
+
before_action :require_authentication
|
16
|
+
end
|
12
17
|
end
|
13
18
|
|
14
19
|
private
|
15
20
|
|
16
21
|
def require_authentication
|
22
|
+
if Configuration.dev_mode
|
23
|
+
::Rails.logger.info "Omniauth::Rails: dev_mode is enabled. Skipping 'require_authentication'"
|
24
|
+
return
|
25
|
+
end
|
26
|
+
|
17
27
|
redirect_to_sign_in_url unless authenticated?
|
18
28
|
end
|
19
29
|
|
@@ -1,9 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module Omniauth
|
3
3
|
module Rails
|
4
|
-
module
|
4
|
+
module AuthorizationConcern
|
5
5
|
def self.included(klass)
|
6
|
-
klass.include Omniauth::Rails::RequireAuthentication
|
7
6
|
klass.extend ClassMethods
|
8
7
|
end
|
9
8
|
|
@@ -11,7 +10,6 @@ module Omniauth
|
|
11
10
|
private
|
12
11
|
|
13
12
|
def require_authorization(params)
|
14
|
-
# TODO: Do not add this before_action in dev_mode
|
15
13
|
before_action { |c| c.require_authorization(params) }
|
16
14
|
end
|
17
15
|
end
|
@@ -19,7 +17,14 @@ module Omniauth
|
|
19
17
|
protected
|
20
18
|
|
21
19
|
def require_authorization(params)
|
22
|
-
|
20
|
+
if Configuration.dev_mode
|
21
|
+
::Rails.logger.info "Omniauth::Rails: dev_mode is enabled. Skipping 'require_authorization'"
|
22
|
+
return
|
23
|
+
end
|
24
|
+
|
25
|
+
require_authentication # Require authentication before authorization.
|
26
|
+
return if performed?
|
27
|
+
render_403_forbidden unless authorized?(params)
|
23
28
|
end
|
24
29
|
|
25
30
|
private
|
@@ -27,6 +32,10 @@ module Omniauth
|
|
27
32
|
def authorized?(params)
|
28
33
|
AuthorizationChecker.new(email: authenticated_email, params: params).authorized?
|
29
34
|
end
|
35
|
+
|
36
|
+
def render_403_forbidden
|
37
|
+
render "omniauth/rails/forbidden", status: :forbidden, layout: false
|
38
|
+
end
|
30
39
|
end
|
31
40
|
end
|
32
41
|
end
|
@@ -5,39 +5,20 @@ module Omniauth
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
7
|
def set_url_to_return_to_after_authentication
|
8
|
-
#
|
8
|
+
# Use caution when setting these urls.
|
9
|
+
# There are phishing risks associated with redirection, as described here:
|
9
10
|
# See https://www.owasp.org/index.php/Unvalidated_Redirects_and_Forwards_Cheat_Sheet
|
10
11
|
flash[:url_to_return_to_after_authentication] =
|
11
|
-
# url_to_return_to_after_authentication_from_params ||
|
12
12
|
url_to_return_to_after_authentication_from_flash ||
|
13
|
-
# url_to_return_to_after_authentication_from_referer ||
|
14
13
|
default_url_to_return_to_after_authentication
|
15
14
|
end
|
16
15
|
|
17
16
|
private
|
18
17
|
|
19
|
-
# def url_to_return_to_after_authentication_from_params
|
20
|
-
# return nil unless allow_url_to_return_to_after_authentication_from_params?
|
21
|
-
# params[:return_to]
|
22
|
-
# end
|
23
|
-
|
24
|
-
# def allow_url_to_return_to_after_authentication_from_params?
|
25
|
-
# false
|
26
|
-
# end
|
27
|
-
|
28
18
|
def url_to_return_to_after_authentication_from_flash
|
29
19
|
flash[:url_to_return_to_after_authentication]
|
30
20
|
end
|
31
21
|
|
32
|
-
# def url_to_return_to_after_authentication_from_referer
|
33
|
-
# return nil unless allow_url_to_return_to_after_authentication_from_referer?
|
34
|
-
# request.referer
|
35
|
-
# end
|
36
|
-
|
37
|
-
# def allow_url_to_return_to_after_authentication_from_referer?
|
38
|
-
# false
|
39
|
-
# end
|
40
|
-
|
41
22
|
def default_url_to_return_to_after_authentication
|
42
23
|
Configuration.authenticated_root
|
43
24
|
end
|
@@ -7,7 +7,6 @@ module Omniauth
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def persist(authentication_session)
|
10
|
-
# TODO: Store the provider in the session
|
11
10
|
authentication_session.email = email
|
12
11
|
authentication_session.expire_in(session_duration)
|
13
12
|
end
|
@@ -17,7 +16,11 @@ module Omniauth
|
|
17
16
|
attr_reader :request
|
18
17
|
|
19
18
|
def email
|
20
|
-
|
19
|
+
info.email
|
20
|
+
end
|
21
|
+
|
22
|
+
def info
|
23
|
+
request.env["omniauth.auth"].info
|
21
24
|
end
|
22
25
|
|
23
26
|
def session_duration
|
@@ -0,0 +1 @@
|
|
1
|
+
ACCESS DENIED
|
@@ -1,35 +1,2 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
config_hash = YAML.load(ERB.new(File.read("#{Rails.root}/config/omniauth_rails.yml")).result)[Rails.env]
|
4
|
-
|
5
|
-
OmniAuth.config.logger = Rails.logger
|
6
|
-
|
7
|
-
# TODO
|
8
|
-
# OmniAuth.config.path_prefix = "/auth"
|
9
|
-
|
10
|
-
Rails.application.config.middleware.use OmniAuth::Builder do
|
11
|
-
if config_hash.present?
|
12
|
-
raise "You must provide at least one oauth provider" unless config_hash["providers"]
|
13
|
-
config_hash["providers"].each do |provider, provider_config|
|
14
|
-
case provider
|
15
|
-
when "google_oauth2"
|
16
|
-
raise "Provider #{provider} requires a client_id" unless provider_config["client_id"]
|
17
|
-
raise "Provider #{provider} requires a client_secret" unless provider_config["client_secret"]
|
18
|
-
|
19
|
-
provider(:google_oauth2, provider_config["client_id"], provider_config["client_secret"],
|
20
|
-
access_type: "online", approval_prompt: "auto")
|
21
|
-
else
|
22
|
-
raise "#{provider} is not currently handled by omniauth_rails."
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
if config_hash["session_duration_in_seconds"].present?
|
29
|
-
Omniauth::Rails::Configuration.session_duration = config_hash["session_duration_in_seconds"].seconds
|
30
|
-
end
|
31
|
-
|
32
|
-
raise "authenticated_root is required" if config_hash["authenticated_root"].blank?
|
33
|
-
Omniauth::Rails::Configuration.authenticated_root = config_hash["authenticated_root"]
|
34
|
-
raise "unauthenticated_root is required" if config_hash["unauthenticated_root"].blank?
|
35
|
-
Omniauth::Rails::Configuration.unauthenticated_root = config_hash["unauthenticated_root"]
|
2
|
+
Omniauth::Rails::Configurator.from_default_config_file.configure
|
data/lib/omniauth/rails.rb
CHANGED
@@ -2,7 +2,11 @@
|
|
2
2
|
module Omniauth
|
3
3
|
module Rails
|
4
4
|
class Configuration
|
5
|
-
ATTRIBUTES = %i(
|
5
|
+
ATTRIBUTES = %i(
|
6
|
+
authenticated_root include_concern_in_application_controller
|
7
|
+
unauthenticated_root session_duration logger
|
8
|
+
dev_mode automount
|
9
|
+
).freeze
|
6
10
|
|
7
11
|
@session_duration = 1.hour
|
8
12
|
@logger = ::Rails.logger
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Omniauth
|
3
|
+
module Rails
|
4
|
+
class Configurator
|
5
|
+
REQUIRED_SETTINGS = %i(providers authenticated_root unauthenticated_root).freeze
|
6
|
+
|
7
|
+
def self.default_config_file
|
8
|
+
"#{::Rails.root}/config/omniauth_rails.yml"
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.from_default_config_file
|
12
|
+
::Rails.logger.info "Omniauth::Rails::Configurator: Loading from " \
|
13
|
+
"default_config_file=#{default_config_file}"
|
14
|
+
from_yaml(default_config_file)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.from_yaml(file)
|
18
|
+
new(YAML.load(ERB.new(File.read(file)).result)[::Rails.env])
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(data)
|
22
|
+
@data = data
|
23
|
+
end
|
24
|
+
|
25
|
+
def configure
|
26
|
+
validate!
|
27
|
+
|
28
|
+
configure_omni_auth_settings
|
29
|
+
configure_providers
|
30
|
+
|
31
|
+
Configuration.automount = automount
|
32
|
+
Configuration.authenticated_root = authenticated_root
|
33
|
+
Configuration.unauthenticated_root = unauthenticated_root
|
34
|
+
Configuration.include_concern_in_application_controller = include_concern_in_application_controller
|
35
|
+
Configuration.session_duration = session_duration.seconds if session_duration.present?
|
36
|
+
Configuration.dev_mode = dev_mode
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
attr_reader :data
|
42
|
+
|
43
|
+
def configure_omni_auth_settings
|
44
|
+
OmniAuth.config.logger = ::Rails.logger
|
45
|
+
OmniAuth.config.path_prefix = path_prefix
|
46
|
+
end
|
47
|
+
|
48
|
+
def dev_mode
|
49
|
+
data["dev_mode"] == true
|
50
|
+
end
|
51
|
+
|
52
|
+
def validate!
|
53
|
+
REQUIRED_SETTINGS.each do |setting|
|
54
|
+
raise "#{setting} is required" unless send(setting).present?
|
55
|
+
end
|
56
|
+
|
57
|
+
if dev_mode
|
58
|
+
raise "dev_mode may not be used in #{::Rails.env}" unless dev_mode_allowed?
|
59
|
+
::Rails.logger.info "Omniauth::Rails: dev_mode is enabled. Authentication and " \
|
60
|
+
"authorization are disabled."
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def dev_mode_allowed?
|
65
|
+
::Rails.env.development?
|
66
|
+
end
|
67
|
+
|
68
|
+
def automount
|
69
|
+
data["automount"] != false
|
70
|
+
end
|
71
|
+
|
72
|
+
def path_prefix
|
73
|
+
data["path_prefix"] || "/auth"
|
74
|
+
end
|
75
|
+
|
76
|
+
def authenticated_root
|
77
|
+
data["authenticated_root"]
|
78
|
+
end
|
79
|
+
|
80
|
+
def unauthenticated_root
|
81
|
+
data["unauthenticated_root"]
|
82
|
+
end
|
83
|
+
|
84
|
+
def session_duration
|
85
|
+
data["session_duration_in_seconds"]
|
86
|
+
end
|
87
|
+
|
88
|
+
def providers
|
89
|
+
data["providers"]
|
90
|
+
end
|
91
|
+
|
92
|
+
def include_concern_in_application_controller
|
93
|
+
data["autoload_in_application_controller"] != false
|
94
|
+
end
|
95
|
+
|
96
|
+
def configure_providers
|
97
|
+
providers.each do |provider, provider_config|
|
98
|
+
Provider.configure(provider, provider_config)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|