rails_sso 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +19 -8
- data/Rakefile +0 -15
- data/app/controllers/rails_sso/sessions_controller.rb +2 -3
- data/app/services/rails_sso/fetch_user.rb +19 -0
- data/{lib → app/services}/rails_sso/update_user.rb +3 -3
- data/lib/rails_sso/access_token.rb +52 -0
- data/lib/rails_sso/helpers.rb +31 -17
- data/lib/rails_sso/version.rb +1 -1
- data/lib/rails_sso.rb +5 -2
- data/test/controllers/rails_sso/sessions_controller_test.rb +43 -0
- data/test/dummy/app/controllers/application_controller.rb +4 -0
- data/test/dummy/config/initializers/sso.rb +13 -0
- data/test/dummy/config/routes.rb +2 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/test.log +2017 -0
- data/test/services/rails_sso/fetch_user_test.rb +46 -0
- data/test/services/rails_sso/update_user_test.rb +79 -0
- data/test/test_helper.rb +1 -0
- metadata +75 -6
- data/lib/rails_sso/fetch_user.rb +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d21cea945bc44cb3fb84f1d2da048091d6f4661
|
4
|
+
data.tar.gz: 9f4bef5ac2353b226593a063a301cad4f618818a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8a2dd465782b4e9372594fbfd531edf0d769f0f285fbf663e8e2855ad12c348cfb0e8614ba75dc573b8d0fcd622ff0f7946efcc6e0b306cd24db7f56c26b9799
|
7
|
+
data.tar.gz: 8efb688b7383bcb5aa783e610d94317ecd22fb7aa5f514d829da0cde7836f76ed3a42a5567a17a88516fb38b96314ace659d81bd829eec0e514c49c8691e694f
|
data/README.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# SSO client Rails Engine
|
2
2
|
|
3
|
+
[](https://gemnasium.com/monterail/rails_sso)
|
4
|
+
[](http://badge.fury.io/rb/rails_sso)
|
5
|
+
|
6
|
+
## About
|
7
|
+
|
8
|
+
*SOON*
|
9
|
+
|
3
10
|
## Installation
|
4
11
|
|
5
12
|
Add engine and [omniauth](https://github.com/intridea/omniauth-oauth2) provider gems to your project:
|
@@ -26,6 +33,8 @@ RailsSso.configure do |config|
|
|
26
33
|
config.provider_profile_path = '/api/v1/profile'
|
27
34
|
# set if you support single sign out
|
28
35
|
config.provider_sign_out_path = '/api/v1/session'
|
36
|
+
# enable cache (will use Rails.cache store)
|
37
|
+
config.use_cache = Rails.application.config.action_controller.perform_caching
|
29
38
|
|
30
39
|
# user fields to synchronize from API
|
31
40
|
config.user_fields = [
|
@@ -56,9 +65,11 @@ Available helpers for controllers and views:
|
|
56
65
|
* `current_user`
|
57
66
|
* `user_signed_in?`
|
58
67
|
|
59
|
-
Available filters for controllers:
|
68
|
+
Available filters and helpers for controllers:
|
60
69
|
|
61
70
|
* `authenticate_user!`
|
71
|
+
* `save_access_token!`
|
72
|
+
* `invalidate_access_token!`
|
62
73
|
|
63
74
|
Available helpers for views:
|
64
75
|
|
@@ -69,11 +80,11 @@ Available helpers for views:
|
|
69
80
|
|
70
81
|
Required methods:
|
71
82
|
|
72
|
-
* `
|
73
|
-
* `
|
83
|
+
* `find_by_sso_id(id)`
|
84
|
+
* `create_with_sso_id(id, attrs)`
|
74
85
|
* `update(record, attrs)`
|
75
86
|
|
76
|
-
Example:
|
87
|
+
Example with `ActiveRecord` user model:
|
77
88
|
|
78
89
|
```ruby
|
79
90
|
# app/repositories/user_repository.rb
|
@@ -85,13 +96,13 @@ class UserRepository
|
|
85
96
|
self.adapter = adapter
|
86
97
|
end
|
87
98
|
|
88
|
-
def
|
89
|
-
adapter.find_by(
|
99
|
+
def find_by_sso_id(id)
|
100
|
+
adapter.find_by(sso_id: id)
|
90
101
|
end
|
91
102
|
|
92
|
-
def
|
103
|
+
def create_with_sso_id(id, attrs)
|
93
104
|
adapter.new(attrs) do |user|
|
94
|
-
user.
|
105
|
+
user.sso_id = id
|
95
106
|
user.save!
|
96
107
|
end
|
97
108
|
end
|
data/Rakefile
CHANGED
@@ -4,21 +4,6 @@ rescue LoadError
|
|
4
4
|
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
5
|
end
|
6
6
|
|
7
|
-
require 'rdoc/task'
|
8
|
-
|
9
|
-
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
-
rdoc.rdoc_dir = 'rdoc'
|
11
|
-
rdoc.title = 'RailsSso'
|
12
|
-
rdoc.options << '--line-numbers'
|
13
|
-
rdoc.rdoc_files.include('README.rdoc')
|
14
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
-
end
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
7
|
Bundler::GemHelper.install_tasks
|
23
8
|
|
24
9
|
require 'rake/testtask'
|
@@ -3,14 +3,13 @@ module RailsSso
|
|
3
3
|
skip_before_action :authenticate_user!, only: [:create]
|
4
4
|
|
5
5
|
def create
|
6
|
-
|
7
|
-
session[:refresh_token] = auth_hash.credentials.refresh_token
|
6
|
+
save_access_token!(auth_hash.credentials)
|
8
7
|
|
9
8
|
redirect_to root_path
|
10
9
|
end
|
11
10
|
|
12
11
|
def destroy
|
13
|
-
|
12
|
+
invalidate_access_token!
|
14
13
|
|
15
14
|
redirect_to root_path
|
16
15
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module RailsSso
|
2
|
+
class FetchUser
|
3
|
+
def initialize(access_token)
|
4
|
+
@access_token = access_token
|
5
|
+
end
|
6
|
+
|
7
|
+
def call
|
8
|
+
yield(get)
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
attr_reader :access_token
|
14
|
+
|
15
|
+
def get
|
16
|
+
access_token.get(RailsSso.provider_profile_path).parsed
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,16 +1,16 @@
|
|
1
1
|
module RailsSso
|
2
2
|
class UpdateUser
|
3
3
|
def initialize(data, options = {})
|
4
|
-
@id, @data = data.
|
4
|
+
@id, @data = data['id'], data.except('id')
|
5
5
|
@fields, @repository = options.values_at(:fields, :repository)
|
6
6
|
end
|
7
7
|
|
8
8
|
def call
|
9
|
-
if user = repository.
|
9
|
+
if user = repository.find_by_sso_id(id)
|
10
10
|
repository.update(user, params)
|
11
11
|
user
|
12
12
|
else
|
13
|
-
repository.
|
13
|
+
repository.create_with_sso_id(id, params)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'faraday-http-cache'
|
2
|
+
|
3
|
+
module RailsSso
|
4
|
+
class AccessToken
|
5
|
+
attr_reader :token, :refresh_token
|
6
|
+
|
7
|
+
delegate :get, :patch, :post, :put, :delete, to: :access_token
|
8
|
+
|
9
|
+
def self.from_access_token(access_token)
|
10
|
+
new(access_token.token, access_token.refresh_token)
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(token, refresh_token)
|
14
|
+
@token, @refresh_token = token, refresh_token
|
15
|
+
end
|
16
|
+
|
17
|
+
def refresh!
|
18
|
+
self.class.from_access_token(access_token.refresh!)
|
19
|
+
end
|
20
|
+
|
21
|
+
def access_token
|
22
|
+
@access_token ||= OAuth2::AccessToken.new(client, token, {
|
23
|
+
refresh_token: refresh_token
|
24
|
+
})
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def client
|
30
|
+
strategy.client.tap do |c|
|
31
|
+
if RailsSso.use_cache
|
32
|
+
c.options[:connection_build] = Proc.new do |conn|
|
33
|
+
conn.use :http_cache,
|
34
|
+
store: Rails.cache,
|
35
|
+
logger: Rails.logger,
|
36
|
+
shared_cache: false
|
37
|
+
|
38
|
+
conn.adapter Faraday.default_adapter
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def strategy
|
45
|
+
@strategy ||= strategy_class.new(nil, RailsSso.provider_key, RailsSso.provider_secret)
|
46
|
+
end
|
47
|
+
|
48
|
+
def strategy_class
|
49
|
+
"OmniAuth::Strategies::#{RailsSso.provider_name.classify}".constantize
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/rails_sso/helpers.rb
CHANGED
@@ -7,7 +7,9 @@ module RailsSso
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def current_user
|
10
|
-
@current_user ||= fetch_user
|
10
|
+
@current_user ||= fetch_user do |user|
|
11
|
+
update_user(user).call
|
12
|
+
end
|
11
13
|
end
|
12
14
|
|
13
15
|
def user_signed_in?
|
@@ -18,7 +20,11 @@ module RailsSso
|
|
18
20
|
redirect_to sign_in_path unless user_signed_in?
|
19
21
|
end
|
20
22
|
|
21
|
-
def
|
23
|
+
def access_token
|
24
|
+
RailsSso::AccessToken.new(session[:access_token], session[:refresh_token])
|
25
|
+
end
|
26
|
+
|
27
|
+
def invalidate_access_token!
|
22
28
|
if RailsSso.provider_sign_out_path
|
23
29
|
access_token.delete(RailsSso.provider_sign_out_path)
|
24
30
|
end
|
@@ -26,32 +32,40 @@ module RailsSso
|
|
26
32
|
reset_session
|
27
33
|
end
|
28
34
|
|
29
|
-
|
35
|
+
def save_access_token!(access_token)
|
36
|
+
session[:access_token] = access_token.token
|
37
|
+
session[:refresh_token] = access_token.refresh_token
|
38
|
+
end
|
30
39
|
|
31
|
-
def
|
32
|
-
|
40
|
+
def refresh_access_token!
|
41
|
+
save_access_token!(access_token.refresh!)
|
33
42
|
|
34
|
-
|
43
|
+
yield if block_given?
|
35
44
|
rescue ::OAuth2::Error
|
36
45
|
nil
|
37
46
|
end
|
38
47
|
|
39
|
-
|
40
|
-
OAuth2::AccessToken.new(oauth_client, session[:access_token], {
|
41
|
-
refresh_token: session[:refresh_token]
|
42
|
-
})
|
43
|
-
end
|
48
|
+
private
|
44
49
|
|
45
|
-
def
|
46
|
-
|
50
|
+
def fetch_user(&block)
|
51
|
+
return unless session[:access_token]
|
52
|
+
|
53
|
+
RailsSso::FetchUser.new(access_token).call(&block)
|
54
|
+
rescue ::OAuth2::Error
|
55
|
+
refresh_access_token! do
|
56
|
+
RailsSso::FetchUser.new(access_token).call(&block)
|
57
|
+
end
|
47
58
|
end
|
48
59
|
|
49
|
-
def
|
50
|
-
|
60
|
+
def update_user(data)
|
61
|
+
RailsSso::UpdateUser.new(data, update_user_options).call
|
51
62
|
end
|
52
63
|
|
53
|
-
def
|
54
|
-
|
64
|
+
def update_user_options
|
65
|
+
{
|
66
|
+
fields: RailsSso.user_fields,
|
67
|
+
repository: RailsSso.user_repository.new
|
68
|
+
}
|
55
69
|
end
|
56
70
|
end
|
57
71
|
end
|
data/lib/rails_sso/version.rb
CHANGED
data/lib/rails_sso.rb
CHANGED
@@ -14,6 +14,9 @@ module RailsSso
|
|
14
14
|
mattr_accessor :user_fields
|
15
15
|
@@user_fields = [:email]
|
16
16
|
|
17
|
+
mattr_accessor :use_cache
|
18
|
+
@@use_cache = false
|
19
|
+
|
17
20
|
def self.configure
|
18
21
|
yield self
|
19
22
|
end
|
@@ -27,8 +30,8 @@ module RailsSso
|
|
27
30
|
end
|
28
31
|
end
|
29
32
|
|
33
|
+
require 'omniauth-oauth2'
|
30
34
|
require 'rails_sso/version'
|
31
35
|
require 'rails_sso/engine'
|
32
36
|
require 'rails_sso/helpers'
|
33
|
-
require 'rails_sso/
|
34
|
-
require 'rails_sso/fetch_user'
|
37
|
+
require 'rails_sso/access_token'
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class RailsSso::SessionsControllerTest < ActionController::TestCase
|
4
|
+
def setup
|
5
|
+
@routes = RailsSso::Engine.routes
|
6
|
+
|
7
|
+
@auth_hash = OmniAuth::AuthHash.new({
|
8
|
+
provider: 'developer',
|
9
|
+
uid: '1',
|
10
|
+
name: 'Kowalski',
|
11
|
+
email: 'jan@kowalski.pl',
|
12
|
+
key: 'value'
|
13
|
+
})
|
14
|
+
|
15
|
+
OmniAuth.config.mock_auth[:developer] = @auth_hash
|
16
|
+
|
17
|
+
request.env['omniauth.auth'] = OmniAuth.config.mock_auth[:developer]
|
18
|
+
end
|
19
|
+
|
20
|
+
def teardown
|
21
|
+
OmniAuth.config.mock_auth[:developer] = nil
|
22
|
+
end
|
23
|
+
|
24
|
+
test 'create should save access token and redirect to root path' do
|
25
|
+
@controller.expects(:save_access_token!).with(@auth_hash.credentials).once
|
26
|
+
|
27
|
+
get :create, { provider: 'developer' }
|
28
|
+
|
29
|
+
assert_redirected_to main_app.root_path
|
30
|
+
end
|
31
|
+
|
32
|
+
test 'destroy should invalidate access token and redirect to root path' do
|
33
|
+
@controller.expects(:invalidate_access_token!).once
|
34
|
+
|
35
|
+
delete :destroy, {}, { access_token: 'abc', refresh_token: 'def' }
|
36
|
+
|
37
|
+
assert_redirected_to main_app.root_path
|
38
|
+
end
|
39
|
+
|
40
|
+
def main_app
|
41
|
+
Rails.application.class.routes.url_helpers
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
RailsSso.configure do |config|
|
2
|
+
config.provider_name = 'developer'
|
3
|
+
config.provider_key = 'key'
|
4
|
+
config.provider_secret = 'secret'
|
5
|
+
config.provider_profile_path = '/api/v1/me'
|
6
|
+
config.provider_sign_out_path = '/api/v1/me'
|
7
|
+
config.use_cache = false
|
8
|
+
config.user_fields = [
|
9
|
+
:email,
|
10
|
+
:name
|
11
|
+
]
|
12
|
+
config.user_repository = 'UserRepository'
|
13
|
+
end
|
data/test/dummy/config/routes.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
Rails.application.routes.draw do
|
2
|
+
mount RailsSso::Engine => '/sso', as: 'sso'
|
2
3
|
# The priority is based upon order of creation: first created -> highest priority.
|
3
4
|
# See how all your routes lay out with "rake routes".
|
4
5
|
|
@@ -53,4 +54,5 @@ Rails.application.routes.draw do
|
|
53
54
|
# # (app/controllers/admin/products_controller.rb)
|
54
55
|
# resources :products
|
55
56
|
# end
|
57
|
+
root to: 'application#index'
|
56
58
|
end
|
File without changes
|