prx_auth-rails 1.4.1 → 2.0.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 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