prx_auth-rails 1.4.1 → 2.0.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
  SHA256:
3
- metadata.gz: 6af8c934d225009086d72c5503a3ad3db62b95c073063f019a31277c9eacc5bf
4
- data.tar.gz: ab82780e90f78e9a3a31515078c9b7530354ad83bf3fd402a05c78514a0c762d
3
+ metadata.gz: 76cccc8605691493ace58a976780a69b37bb138d63874eec2a4b1158a316c237
4
+ data.tar.gz: 121c8ac1bfe90d10d4424030c8472f5f443d5a26a62cf4e4480dae5de356c408
5
5
  SHA512:
6
- metadata.gz: 7af00c69f65cabbb5da5a1ea9fe0a79d85a3b004d9c437fa5c1a5539be22fc21ac346e2956d3f6cebbf07765e6b988d9d291c1b384bf8a56b78a8782d2f8f6af
7
- data.tar.gz: c9a17a75d94bf7158b96147c877020f2093c07eb6e5ba345fb4ba37d6fd51df72fb2d5db4fc22ca04832c6954b5f7b9154252fb40a5de4e5878d006b096f02b6
6
+ metadata.gz: 1f6e5d4ca1a8590e1f313791d91f08179eff18217671fbc532f5a6a6dcf365f81519e71192dd80257b35af148b53b8b46933c6fd9d3ce47d678329d91919f38c
7
+ data.tar.gz: 4292c219ad997eea92c2ae81e66db3223e8e4d3cd7f63d521ca0ee59e008e409ba6cf228e97aa5f24765da30dc3defa8e47a9349491d1d5c5885cfb7ca7fad45
@@ -4,13 +4,11 @@ module PrxAuth::Rails
4
4
 
5
5
  skip_before_action :authenticate!
6
6
 
7
- before_action :set_nonce!, only: :show
7
+ before_action :set_nonce!, only: [:new, :show]
8
8
 
9
9
  ID_NONCE_SESSION_KEY = 'id_prx_openid_nonce'.freeze
10
10
 
11
11
  def new
12
- set_nonce! unless fetch_nonce.present?
13
-
14
12
  config = PrxAuth::Rails.configuration
15
13
 
16
14
  id_auth_params = {
@@ -27,81 +25,89 @@ module PrxAuth::Rails
27
25
  def show
28
26
  end
29
27
 
28
+ def destroy
29
+ sign_out_user
30
+ redirect_to after_sign_out_path
31
+ end
32
+
30
33
  def auth_error
31
34
  @auth_error_message = params.require(:error)
32
35
  end
33
36
 
34
37
  def create
35
- jwt_id_claims = id_claims
36
- jwt_access_claims = access_claims
37
-
38
- jwt_access_claims['id_token'] = jwt_id_claims.as_json
39
-
40
- result_path = if valid_nonce?(jwt_id_claims['nonce']) &&
41
- users_match?(jwt_id_claims, jwt_access_claims)
42
- sign_in_user(jwt_access_claims)
43
- lookup_and_register_accounts_names
44
- after_sign_in_path_for(current_user)
45
- else
46
- auth_error_sessions_path(error: 'verification_failed')
47
- end
48
- reset_nonce!
49
-
50
- redirect_to result_path
38
+ if valid_nonce? && users_match?
39
+ clear_nonce!
40
+ sign_in_user(access_token)
41
+ redirect_to after_sign_in_path_for(current_user)
42
+ else
43
+ clear_nonce!
44
+ redirect_to auth_error_sessions_path(error: 'verification_failed')
45
+ end
51
46
  end
52
47
 
53
48
  private
54
49
 
55
50
  def after_sign_in_path_for(_)
51
+ back_path = after_sign_in_user_redirect
52
+ if back_path.present?
53
+ back_path
54
+ elsif defined?(super)
55
+ super
56
+ else
57
+ '/'
58
+ end
59
+ end
60
+
61
+ def after_sign_out_path
56
62
  return super if defined?(super)
57
63
 
58
- "/"
64
+ "https://#{id_host}/session/sign_out"
65
+ end
66
+
67
+ def id_token
68
+ params.require('id_token')
69
+ end
70
+
71
+ def access_token
72
+ params.require('access_token')
59
73
  end
60
74
 
61
75
  def id_claims
62
- id_token = params.require('id_token')
63
- validate_token(id_token)
76
+ @id_claims ||= validate_token(id_token)
64
77
  end
65
78
 
66
79
  def access_claims
67
- access_token = params.require('access_token')
68
- validate_token(access_token)
80
+ @access_claims ||= validate_token(access_token)
69
81
  end
70
82
 
71
- def reset_nonce!
72
- session[ID_NONCE_SESSION_KEY] = nil
83
+ def clear_nonce!
84
+ session.delete(ID_NONCE_SESSION_KEY)
73
85
  end
74
86
 
75
87
  def set_nonce!
76
- n = session[ID_NONCE_SESSION_KEY]
77
- return n if n.present?
78
-
79
- session[ID_NONCE_SESSION_KEY] = SecureRandom.hex
88
+ session[ID_NONCE_SESSION_KEY] ||= SecureRandom.hex
80
89
  end
81
90
 
82
91
  def fetch_nonce
83
92
  session[ID_NONCE_SESSION_KEY]
84
93
  end
85
94
 
86
- def valid_nonce?(nonce)
87
- return false if fetch_nonce.nil?
88
-
89
- fetch_nonce == nonce
95
+ def valid_nonce?
96
+ id_claims['nonce'].present? && id_claims['nonce'] == fetch_nonce
90
97
  end
91
98
 
92
- def users_match?(claims1, claims2)
93
- return false if claims1['sub'].nil? || claims2['sub'].nil?
94
-
95
- claims1['sub'] == claims2['sub']
99
+ def users_match?
100
+ id_claims['sub'].present? && id_claims['sub'] == access_claims['sub']
96
101
  end
97
102
 
98
103
  def validate_token(token)
99
- id_host = PrxAuth::Rails.configuration.id_host
100
104
  prx_auth_cert = Rack::PrxAuth::Certificate.new("https://#{id_host}/api/v1/certs")
101
105
  auth_validator = Rack::PrxAuth::AuthValidator.new(token, prx_auth_cert, id_host)
102
- auth_validator.
103
- claims.
104
- with_indifferent_access
106
+ auth_validator.claims.with_indifferent_access
107
+ end
108
+
109
+ def id_host
110
+ PrxAuth::Rails.configuration.id_host
105
111
  end
106
112
  end
107
113
  end
@@ -0,0 +1 @@
1
+ Rails.application.config.assets.precompile << %w(prx_auth-rails_manifest.js)
@@ -2,7 +2,11 @@ module PrxAuth
2
2
  module Rails
3
3
  class Engine < ::Rails::Engine
4
4
  config.to_prepare do
5
- ::ApplicationController.helper_method [:current_user, :account_name_for]
5
+ ::ApplicationController.helper_method [
6
+ :current_user, :prx_jwt,
7
+ :current_user_info, :current_user_name, :current_user_apps,
8
+ :account_name_for, :account_for, :accounts_for,
9
+ ]
6
10
  end
7
11
  end
8
12
  end
@@ -4,14 +4,27 @@ require 'open-uri'
4
4
  module PrxAuth
5
5
  module Rails
6
6
  module Controller
7
+ class SessionTokenExpiredError < RuntimeError; end
7
8
 
8
- PRX_ACCOUNT_NAME_MAPPING_KEY = 'prx.account.name.mapping'.freeze
9
+ PRX_AUTH_ENV_KEY = 'prx.auth'.freeze
10
+ PRX_JWT_SESSION_KEY = 'prx.auth.jwt'.freeze
11
+ PRX_JWT_REFRESH_TTL = 300.freeze
12
+ PRX_ACCOUNT_MAPPING_SESSION_KEY = 'prx.auth.account.mapping'.freeze
13
+ PRX_USER_INFO_SESSION_KEY = 'prx.auth.info'.freeze
14
+ PRX_REFRESH_BACK_KEY = 'prx.auth.back'.freeze
9
15
 
10
16
  def prx_auth_token
11
- rack_auth_token = env_prx_auth_token
12
- return rack_auth_token if rack_auth_token.present?
17
+ env_token || session_token
18
+ rescue SessionTokenExpiredError
19
+ session.delete(PRX_JWT_SESSION_KEY)
20
+ session.delete(PRX_ACCOUNT_MAPPING_SESSION_KEY)
21
+ session.delete(PRX_USER_INFO_SESSION_KEY)
22
+ session[PRX_REFRESH_BACK_KEY] = request.fullpath
23
+ redirect_to PrxAuth::Rails::Engine.routes.url_helpers.new_sessions_path
24
+ end
13
25
 
14
- session['prx.auth'] && Rack::PrxAuth::TokenData.new(session['prx.auth'])
26
+ def prx_jwt
27
+ session[PRX_JWT_SESSION_KEY]
15
28
  end
16
29
 
17
30
  def prx_authenticated?
@@ -24,66 +37,116 @@ module PrxAuth
24
37
  redirect_to PrxAuth::Rails::Engine.routes.url_helpers.new_sessions_path
25
38
  end
26
39
 
40
+ def prx_auth_needs_refresh?(jwt_ttl)
41
+ request.get? && jwt_ttl < PRX_JWT_REFRESH_TTL
42
+ end
43
+
27
44
  def current_user
28
- return if prx_auth_token.nil?
45
+ prx_auth_token
46
+ end
29
47
 
30
- PrxAuth::Rails::Token.new(prx_auth_token)
48
+ def current_user_info
49
+ session[PRX_USER_INFO_SESSION_KEY] ||= fetch_userinfo
31
50
  end
32
51
 
33
- def lookup_and_register_accounts_names
34
- session[PRX_ACCOUNT_NAME_MAPPING_KEY] =
35
- lookup_account_names_mapping
52
+ def current_user_name
53
+ current_user_info['name'] || current_user_info['preferred_username'] || current_user_info['email']
36
54
  end
37
55
 
38
- def account_name_for(id)
39
- id = id.to_i
56
+ def current_user_apps
57
+ apps = (current_user_info.try(:[], 'apps') || []).map do |name, url|
58
+ label = name.sub(/^https?:\/\//, '').sub(/\..+/, '').capitalize
59
+ ["PRX #{label}", url]
60
+ end
40
61
 
41
- session[PRX_ACCOUNT_NAME_MAPPING_KEY] ||= {}
62
+ # only return entire list in development
63
+ if ::Rails.env.production? || ::Rails.env.staging?
64
+ apps.to_h.select { |k, v| v.match?(/\.(org|tech)/) }
65
+ else
66
+ apps.to_h
67
+ end
68
+ end
42
69
 
43
- name =
44
- if session[PRX_ACCOUNT_NAME_MAPPING_KEY].has_key?(id)
45
- session[PRX_ACCOUNT_NAME_MAPPING_KEY][id]
46
- else
47
- session[PRX_ACCOUNT_NAME_MAPPING_KEY][id] = lookup_account_name_for(id)
48
- end
70
+ def sign_in_user(token)
71
+ session[PRX_JWT_SESSION_KEY] = token
72
+ accounts_for(current_user.resources)
73
+ end
49
74
 
50
- name = "[#{id}] Unknown Account Name" unless name.present?
75
+ def after_sign_in_user_redirect
76
+ session.delete(PRX_REFRESH_BACK_KEY)
77
+ end
51
78
 
52
- name
79
+ def sign_out_user
80
+ reset_session
53
81
  end
54
82
 
55
- def sign_in_user(token)
56
- session['prx.auth'] = token
83
+ def account_name_for(account_id)
84
+ account_for(account_id).try(:[], :name)
85
+ end
86
+
87
+ def account_for(account_id)
88
+ lookup_accounts([account_id]).first
89
+ end
90
+
91
+ def accounts_for(account_ids)
92
+ lookup_accounts(account_ids)
57
93
  end
58
94
 
59
95
  private
60
96
 
61
- def lookup_account_name_for(id)
62
- id = id.to_i
97
+ def lookup_accounts(ids)
98
+ session[PRX_ACCOUNT_MAPPING_SESSION_KEY] ||= {}
99
+
100
+ # fetch any accounts we don't have yet
101
+ missing = ids - session[PRX_ACCOUNT_MAPPING_SESSION_KEY].keys
102
+ if missing.present?
103
+ fetch_accounts(missing).each do |account|
104
+ session[PRX_ACCOUNT_MAPPING_SESSION_KEY][account['id']] = account.with_indifferent_access
105
+ end
106
+ end
63
107
 
64
- res = lookup_account_names_mapping([id])
65
- res[id]
108
+ ids.map { |id| session[PRX_ACCOUNT_MAPPING_SESSION_KEY][id] }
66
109
  end
67
110
 
68
- def lookup_account_names_mapping(ids=current_user.resources)
69
- id_host = PrxAuth::Rails.configuration.id_host
111
+ def fetch_accounts(ids)
70
112
  ids_param = ids.map(&:to_s).join(',')
113
+ fetch("/api/v1/accounts?account_ids=#{ids_param}")['accounts']
114
+ end
71
115
 
116
+ def fetch_userinfo
117
+ fetch("/userinfo?scope=apps+email+profile", prx_jwt)
118
+ end
119
+
120
+ def fetch(path, token = nil)
121
+ url = "https://#{PrxAuth::Rails.configuration.id_host}#{path}"
72
122
  options = {}
73
123
  options[:ssl_verify_mode] = OpenSSL::SSL::VERIFY_NONE if ::Rails.env.development?
124
+ options['Authorization'] = "Bearer #{token}" if token
125
+ JSON.parse(URI.open(url, options).read)
126
+ end
74
127
 
75
- accounts = URI.open("https://#{id_host}/api/v1/accounts?account_ids=#{ids_param}", options).read
128
+ # token from data set by prx_auth rack middleware
129
+ def env_token
130
+ @env_token_data ||= if request.env[PRX_AUTH_ENV_KEY]
131
+ token_data = request.env[PRX_AUTH_ENV_KEY]
132
+ PrxAuth::Rails::Token.new(token_data)
133
+ end
134
+ end
76
135
 
77
- mapping = JSON.parse(accounts)['accounts'].map { |acct| [acct['id'], acct['display_name']] }.to_h
136
+ # token from jwt stored in session
137
+ def session_token
138
+ @session_prx_auth_token ||= if prx_jwt
139
+ # NOTE: we already validated this jwt - so just decode it
140
+ validator = Rack::PrxAuth::AuthValidator.new(prx_jwt)
78
141
 
79
- mapping
80
- end
142
+ # does this jwt need to be refreshed?
143
+ if prx_auth_needs_refresh?(validator.time_to_live)
144
+ raise SessionTokenExpiredError.new
145
+ end
81
146
 
82
- def env_prx_auth_token
83
- if !defined? @_prx_auth_token
84
- @_prx_auth_token = request.env['prx.auth'] && PrxAuth::Rails::Token.new(request.env['prx.auth'])
85
- else
86
- @_prx_auth_token
147
+ # create new data/token from access claims
148
+ token_data = Rack::PrxAuth::TokenData.new(validator.claims)
149
+ PrxAuth::Rails::Token.new(token_data)
87
150
  end
88
151
  end
89
152
  end
@@ -1,5 +1,5 @@
1
1
  module PrxAuth
2
2
  module Rails
3
- VERSION = "1.4.1"
3
+ VERSION = "2.0.0"
4
4
  end
5
5
  end
@@ -8,10 +8,8 @@ Gem::Specification.new do |spec|
8
8
  spec.version = PrxAuth::Rails::VERSION
9
9
  spec.authors = ["Chris Rhoden"]
10
10
  spec.email = ["carhoden@gmail.com"]
11
- spec.description = %q{Rails integration for next generation PRX Authorization system.
12
- }
13
- spec.summary = %q{Rails integration for next generation PRX Authorization system.
14
- }
11
+ spec.description = "Rails integration for next generation PRX Authorization system."
12
+ spec.summary = "Rails integration for next generation PRX Authorization system."
15
13
  spec.homepage = "https://github.com/PRX/prx_auth-rails"
16
14
  spec.license = "MIT"
17
15
 
@@ -29,11 +27,11 @@ Gem::Specification.new do |spec|
29
27
  spec.add_development_dependency 'coveralls', '~> 0'
30
28
  spec.add_development_dependency 'guard'
31
29
  spec.add_development_dependency 'guard-minitest'
30
+ spec.add_development_dependency 'm', '~> 1.5'
32
31
  spec.add_development_dependency "rails", "~> 6.1.0"
33
32
  spec.add_development_dependency 'pry'
34
33
  spec.add_development_dependency 'sqlite3'
34
+ spec.add_development_dependency 'webmock'
35
35
 
36
-
37
-
38
- spec.add_runtime_dependency 'prx_auth', "~> 1.2"
36
+ spec.add_runtime_dependency 'prx_auth', ">= 1.7.0"
39
37
  end
@@ -2,6 +2,8 @@ class ApplicationController < ActionController::Base
2
2
 
3
3
  before_action :authenticate!
4
4
 
5
+ def index; end
6
+
5
7
  def after_sign_in_path_for(_resource)
6
8
  '/after-sign-in-path'
7
9
  end
@@ -0,0 +1 @@
1
+ the controller index!
@@ -1,3 +1,5 @@
1
1
  Rails.application.routes.draw do
2
+ get 'index', to: 'application#index'
3
+ put 'index', to: 'application#index'
2
4
  mount PrxAuth::Rails::Engine => "/prx_auth-rails"
3
5
  end
@@ -0,0 +1,165 @@
1
+ require 'test_helper'
2
+
3
+ module PrxAuth::Rails::Ext
4
+ class ControllerTest < ActionController::TestCase
5
+
6
+ setup do
7
+ @controller = ApplicationController.new
8
+ @jwt_session_key = ApplicationController::PRX_JWT_SESSION_KEY
9
+ @user_info_key = ApplicationController::PRX_USER_INFO_SESSION_KEY
10
+ @account_mapping_key = ApplicationController::PRX_ACCOUNT_MAPPING_SESSION_KEY
11
+ @stub_claims = {'iat' => Time.now.to_i, 'exp' => Time.now.to_i + 3600}
12
+ end
13
+
14
+ # stub auth and init controller+session by getting a page
15
+ def with_stubbed_auth(jwt)
16
+ session[@jwt_session_key] = 'some-jwt'
17
+ @controller.stub(:prx_auth_needs_refresh?, false) do
18
+ get :index
19
+ assert_equal response.code, '200'
20
+ yield
21
+ end
22
+ end
23
+
24
+ test 'redirects unless you are authenticated' do
25
+ get :index
26
+ assert_equal response.code, '302'
27
+ assert response.headers['Location'].ends_with?('/sessions/new')
28
+ end
29
+
30
+ test 'uses a valid session token' do
31
+ session[@jwt_session_key] = 'some-jwt'
32
+ JSON::JWT.stub(:decode, @stub_claims) do
33
+ get :index
34
+ assert_equal response.code, '200'
35
+ assert response.body.include?('the controller index!')
36
+ assert @controller.current_user.is_a?(PrxAuth::Rails::Token)
37
+ end
38
+ end
39
+
40
+ test 'redirects if your token is nearing expiration' do
41
+ session[@jwt_session_key] = 'some-jwt'
42
+ @stub_claims['exp'] = Time.now.to_i + 10
43
+ JSON::JWT.stub(:decode, @stub_claims) do
44
+ get :index
45
+ assert_equal response.code, '302'
46
+ assert response.headers['Location'].ends_with?('/sessions/new')
47
+ end
48
+ end
49
+
50
+ test 'does not redirect if your token has expired on a non-GET request' do
51
+ session[@jwt_session_key] = 'some-jwt'
52
+ @stub_claims['exp'] = Time.now.to_i + 10
53
+ JSON::JWT.stub(:decode, @stub_claims) do
54
+ put :index
55
+ assert_equal response.code, '200'
56
+ assert response.body.include?('the controller index!')
57
+ end
58
+ end
59
+
60
+ test 'fetches current user info' do
61
+ with_stubbed_auth('some-jwt') do
62
+ body = {
63
+ 'name' => 'Some Username',
64
+ 'apps' => {'publish.prx.test' => 'https://publish.prx.test'},
65
+ 'other' => 'stuff'
66
+ }
67
+
68
+ id_host = PrxAuth::Rails.configuration.id_host
69
+ stub_request(:get, "https://#{id_host}/userinfo?scope=apps%20email%20profile").
70
+ with(headers: {'Authorization' => 'Bearer some-jwt'}).
71
+ to_return(status: 200, body: JSON.generate(body))
72
+
73
+ assert session[@user_info_key] == nil
74
+ assert_equal @controller.current_user_info, body
75
+ refute session[@user_info_key] == nil
76
+ assert_equal @controller.current_user_name, 'Some Username'
77
+ assert_equal @controller.current_user_apps, {'PRX Publish' => 'https://publish.prx.test'}
78
+ end
79
+ end
80
+
81
+ test 'has user name fallbacks' do
82
+ with_stubbed_auth('some-jwt') do
83
+ session[@user_info_key] = {'name' => 'one', 'preferred_username' => 'two', 'email' => 'three'}
84
+ assert_equal @controller.current_user_name, 'one'
85
+
86
+ session[@user_info_key] = {'preferred_username' => 'two', 'email' => 'three'}
87
+ assert_equal @controller.current_user_name, 'two'
88
+
89
+ session[@user_info_key] = {'email' => 'three'}
90
+ assert_equal @controller.current_user_name, 'three'
91
+ end
92
+ end
93
+
94
+ test 'filters apps displayed in production' do
95
+ with_stubbed_auth('some-jwt') do
96
+ Rails.env.stub(:production?, true) do
97
+ session[@user_info_key] = {
98
+ 'apps' => {
99
+ 'localhost stuff' => 'http://localhost:4000/path1',
100
+ 'publish.prx.test' => 'https://publish.prx.test/path2',
101
+ 'metrics.prx.tech' => 'https://metrics.prx.tech/path3',
102
+ 'augury.prx.org' => 'https://augury.prx.org/path4',
103
+ }
104
+ }
105
+
106
+ assert_equal @controller.current_user_apps, {
107
+ 'PRX Metrics' => 'https://metrics.prx.tech/path3',
108
+ 'PRX Augury' => 'https://augury.prx.org/path4',
109
+ }
110
+ end
111
+ end
112
+ end
113
+
114
+ test 'fetches accounts' do
115
+ with_stubbed_auth('some-jwt') do
116
+ one = {'id' => 1, 'type' => 'IndividualAccount', 'name' => 'One'}
117
+ three = {'id' => 3, 'type' => 'GroupAccount', 'name' => 'Three'}
118
+ body = {'accounts' => [one, three]}
119
+
120
+ id_host = PrxAuth::Rails.configuration.id_host
121
+ stub_request(:get, "https://#{id_host}/api/v1/accounts?account_ids=1,2,3").
122
+ to_return(status: 200, body: JSON.generate(body))
123
+
124
+ assert_nil session[@account_mapping_key]
125
+ assert_equal @controller.accounts_for([1, 2, 3]), [one, nil, three]
126
+ refute_nil session[@account_mapping_key]
127
+ assert_equal @controller.account_for(1), one
128
+ assert_equal @controller.account_for(3), three
129
+ assert_equal @controller.account_name_for(1), 'One'
130
+ assert_equal @controller.account_name_for(3), 'Three'
131
+ end
132
+ end
133
+
134
+ test 'handles unknown account ids' do
135
+ with_stubbed_auth('some-jwt') do
136
+ id_host = PrxAuth::Rails.configuration.id_host
137
+ stub_request(:get, "https://#{id_host}/api/v1/accounts?account_ids=2").
138
+ to_return(status: 200, body: JSON.generate({accounts: []})).
139
+ times(3)
140
+
141
+ assert_equal @controller.accounts_for([2]), [nil]
142
+ assert_nil @controller.account_for(2)
143
+ assert_nil @controller.account_name_for(2)
144
+ end
145
+ end
146
+
147
+ test 'only fetches only missing accounts' do
148
+ with_stubbed_auth('some-jwt') do
149
+ one = {'name' => 'One'}
150
+ two = {'id' => 2, 'type' => 'StationAccount', 'name' => 'Two'}
151
+ three = {'name' => 'Three'}
152
+ session[@account_mapping_key] = {1 => one, 3 => three}
153
+ body = {'accounts' => [two]}
154
+
155
+ id_host = PrxAuth::Rails.configuration.id_host
156
+ stub_request(:get, "https://#{id_host}/api/v1/accounts?account_ids=2").
157
+ to_return(status: 200, body: JSON.generate(body))
158
+
159
+ assert_equal @controller.accounts_for([1, 2, 3]), [one, two, three]
160
+ assert_equal @controller.account_for(2), two
161
+ assert_equal @controller.account_name_for(2), 'Two'
162
+ end
163
+ end
164
+ end
165
+ end
@@ -6,8 +6,10 @@ module PrxAuth::Rails
6
6
  setup do
7
7
  @routes = PrxAuth::Rails::Engine.routes
8
8
  @nonce_session_key = SessionsController::ID_NONCE_SESSION_KEY
9
- @token_params = {id_token: 'sometok', access_token: 'othertok'}
9
+ @refresh_back_key = SessionsController::PRX_REFRESH_BACK_KEY
10
+ @token_params = {id_token: 'idtok', access_token: 'accesstok'}
10
11
  @stub_claims = {'nonce' => '123', 'sub' => '1'}
12
+ @stub_token = PrxAuth::Rails::Token.new(Rack::PrxAuth::TokenData.new())
11
13
  end
12
14
 
13
15
  test "new creates nonce" do
@@ -31,11 +33,12 @@ module PrxAuth::Rails
31
33
  end
32
34
 
33
35
  test 'create should validate a token and set the session variable' do
36
+ session[SessionsController::PRX_JWT_SESSION_KEY] = nil
34
37
  @controller.stub(:validate_token, @stub_claims) do
35
- @controller.stub(:lookup_and_register_accounts_names, nil) do
38
+ @controller.stub(:session_token, @stub_token) do
36
39
  session[@nonce_session_key] = '123'
37
40
  post :create, params: @token_params, format: :json
38
- assert session['prx.auth']['id_token']['nonce'] == '123'
41
+ assert session[SessionsController::PRX_JWT_SESSION_KEY] == 'accesstok'
39
42
  end
40
43
  end
41
44
  end
@@ -50,7 +53,7 @@ module PrxAuth::Rails
50
53
 
51
54
  test 'create should reset the nonce after consumed' do
52
55
  @controller.stub(:validate_token, @stub_claims) do
53
- @controller.stub(:lookup_and_register_accounts_names, nil) do
56
+ @controller.stub(:session_token, @stub_token) do
54
57
  session[@nonce_session_key] = '123'
55
58
  post :create, params: @token_params, format: :json
56
59
 
@@ -61,7 +64,21 @@ module PrxAuth::Rails
61
64
  end
62
65
  end
63
66
 
64
- test 'should respond with aredirect to the auth error page / code if the nonce does not match' do
67
+ test 'redirects to a back-path after refresh' do
68
+ @controller.stub(:validate_token, @stub_claims) do
69
+ @controller.stub(:session_token, @stub_token) do
70
+ session[@nonce_session_key] = '123'
71
+ session[@refresh_back_key] = '/lets/go/here?okay'
72
+ post :create, params: @token_params, format: :json
73
+
74
+ assert session[@refresh_back_key] == nil
75
+ assert response.code == '302'
76
+ assert response.headers['Location'].ends_with?('/lets/go/here?okay')
77
+ end
78
+ end
79
+ end
80
+
81
+ test 'should respond with redirect to the auth error page / code if the nonce does not match' do
65
82
  @controller.stub(:validate_token, @stub_claims) do
66
83
  session[@nonce_session_key] = 'nonce-does-not-match'
67
84
  post :create, params: @token_params, format: :json
@@ -86,13 +103,19 @@ module PrxAuth::Rails
86
103
  @controller.stub(:id_claims, @stub_claims) do
87
104
  @controller.stub(:access_claims, @stub_claims.merge('sub' => '444')) do
88
105
 
89
- session[@nonce_session_key] = '123'
90
- post :create, params: @token_params, format: :json
106
+ session[@nonce_session_key] = '123'
107
+ post :create, params: @token_params, format: :json
91
108
 
92
- assert response.code == '302'
93
- assert response.body.match?(/error=verification_failed/)
94
- end
109
+ assert response.code == '302'
110
+ assert response.body.match?(/error=verification_failed/)
111
+ end
95
112
  end
96
113
  end
114
+
115
+ test 'should clear the user token on sign out' do
116
+ session[SessionsController::PRX_JWT_SESSION_KEY] = 'some-token'
117
+ post :destroy
118
+ assert session[SessionsController::PRX_JWT_SESSION_KEY] == nil
119
+ end
97
120
  end
98
121
  end
data/test/test_helper.rb CHANGED
@@ -5,6 +5,7 @@ Coveralls.wear!
5
5
  require 'minitest/autorun'
6
6
  require 'minitest/spec'
7
7
  require 'minitest/pride'
8
+ require 'webmock/minitest'
8
9
  require 'action_pack'
9
10
  require 'action_controller'
10
11
  require 'action_view'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prx_auth-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Rhoden
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-18 00:00:00.000000000 Z
11
+ date: 2021-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: m
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.5'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.5'
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: rails
99
113
  requirement: !ruby/object:Gem::Requirement
@@ -136,23 +150,35 @@ dependencies:
136
150
  - - ">="
137
151
  - !ruby/object:Gem::Version
138
152
  version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: webmock
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
139
167
  - !ruby/object:Gem::Dependency
140
168
  name: prx_auth
141
169
  requirement: !ruby/object:Gem::Requirement
142
170
  requirements:
143
- - - "~>"
171
+ - - ">="
144
172
  - !ruby/object:Gem::Version
145
- version: '1.2'
173
+ version: 1.7.0
146
174
  type: :runtime
147
175
  prerelease: false
148
176
  version_requirements: !ruby/object:Gem::Requirement
149
177
  requirements:
150
- - - "~>"
178
+ - - ">="
151
179
  - !ruby/object:Gem::Version
152
- version: '1.2'
153
- description: 'Rails integration for next generation PRX Authorization system.
154
-
155
- '
180
+ version: 1.7.0
181
+ description: Rails integration for next generation PRX Authorization system.
156
182
  email:
157
183
  - carhoden@gmail.com
158
184
  executables: []
@@ -168,6 +194,7 @@ files:
168
194
  - app/controllers/prx_auth/rails/sessions_controller.rb
169
195
  - app/views/prx_auth/rails/sessions/auth_error.html.erb
170
196
  - app/views/prx_auth/rails/sessions/show.html.erb
197
+ - config/initializers/assets.rb
171
198
  - config/routes.rb
172
199
  - lib/prx_auth/rails.rb
173
200
  - lib/prx_auth/rails/configuration.rb
@@ -191,6 +218,7 @@ files:
191
218
  - test/dummy/app/mailers/application_mailer.rb
192
219
  - test/dummy/app/models/application_record.rb
193
220
  - test/dummy/app/models/concerns/.keep
221
+ - test/dummy/app/views/application/index.html.erb
194
222
  - test/dummy/app/views/layouts/application.html.erb
195
223
  - test/dummy/app/views/layouts/mailer.html.erb
196
224
  - test/dummy/app/views/layouts/mailer.text.erb
@@ -234,6 +262,7 @@ files:
234
262
  - test/dummy/storage/.keep
235
263
  - test/log/development.log
236
264
  - test/prx_auth/rails/configuration_test.rb
265
+ - test/prx_auth/rails/ext/controller_test.rb
237
266
  - test/prx_auth/rails/sessions_controller_test.rb
238
267
  - test/prx_auth/rails/token_test.rb
239
268
  - test/test_helper.rb
@@ -275,6 +304,7 @@ test_files:
275
304
  - test/dummy/app/mailers/application_mailer.rb
276
305
  - test/dummy/app/models/application_record.rb
277
306
  - test/dummy/app/models/concerns/.keep
307
+ - test/dummy/app/views/application/index.html.erb
278
308
  - test/dummy/app/views/layouts/application.html.erb
279
309
  - test/dummy/app/views/layouts/mailer.html.erb
280
310
  - test/dummy/app/views/layouts/mailer.text.erb
@@ -318,6 +348,7 @@ test_files:
318
348
  - test/dummy/storage/.keep
319
349
  - test/log/development.log
320
350
  - test/prx_auth/rails/configuration_test.rb
351
+ - test/prx_auth/rails/ext/controller_test.rb
321
352
  - test/prx_auth/rails/sessions_controller_test.rb
322
353
  - test/prx_auth/rails/token_test.rb
323
354
  - test/test_helper.rb