doorkeeper_sso 0.4.1 → 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/models/sso/pingback.rb +1 -12
- data/lib/sso.rb +4 -3
- data/lib/sso/doorkeeper/application_controller_mixin.rb +43 -0
- data/lib/sso/doorkeeper/authorization.rb +10 -0
- data/lib/sso/doorkeeper/authorization/code_mixin.rb +0 -4
- data/lib/sso/doorkeeper/authorization/token_mixin.rb +1 -4
- data/lib/sso/doorkeeper/oauth.rb +10 -0
- data/lib/sso/doorkeeper/oauth/authorization_code_request_mixin.rb +13 -0
- data/lib/sso/doorkeeper/oauth/base.rb +22 -0
- data/lib/sso/engine.rb +24 -7
- data/lib/sso/engine.rb.orig +71 -0
- data/lib/sso/version.rb +1 -1
- data/lib/sso/warden/hooks/before_logout.rb +1 -0
- data/lib/sso/warden/hooks/create_master_session.rb +8 -5
- data/spec/lib/sso/warden/hooks/before_logout_spec.rb +6 -1
- data/spec/lib/sso/warden/hooks/create_master_session_spec.rb +7 -15
- data/spec/request/oauth/authorization_code_spec.rb +122 -0
- metadata +10 -9
- data/lib/doorkeeper/oauth/request_concern.rb +0 -12
- data/lib/sso/doorkeeper/authorizations_controller_mixin.rb +0 -48
- data/lib/sso/doorkeeper/tokens_controller_mixin.rb +0 -55
- data/spec/lib/doorkeeper/authorizations_controller_mixin_spec.rb +0 -65
- data/spec/lib/doorkeeper/tokens_controller_mixin_spec.rb +0 -72
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0ca0ce3b31e9f84891cca3a72dddd92d8b401bf2
|
4
|
+
data.tar.gz: 926a26fbbec7d49bb05a2b71fd4db19f85a6f5fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5b96c999fe8b444644bc6b1c5faa131d7f0950a4e391da11ab6a71a0255ec58538dd4636887965fb4542a20f3b550718117bda9d9c8a9a27dcacc66a8e43b645
|
7
|
+
data.tar.gz: 32e6a6a7460f9c5b2e37901f637ad5db92afe1ff4c29e573ee1efe0a620c7ddf204b603b4c5aec7fe22375b7274c03180e29cb702c51b30b23f84be46c976d44
|
data/app/models/sso/pingback.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module Sso
|
2
2
|
class Pingback
|
3
3
|
include ::Sso::Logging
|
4
|
+
include ::Sso::Warden::Support
|
4
5
|
|
5
6
|
attr_reader :user, :warden, :options
|
6
7
|
delegate :request, to: :warden
|
@@ -32,17 +33,5 @@ module Sso
|
|
32
33
|
end
|
33
34
|
end
|
34
35
|
end
|
35
|
-
|
36
|
-
def scope
|
37
|
-
scope = options[:scope]
|
38
|
-
end
|
39
|
-
|
40
|
-
def session
|
41
|
-
warden.session(scope)
|
42
|
-
end
|
43
|
-
|
44
|
-
def logged_in?
|
45
|
-
warden.authenticated?(scope) && session && user
|
46
|
-
end
|
47
36
|
end
|
48
37
|
end
|
data/lib/sso.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require "doorkeeper/oauth/request_concern"
|
2
1
|
require "sso/engine"
|
3
2
|
require "sso/logging"
|
4
3
|
require "sso/warden/support"
|
@@ -8,8 +7,9 @@ require "sso/warden/hooks/session_check"
|
|
8
7
|
require "sso/doorkeeper/access_grant_mixin"
|
9
8
|
require "sso/doorkeeper/access_token_mixin"
|
10
9
|
require "sso/doorkeeper/application_mixin"
|
11
|
-
require "sso/doorkeeper/
|
12
|
-
require "sso/doorkeeper/
|
10
|
+
require "sso/doorkeeper/application_controller_mixin"
|
11
|
+
require "sso/doorkeeper/authorization"
|
12
|
+
require "sso/doorkeeper/oauth"
|
13
13
|
|
14
14
|
|
15
15
|
module Sso
|
@@ -17,3 +17,4 @@ module Sso
|
|
17
17
|
'sso_'
|
18
18
|
end
|
19
19
|
end
|
20
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Sso
|
2
|
+
module Doorkeeper
|
3
|
+
module ApplicationControllerMixin
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
include ::Sso::Logging
|
6
|
+
|
7
|
+
included do
|
8
|
+
around_filter :subscribe_to_grant_creation
|
9
|
+
end
|
10
|
+
|
11
|
+
def subscribe_to_grant_creation
|
12
|
+
Wisper.subscribe(self) do
|
13
|
+
yield
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def warden_user_session
|
18
|
+
warden.session(:user)
|
19
|
+
end
|
20
|
+
|
21
|
+
def access_grant_created(token_id)
|
22
|
+
debug { "Wisper#access_grant_created grant - #{token_id}" }
|
23
|
+
oauth_grant = ::Doorkeeper::AccessGrant.find(token_id)
|
24
|
+
|
25
|
+
generate_sso_session if warden_user_session["sso_session_id"].blank?
|
26
|
+
sso_session = Sso::Session.find(warden_user_session["sso_session_id"])
|
27
|
+
|
28
|
+
debug { "Sso::Session.update_master_with_grant - #{sso_session.id.inspect}, #{oauth_grant.inspect}" }
|
29
|
+
sso_session.clients.find_or_create_by!(access_grant_id: oauth_grant.id, application_id: oauth_grant.application_id)
|
30
|
+
rescue => e
|
31
|
+
sso_session.try(:logout)
|
32
|
+
raise
|
33
|
+
end
|
34
|
+
|
35
|
+
def generate_sso_session
|
36
|
+
debug { "Sso:Session doesn't exist for user #{user.id.inspect}. Generate new one" }
|
37
|
+
attributes = { ip: request.ip, agent: request.user_agent }
|
38
|
+
sso_session = Sso::Session.generate_master(user, attributes)
|
39
|
+
warden_user_session["sso_session_id"] = sso_session.id.to_s
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -5,15 +5,11 @@ module Sso
|
|
5
5
|
module Doorkeeper
|
6
6
|
module Authorization
|
7
7
|
module CodeMixin
|
8
|
-
extend ActiveSupport::Concern
|
9
|
-
include ::Sso::Logging
|
10
|
-
|
11
8
|
def issue_token
|
12
9
|
super
|
13
10
|
broadcast(:access_grant_created, token.id) if @token.try(:id)
|
14
11
|
@token
|
15
12
|
end
|
16
|
-
|
17
13
|
end
|
18
14
|
end
|
19
15
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Sso
|
2
|
+
module Doorkeeper
|
3
|
+
module OAuth
|
4
|
+
module Base
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
def sso_client
|
8
|
+
return @sso_client if @sso_client
|
9
|
+
|
10
|
+
user = User.find(@access_token.resource_owner_id)
|
11
|
+
sso_session = Sso::Session.generate_master(user, {})
|
12
|
+
@sso_client = sso_session.clients.last
|
13
|
+
end
|
14
|
+
|
15
|
+
def after_successful_response
|
16
|
+
self.sso_client.update_attributes(access_token_id: @access_token.id)
|
17
|
+
super
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/sso/engine.rb
CHANGED
@@ -22,14 +22,31 @@ module Sso
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
+
config.before_initialize do
|
26
|
+
[::Wisper::Publisher].each do |klass|
|
27
|
+
::Doorkeeper::OAuth::Authorization::Code.send(:include, klass)
|
28
|
+
::Doorkeeper::OAuth::Authorization::Token.send(:include, klass)
|
29
|
+
end
|
30
|
+
|
31
|
+
::Doorkeeper::ApplicationMetalController.send(:include, ::AbstractController::Callbacks)
|
32
|
+
end
|
33
|
+
|
25
34
|
config.after_initialize do
|
26
|
-
::Doorkeeper::
|
27
|
-
::Doorkeeper::
|
28
|
-
|
29
|
-
|
30
|
-
::Doorkeeper::
|
31
|
-
::Doorkeeper::
|
32
|
-
::Doorkeeper::
|
35
|
+
::Doorkeeper::OAuth::Authorization::Code.send(:prepend, ::Sso::Doorkeeper::Authorization::CodeMixin)
|
36
|
+
::Doorkeeper::OAuth::Authorization::Token.send(:prepend, ::Sso::Doorkeeper::Authorization::TokenMixin)
|
37
|
+
|
38
|
+
# Patch every class that includes RequestConcern
|
39
|
+
::Doorkeeper::OAuth::AuthorizationCodeRequest.send(:prepend, ::Sso::Doorkeeper::OAuth::AuthorizationCodeRequestMixin)
|
40
|
+
::Doorkeeper::OAuth::ClientCredentialsRequest.send(:include, ::Sso::Doorkeeper::OAuth::Base)
|
41
|
+
::Doorkeeper::OAuth::PasswordAccessTokenRequest.send(:include, ::Sso::Doorkeeper::OAuth::Base)
|
42
|
+
::Doorkeeper::OAuth::RefreshTokenRequest.send(:include, ::Sso::Doorkeeper::OAuth::Base)
|
43
|
+
|
44
|
+
::Doorkeeper::Application.send(:include, ::Sso::Doorkeeper::ApplicationMixin)
|
45
|
+
::Doorkeeper::AccessGrant.send(:include, ::Sso::Doorkeeper::AccessGrantMixin)
|
46
|
+
::Doorkeeper::AccessToken.send(:include, ::Sso::Doorkeeper::AccessTokenMixin)
|
47
|
+
|
48
|
+
::Doorkeeper::ApplicationController.send(:include, ::Sso::Doorkeeper::ApplicationControllerMixin)
|
49
|
+
# ::Doorkeeper::ApplicationMetalController.send(:include, ::Sso::Doorkeeper::ApplicationControllerMixin)
|
33
50
|
|
34
51
|
::Warden::Manager.after_set_user(scope: :user, except: :fetch, &::Sso::Warden::Hooks::CreateMasterSession.to_proc)
|
35
52
|
::Warden::Manager.before_logout(scope: :user, &::Sso::Warden::Hooks::BeforeLogout.to_proc)
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Sso
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
isolate_namespace Sso
|
4
|
+
|
5
|
+
# New test framework integration
|
6
|
+
config.generators do |g|
|
7
|
+
g.test_framework :rspec,
|
8
|
+
:fixtures => true,
|
9
|
+
:view_specs => false,
|
10
|
+
:helper_specs => false,
|
11
|
+
:routing_specs => false,
|
12
|
+
:controller_specs => true,
|
13
|
+
:request_specs => false
|
14
|
+
g.fixture_replacement :fabrication
|
15
|
+
end
|
16
|
+
|
17
|
+
initializer :append_migrations do |app|
|
18
|
+
unless app.root.to_s.match root.to_s
|
19
|
+
config.paths["db/migrate"].expanded.each do |expanded_path|
|
20
|
+
app.config.paths["db/migrate"] << expanded_path
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
config.before_initialize do
|
26
|
+
[::Sso::Logging, ::Wisper::Publisher].each do |klass|
|
27
|
+
::Doorkeeper::OAuth::RequestConcern.send(:include, klass)
|
28
|
+
::Doorkeeper::OAuth::Authorization::Code.send(:include, klass)
|
29
|
+
::Doorkeeper::OAuth::Authorization::Token.send(:include, klass)
|
30
|
+
end
|
31
|
+
|
32
|
+
::Doorkeeper::ApplicationMetalController.send(:include, ::AbstractController::Callbacks)
|
33
|
+
|
34
|
+
# need a better way to fix this
|
35
|
+
::Doorkeeper::OAuth::RequestConcern.class_eval do
|
36
|
+
def after_successful_response
|
37
|
+
raise "RequestConcern#token - #{@access_token.inspect}"
|
38
|
+
broadcast(:access_token_request_successful, @access_token.id)
|
39
|
+
super
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
config.after_initialize do
|
45
|
+
|
46
|
+
::Doorkeeper::OAuth::Authorization::Code.send(:prepend, ::Sso::Doorkeeper::Authorization::CodeMixin)
|
47
|
+
::Doorkeeper::OAuth::Authorization::Token.send(:prepend, ::Sso::Doorkeeper::Authorization::TokenMixin)
|
48
|
+
::Doorkeeper::Application.send(:include, ::Sso::Doorkeeper::ApplicationMixin)
|
49
|
+
::Doorkeeper::AccessGrant.send(:include, ::Sso::Doorkeeper::AccessGrantMixin)
|
50
|
+
::Doorkeeper::AccessToken.send(:include, ::Sso::Doorkeeper::AccessTokenMixin)
|
51
|
+
::Doorkeeper::ApplicationMetalController.send(:include, ::Sso::Doorkeeper::ApplicationControllerMixin)
|
52
|
+
::Doorkeeper::ApplicationController.send(:include, ::Sso::Doorkeeper::ApplicationControllerMixin)
|
53
|
+
# ::Doorkeeper::TokensController.send(:include, ::AbstractController::Callbacks)
|
54
|
+
# ::Doorkeeper::TokensController.send(:include, ::Sso::Doorkeeper::TokensControllerMixin)
|
55
|
+
# ::Doorkeeper::AuthorizationsController.send(:include, ::Sso::Doorkeeper::AuthorizationsControllerMixin)
|
56
|
+
|
57
|
+
<<<<<<< HEAD
|
58
|
+
::Warden::Manager.after_set_user(scope: :user, &::Sso::Warden::Hooks::CreateMasterSession.to_proc)
|
59
|
+
=======
|
60
|
+
>>>>>>> Use wisper to broadcast when token is created
|
61
|
+
::Warden::Manager.after_set_user(scope: :user, except: :fetch, &::Sso::Warden::Hooks::CreateMasterSession.to_proc)
|
62
|
+
::Warden::Manager.before_logout(scope: :user, &::Sso::Warden::Hooks::BeforeLogout.to_proc)
|
63
|
+
|
64
|
+
# TODO : Do we want to ensure that session is always active?
|
65
|
+
# ::Warden::Manager.after_fetch(scope: :user, &::Sso::Warden::Hooks::SessionCheck.to_proc)
|
66
|
+
|
67
|
+
# TODO : Why does it need a passport strategy
|
68
|
+
# Warden::Strategies.add :passport, ::Sso::Server::Warden::Strategies::Passport
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/sso/version.rb
CHANGED
@@ -5,12 +5,15 @@ module Sso
|
|
5
5
|
include ::Sso::Warden::Support
|
6
6
|
|
7
7
|
def call
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
::Sso::Session.logout(session["sso_session_id"])
|
12
|
-
generate_session
|
8
|
+
unless logged_in?
|
9
|
+
throw(:warden)
|
10
|
+
raise "DoorkeeperSso : CreateMasterSession requires an authenticated session" and return
|
13
11
|
end
|
12
|
+
|
13
|
+
debug { "NEW USER WARDEN SESSION" }
|
14
|
+
debug { "Log out previous Sso:Session if exists : ID #{session['sso_session_id']}" }
|
15
|
+
::Sso::Session.logout(session["sso_session_id"])
|
16
|
+
generate_session
|
14
17
|
return nil
|
15
18
|
end
|
16
19
|
|
@@ -32,7 +32,7 @@ RSpec.describe Sso::Warden::Hooks::BeforeLogout do
|
|
32
32
|
|
33
33
|
it "run #logout" do
|
34
34
|
expect(::Sso::Session).to receive(:logout).with(session.id)
|
35
|
-
|
35
|
+
rack.call
|
36
36
|
end
|
37
37
|
|
38
38
|
it 'revokes the passport' do
|
@@ -41,6 +41,11 @@ RSpec.describe Sso::Warden::Hooks::BeforeLogout do
|
|
41
41
|
expect(session.revoked_at.to_i).to eq Time.now.to_i
|
42
42
|
expect(session.revoke_reason).to eq 'logout'
|
43
43
|
end
|
44
|
+
|
45
|
+
it 'clears session' do
|
46
|
+
rack.call
|
47
|
+
expect(rack.session["sso_session_id"]).to be_nil
|
48
|
+
end
|
44
49
|
end
|
45
50
|
|
46
51
|
context "when logged_out" do
|
@@ -33,15 +33,14 @@ RSpec.describe Sso::Warden::Hooks::CreateMasterSession do
|
|
33
33
|
context 'existing session' do
|
34
34
|
let(:sso_params) { { :ip => "202.188.0.133", :agent => "Chrome" } }
|
35
35
|
let(:sso_session) { ::Sso::Session.generate_master(user, sso_params ) }
|
36
|
-
let
|
36
|
+
let(:sso_session_id) { sso_session.id }
|
37
|
+
let!(:session_params) { { "sso_session_id" => sso_session_id } }
|
37
38
|
|
38
|
-
|
39
|
-
|
40
|
-
it { expect(::Sso::Session.count).to eq 2 }
|
41
|
-
it { expect(::Sso::Session.find_by_id(sso_session.id).revoke_reason).to eq "logout" }
|
39
|
+
it { rack.call; expect(::Sso::Session.count).to eq 2 }
|
40
|
+
it { rack.call; expect(::Sso::Session.find_by_id(sso_session.id).revoke_reason).to eq "logout" }
|
42
41
|
|
43
42
|
it "runs Sso::Session.logout" do
|
44
|
-
expect(::Sso::Session).to receive(:logout).with(
|
43
|
+
expect(::Sso::Session).to receive(:logout).with(sso_session_id)
|
45
44
|
rack.call
|
46
45
|
end
|
47
46
|
end
|
@@ -49,16 +48,9 @@ RSpec.describe Sso::Warden::Hooks::CreateMasterSession do
|
|
49
48
|
context 'logged out' do
|
50
49
|
let(:user) { nil }
|
51
50
|
|
52
|
-
|
53
|
-
|
54
|
-
it "will not run Sso::Session.logout" do
|
51
|
+
it "will not run Sso::Session.logout but throw :warden" do
|
55
52
|
expect(::Sso::Session).not_to receive(:logout)
|
56
|
-
rack.call
|
57
|
-
end
|
58
|
-
|
59
|
-
it "will not run #generate_session" do
|
60
|
-
expect(rack).not_to receive(:generate_session)
|
61
|
-
rack.call
|
53
|
+
expect { rack.call }.to raise_exception("uncaught throw :warden")
|
62
54
|
end
|
63
55
|
end
|
64
56
|
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
RSpec.describe 'OAuth 2.0 Authorization Grant Flow', type: :request, db: true do
|
4
|
+
|
5
|
+
let!(:user) { Fabricate(:user, password: "bumblebee") }
|
6
|
+
let!(:doorkeeper_application) { Fabricate('Doorkeeper::Application') }
|
7
|
+
let(:redirect_uri) { doorkeeper_application.redirect_uri }
|
8
|
+
|
9
|
+
let(:grant_params) { { client_id: doorkeeper_application.uid, redirect_uri: redirect_uri, response_type: "code", state: 'some_random_string' } } # client_id=04364b30de79090493f079724571899eece7791b5af54e5866d73c6aaf167ec9&redirect_uri=http%3A%2F%2Flaunchpad.dev%2Fauth%2Fmindvalley%2Fcallback&response_type=code&state=a82b7b992c78ed7c47aba11340cdea76cc5ecc4ffe62ef39
|
10
|
+
|
11
|
+
let(:result) { JSON.parse(response.body) }
|
12
|
+
|
13
|
+
let(:latest_grant) { ::Doorkeeper::AccessGrant.last }
|
14
|
+
let(:latest_access_token) { ::Doorkeeper::AccessToken.last }
|
15
|
+
let(:access_token_count) { ::Doorkeeper::AccessToken.count }
|
16
|
+
let(:grant_count) { ::Doorkeeper::AccessGrant.count }
|
17
|
+
|
18
|
+
let(:latest_passport) { ::SSO::Session.last }
|
19
|
+
let(:passport_count) { ::SSO::Session.last.count }
|
20
|
+
|
21
|
+
before do
|
22
|
+
get_via_redirect '/oauth/authorize', grant_params
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'shows to the login page' do
|
26
|
+
expect(response).to render_template 'devise/sessions/new'
|
27
|
+
end
|
28
|
+
|
29
|
+
describe 'Logging in' do
|
30
|
+
before do
|
31
|
+
post '/login', user: { email: user.email, password: "bumblebee" }
|
32
|
+
follow_redirect!
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'redirects to the application callback including the Grant Token' do
|
36
|
+
#expect(latest_grant).to be_present
|
37
|
+
expect(response.body).to eq 1 #redirect_to "#{doorkeeper_application.redirect_uri}?code=#{latest_grant.token}&state=some_random_string"
|
38
|
+
end
|
39
|
+
|
40
|
+
# it 'generates a passport with the grant token attached to it' do
|
41
|
+
# expect(latest_passport.oauth_access_grant_id).to eq latest_grant.id
|
42
|
+
# end
|
43
|
+
|
44
|
+
# it 'does not generate multiple authorization grants' do
|
45
|
+
# expect(grant_count).to eq 1
|
46
|
+
# end
|
47
|
+
|
48
|
+
pending 'Exchanging the Authorization Grant for an Access Token' do
|
49
|
+
let(:grant) { ::Rack::Utils.parse_query(URI.parse(response.location).query).fetch('code') }
|
50
|
+
let(:grant_type) { :authorization_code }
|
51
|
+
let(:params) { { doorkeeper_application_id: doorkeeper_application.uid, doorkeeper_application_secret: doorkeeper_application.secret, code: grant, grant_type: grant_type, redirect_uri: redirect_uri } }
|
52
|
+
let(:token) { JSON.parse(response.body).fetch 'access_token' }
|
53
|
+
|
54
|
+
before do
|
55
|
+
post '/oauth/token', params
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'succeeds' do
|
59
|
+
expect(response.status).to eq 200
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'responds with JSON serialized params' do
|
63
|
+
expect(result).to be_instance_of Hash
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'includes the access_token' do
|
67
|
+
expect(result['access_token']).to eq latest_access_token.token
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'generates a passport with the grant token attached to it' do
|
71
|
+
expect(latest_passport.oauth_access_token_id).to eq latest_access_token.id
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'does not generate multiple passports' do
|
75
|
+
expect(passport_count).to eq 1
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'does not generate multiple access tokens' do
|
79
|
+
expect(access_token_count).to eq 1
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'succeeds' do
|
83
|
+
expect(response.status).to eq 200
|
84
|
+
end
|
85
|
+
|
86
|
+
pending 'Exchanging the Access Token for a Passport' do
|
87
|
+
before do
|
88
|
+
SSO.config.passport_chip_key = SecureRandom.hex
|
89
|
+
post '/oauth/sso/v1/passports', access_token: token
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'succeeds' do
|
93
|
+
expect(response.status).to eq 200
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'gets the passport' do
|
97
|
+
expect(result['passport']).to be_present
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'is the passport for that access token' do
|
101
|
+
expect(result['passport']['id']).to eq latest_passport.id
|
102
|
+
expect(latest_passport.oauth_access_token_id).to eq latest_access_token.id
|
103
|
+
end
|
104
|
+
|
105
|
+
pending 'is an outsider passport' do
|
106
|
+
expect(latest_passport).to_not be_insider
|
107
|
+
end
|
108
|
+
|
109
|
+
pending 'insider application' do
|
110
|
+
let!(:doorkeeper_application) { Fabricate('Doorkeeper::Application') }
|
111
|
+
let(:scope) { :insider }
|
112
|
+
|
113
|
+
it 'is an insider passport' do
|
114
|
+
expect(latest_passport).to be_insider
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: doorkeeper_sso
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Wong
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-09-
|
11
|
+
date: 2015-09-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: warden
|
@@ -348,17 +348,20 @@ files:
|
|
348
348
|
- db/migrate/20150521142926_create_sso_clients.rb
|
349
349
|
- db/migrate/20150521165143_remove_extra_columns_from_sso_sessions.rb
|
350
350
|
- db/migrate/20150603145730_add_pingback_uri_to_doorkeeper_applications.rb
|
351
|
-
- lib/doorkeeper/oauth/request_concern.rb
|
352
351
|
- lib/doorkeeper_sso.rb
|
353
352
|
- lib/sso.rb
|
354
353
|
- lib/sso/doorkeeper/access_grant_mixin.rb
|
355
354
|
- lib/sso/doorkeeper/access_token_mixin.rb
|
355
|
+
- lib/sso/doorkeeper/application_controller_mixin.rb
|
356
356
|
- lib/sso/doorkeeper/application_mixin.rb
|
357
|
+
- lib/sso/doorkeeper/authorization.rb
|
357
358
|
- lib/sso/doorkeeper/authorization/code_mixin.rb
|
358
359
|
- lib/sso/doorkeeper/authorization/token_mixin.rb
|
359
|
-
- lib/sso/doorkeeper/
|
360
|
-
- lib/sso/doorkeeper/
|
360
|
+
- lib/sso/doorkeeper/oauth.rb
|
361
|
+
- lib/sso/doorkeeper/oauth/authorization_code_request_mixin.rb
|
362
|
+
- lib/sso/doorkeeper/oauth/base.rb
|
361
363
|
- lib/sso/engine.rb
|
364
|
+
- lib/sso/engine.rb.orig
|
362
365
|
- lib/sso/logging.rb
|
363
366
|
- lib/sso/version.rb
|
364
367
|
- lib/sso/warden/hooks/before_logout.rb
|
@@ -378,14 +381,13 @@ files:
|
|
378
381
|
- spec/lib/doorkeeper/access_grant_mixin_spec.rb
|
379
382
|
- spec/lib/doorkeeper/access_token_mixin_spec.rb
|
380
383
|
- spec/lib/doorkeeper/application_mixin_spec.rb
|
381
|
-
- spec/lib/doorkeeper/authorizations_controller_mixin_spec.rb
|
382
|
-
- spec/lib/doorkeeper/tokens_controller_mixin_spec.rb
|
383
384
|
- spec/lib/sso/warden/hooks/before_logout_spec.rb
|
384
385
|
- spec/lib/sso/warden/hooks/create_master_session_spec.rb
|
385
386
|
- spec/models/sso/client_spec.rb
|
386
387
|
- spec/models/sso/pingback_spec.rb
|
387
388
|
- spec/models/sso/session_spec.rb
|
388
389
|
- spec/rails_helper.rb
|
390
|
+
- spec/request/oauth/authorization_code_spec.rb
|
389
391
|
- spec/spec_helper.rb
|
390
392
|
- spec/support/api_schema_matcher.rb
|
391
393
|
- spec/support/database_cleaner.rb
|
@@ -438,14 +440,13 @@ test_files:
|
|
438
440
|
- spec/lib/doorkeeper/access_grant_mixin_spec.rb
|
439
441
|
- spec/lib/doorkeeper/access_token_mixin_spec.rb
|
440
442
|
- spec/lib/doorkeeper/application_mixin_spec.rb
|
441
|
-
- spec/lib/doorkeeper/authorizations_controller_mixin_spec.rb
|
442
|
-
- spec/lib/doorkeeper/tokens_controller_mixin_spec.rb
|
443
443
|
- spec/lib/sso/warden/hooks/before_logout_spec.rb
|
444
444
|
- spec/lib/sso/warden/hooks/create_master_session_spec.rb
|
445
445
|
- spec/models/sso/client_spec.rb
|
446
446
|
- spec/models/sso/pingback_spec.rb
|
447
447
|
- spec/models/sso/session_spec.rb
|
448
448
|
- spec/rails_helper.rb
|
449
|
+
- spec/request/oauth/authorization_code_spec.rb
|
449
450
|
- spec/spec_helper.rb
|
450
451
|
- spec/support/api_schema_matcher.rb
|
451
452
|
- spec/support/database_cleaner.rb
|
@@ -1,48 +0,0 @@
|
|
1
|
-
module Sso
|
2
|
-
module Doorkeeper
|
3
|
-
module AuthorizationsControllerMixin
|
4
|
-
extend ActiveSupport::Concern
|
5
|
-
include ::Sso::Logging
|
6
|
-
|
7
|
-
included do
|
8
|
-
around_action :subscribe_to_token_creation, only: [:new, :create]
|
9
|
-
after_action :after_grant_create, only: [:new, :create]
|
10
|
-
end
|
11
|
-
|
12
|
-
protected
|
13
|
-
|
14
|
-
def subscribe_to_token_creation
|
15
|
-
Wisper.subscribe(self) do
|
16
|
-
yield
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def access_token_created(token_id)
|
21
|
-
raise "AuthorizationsController#gives token - #{token_id}"
|
22
|
-
end
|
23
|
-
|
24
|
-
def after_grant_create
|
25
|
-
debug { "AuthorizationsController#Create : after_action" }
|
26
|
-
code_response = authorization.instance_variable_get("@response")
|
27
|
-
oauth_grant = code_response.try(:auth).try(:token)
|
28
|
-
|
29
|
-
warden_session = session["warden.user.user.session"] || {}
|
30
|
-
sso_session = Sso::Session.find_by_id(warden_session["sso_session_id"].to_s)
|
31
|
-
|
32
|
-
unless sso_session.try(:active?)
|
33
|
-
error { "ERROR : AuthorizationsControllerMixin - Sso::Session INACTIVE) #{sso_session.inspect}" }
|
34
|
-
return false
|
35
|
-
end
|
36
|
-
|
37
|
-
if oauth_grant
|
38
|
-
debug { "Sso::Session.update_master_with_grant - #{sso_session.id.inspect}, #{oauth_grant.inspect}" }
|
39
|
-
sso_session.clients.find_or_create_by!(access_grant_id: oauth_grant.id)
|
40
|
-
else
|
41
|
-
error { "ERROR : AuthorizationsControllerMixin - Unable to get grant id from #{oauth_grant.inspect}" }
|
42
|
-
sso_session.logout
|
43
|
-
return false
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
@@ -1,55 +0,0 @@
|
|
1
|
-
require 'active_support/concern'
|
2
|
-
|
3
|
-
module Sso
|
4
|
-
module Doorkeeper
|
5
|
-
module TokensControllerMixin
|
6
|
-
extend ActiveSupport::Concern
|
7
|
-
include ::Sso::Logging
|
8
|
-
|
9
|
-
included do
|
10
|
-
after_action :after_token_create, only: :create
|
11
|
-
end
|
12
|
-
|
13
|
-
protected
|
14
|
-
|
15
|
-
def after_token_create
|
16
|
-
debug { "TokensController#Create : after_action" }
|
17
|
-
handle_authorization_grant_flow
|
18
|
-
end
|
19
|
-
|
20
|
-
def handle_authorization_grant_flow
|
21
|
-
# We cannot rely on session[:sso_session_id] here because the end-user might have cookies disabled.
|
22
|
-
# The only thing we can rely on to identify the user/Passport is the incoming grant token.
|
23
|
-
debug { %(Detected outgoing "Access Token" #{outgoing_access_token.inspect}) }
|
24
|
-
|
25
|
-
unless client = ::Sso::Client.find_by_grant_token(grant_token)
|
26
|
-
return error_and_return "::Sso::Client not found for grant token #{grant_token}"
|
27
|
-
end
|
28
|
-
|
29
|
-
if client.update_access_token(outgoing_access_token)
|
30
|
-
debug { "::Sso::Client.update_access_token success for access_token: #{outgoing_access_token}" }
|
31
|
-
else
|
32
|
-
return error_and_return "::Sso::Session.update_access_token failed. #{client.errors.inspect}"
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def error_and_return(msg)
|
37
|
-
error { msg }
|
38
|
-
return false
|
39
|
-
end
|
40
|
-
|
41
|
-
def grant_token
|
42
|
-
params["code"]
|
43
|
-
end
|
44
|
-
|
45
|
-
def grant_type
|
46
|
-
params["grant_type"]
|
47
|
-
end
|
48
|
-
|
49
|
-
def outgoing_access_token
|
50
|
-
@response_hash ||= JSON.parse(response.body)
|
51
|
-
@response_hash["access_token"]
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
@@ -1,65 +0,0 @@
|
|
1
|
-
require 'rails_helper'
|
2
|
-
|
3
|
-
# Engine.rb automatically includes the mixin
|
4
|
-
|
5
|
-
RSpec.describe Doorkeeper::AuthorizationsController do
|
6
|
-
|
7
|
-
let(:user) { Fabricate(:user) }
|
8
|
-
let(:application) { Fabricate('Doorkeeper::Application') }
|
9
|
-
# let(:access_token) { Fabricate('Doorkeeper::AccessToken',
|
10
|
-
# resource_owner_id: user.id) }
|
11
|
-
let!(:access_grant) { Fabricate('Doorkeeper::AccessGrant',
|
12
|
-
application_id: application.id,
|
13
|
-
resource_owner_id: user.id,
|
14
|
-
redirect_uri: 'http://localhost:3002/oauth/callback'
|
15
|
-
) }
|
16
|
-
|
17
|
-
# Set up Session
|
18
|
-
let(:session) { Fabricate('Sso::Session', owner: user) }
|
19
|
-
let!(:client) { Fabricate('Sso::Client', session: session,
|
20
|
-
application_id: application.id) }
|
21
|
-
|
22
|
-
let(:auth) { double :auth, token: access_grant }
|
23
|
-
let(:code_response) { double :code_response, auth: auth }
|
24
|
-
let(:authorization) { double :authorization, instance_variable_get: code_response }
|
25
|
-
let(:warden_session) { { "warden.user.user.session" => { "sso_session_id" => session.id } } }
|
26
|
-
subject(:controller) { described_class.new }
|
27
|
-
|
28
|
-
|
29
|
-
before do
|
30
|
-
allow_any_instance_of(described_class).to receive(:authorization).and_return(authorization)
|
31
|
-
allow_any_instance_of(described_class).to receive(:session).and_return(warden_session)
|
32
|
-
end
|
33
|
-
|
34
|
-
describe "#after_grant_create" do
|
35
|
-
context "working" do
|
36
|
-
it "creates client with grant_id" do
|
37
|
-
controller.send(:after_grant_create)
|
38
|
-
expect(access_grant.sso_client).to be_a ::Sso::Client
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
context "no grant" do
|
43
|
-
let(:access_grant) { nil }
|
44
|
-
|
45
|
-
it "logs error" do
|
46
|
-
expect(controller).to receive(:error)
|
47
|
-
controller.send(:after_grant_create)
|
48
|
-
end
|
49
|
-
|
50
|
-
it "logout session" do
|
51
|
-
expect_any_instance_of(::Sso::Session).to receive(:logout).and_call_original
|
52
|
-
controller.send(:after_grant_create)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
context "no session" do
|
57
|
-
let(:warden_session) { {} }
|
58
|
-
|
59
|
-
it "logs error" do
|
60
|
-
expect(controller).to receive(:error)
|
61
|
-
controller.send(:after_grant_create)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
@@ -1,72 +0,0 @@
|
|
1
|
-
require 'rails_helper'
|
2
|
-
|
3
|
-
# Engine.rb automatically includes the mixin
|
4
|
-
|
5
|
-
RSpec.describe Doorkeeper::TokensController, :type => :controller do
|
6
|
-
|
7
|
-
let(:user) { Fabricate(:user) }
|
8
|
-
let(:application) { Fabricate('Doorkeeper::Application') }
|
9
|
-
let(:access_token) { Fabricate('Doorkeeper::AccessToken',
|
10
|
-
resource_owner_id: user.id) }
|
11
|
-
let!(:access_grant) { Fabricate('Doorkeeper::AccessGrant',
|
12
|
-
application_id: application.id,
|
13
|
-
resource_owner_id: user.id,
|
14
|
-
redirect_uri: 'http://localhost:3002/oauth/callback'
|
15
|
-
) }
|
16
|
-
|
17
|
-
# Set up Session
|
18
|
-
let(:session) { Fabricate('Sso::Session', owner: user) }
|
19
|
-
let!(:client) { Fabricate('Sso::Client', session: session,
|
20
|
-
application_id: application.id,
|
21
|
-
access_grant_id: access_grant.id) }
|
22
|
-
|
23
|
-
let(:auth) { double :auth, token: access_grant }
|
24
|
-
let(:code_response) { double :code_response, auth: auth }
|
25
|
-
let(:authorization) { double :authorization, instance_variable_get: code_response }
|
26
|
-
let(:warden_session) { { "warden.user.user.session" => { "sso_session_id" => session.id } } }
|
27
|
-
subject(:controller) { described_class.new }
|
28
|
-
|
29
|
-
|
30
|
-
describe "#handle_authorization_grant_flow" do
|
31
|
-
before do
|
32
|
-
allow(controller).to receive(:grant_token).and_return(access_grant.try(:token))
|
33
|
-
allow(controller).to receive(:grant_type).and_return("authorization_code")
|
34
|
-
allow(controller).to receive(:outgoing_access_token).and_return(access_token.try(:token))
|
35
|
-
end
|
36
|
-
|
37
|
-
context "working flow" do
|
38
|
-
it "saves access_token" do
|
39
|
-
controller.send(:handle_authorization_grant_flow)
|
40
|
-
client.reload
|
41
|
-
expect(client.access_grant).to eq access_grant
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
context "grant missing" do
|
46
|
-
let!(:access_grant) { nil }
|
47
|
-
let!(:client) { nil }
|
48
|
-
|
49
|
-
it "logs error and halt" do
|
50
|
-
expect(controller).to receive(:error)
|
51
|
-
expect(controller.send(:handle_authorization_grant_flow)).to be_falsy
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
context "access_grant token missing" do
|
56
|
-
let(:access_token) { nil }
|
57
|
-
|
58
|
-
it "logs error and halt" do
|
59
|
-
expect(controller).to receive(:error)
|
60
|
-
expect(controller.send(:handle_authorization_grant_flow)).to be_falsy
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
|
66
|
-
describe "#error_and_return" do
|
67
|
-
after() { controller.send(:error_and_return, "AN ERROR") }
|
68
|
-
|
69
|
-
it { expect(controller).to receive(:error) }
|
70
|
-
end
|
71
|
-
|
72
|
-
end
|