rails_sso 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6c8245291e6e960c35dfa2e46a034e44ba3ee1d0
4
- data.tar.gz: acbd5d0746f35fcdb1e9bf0ff2ba727a00393d4c
3
+ metadata.gz: 5d21cea945bc44cb3fb84f1d2da048091d6f4661
4
+ data.tar.gz: 9f4bef5ac2353b226593a063a301cad4f618818a
5
5
  SHA512:
6
- metadata.gz: 207514bc02f2ed7fbede366398fb45b79d76341b7173e92c78a937ddbb7b3afcf75d9a11d1020a5d6e470c05f06e77d74c7acf74a9492bc9a38ab458665fa4e3
7
- data.tar.gz: 2326dd8b701d1797e3c970c6436d09c428c08cc60cf39c82f28c4928b3fe948d599ed8f469f52bec7682d94acf30d5bb192967833b8024724116a5eb169be568
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
+ [![Dependency Status](https://gemnasium.com/monterail/rails_sso.svg)](https://gemnasium.com/monterail/rails_sso)
4
+ [![Gem Version](https://badge.fury.io/rb/rails_sso.svg)](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
- * `find_by({ key: value })`
73
- * `create_with_id(id, attrs)`
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 find_by(attrs)
89
- adapter.find_by(attrs)
99
+ def find_by_sso_id(id)
100
+ adapter.find_by(sso_id: id)
90
101
  end
91
102
 
92
- def create_with_id(id, attrs)
103
+ def create_with_sso_id(id, attrs)
93
104
  adapter.new(attrs) do |user|
94
- user.id = id
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
- session[:access_token] = auth_hash.credentials.token
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
- invalidate_user!
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.delete('id'), 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.find_by(id: id)
9
+ if user = repository.find_by_sso_id(id)
10
10
  repository.update(user, params)
11
11
  user
12
12
  else
13
- repository.create_with_id(id, params)
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
@@ -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 invalidate_user!
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
- private
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 fetch_user
32
- return unless session[:access_token]
40
+ def refresh_access_token!
41
+ save_access_token!(access_token.refresh!)
33
42
 
34
- RailsSso::FetchUser.new(access_token, session).get_and_cache
43
+ yield if block_given?
35
44
  rescue ::OAuth2::Error
36
45
  nil
37
46
  end
38
47
 
39
- def access_token
40
- OAuth2::AccessToken.new(oauth_client, session[:access_token], {
41
- refresh_token: session[:refresh_token]
42
- })
43
- end
48
+ private
44
49
 
45
- def oauth_client
46
- oauth_strategy.client
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 oauth_strategy
50
- oauth_strategy_class.new(nil, RailsSso.provider_key, RailsSso.provider_secret)
60
+ def update_user(data)
61
+ RailsSso::UpdateUser.new(data, update_user_options).call
51
62
  end
52
63
 
53
- def oauth_strategy_class
54
- "OmniAuth::Strategies::#{RailsSso.provider_name.classify}".constantize
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
@@ -1,3 +1,3 @@
1
1
  module RailsSso
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
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/update_user'
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
@@ -2,4 +2,8 @@ class ApplicationController < ActionController::Base
2
2
  # Prevent CSRF attacks by raising an exception.
3
3
  # For APIs, you may want to use :null_session instead.
4
4
  protect_from_forgery with: :exception
5
+
6
+ def index
7
+ render text: 'Hello'
8
+ end
5
9
  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
@@ -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