prx_auth-rails 1.4.0 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/config/prx_auth-rails_manifest.js +3 -0
- data/app/assets/images/prx_auth-rails/user.svg +5 -0
- data/app/assets/javascripts/prx_auth-rails/user_widget.js.erb +46 -0
- data/app/assets/stylesheets/prx_auth-rails/user_widget.css +69 -0
- data/app/controllers/prx_auth/rails/sessions_controller.rb +48 -42
- data/config/initializers/assets.rb +1 -0
- data/lib/prx_auth/rails/engine.rb +4 -1
- data/lib/prx_auth/rails/ext/controller.rb +65 -34
- data/lib/prx_auth/rails/version.rb +1 -1
- data/prx_auth-rails.gemspec +3 -7
- data/test/dummy/app/controllers/application_controller.rb +2 -0
- data/test/dummy/app/views/application/index.html.erb +1 -0
- data/test/dummy/config/routes.rb +2 -0
- data/test/prx_auth/rails/ext/controller_test.rb +49 -0
- data/test/prx_auth/rails/sessions_controller_test.rb +42 -15
- metadata +20 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a687c733815e035f361fbfd4981e3673480311c6d760206b9b1edd4903e084b
|
4
|
+
data.tar.gz: 5b04a0584489415a7b0223342c85e638c8c3ca01c141e4ff46db9269c192f6be
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 71573dd4f1303e7e2b5fc4ca908c502c74aa986845ddb685613b6e8422c05e136c1952f5bfc2989a607b1a5020f708a06190ebe084a199a46aeefab1f7168706
|
7
|
+
data.tar.gz: dc5685c9e2908ea56c10f577eb2a457167087345f07b09927e8c36c1b0d2df513e2f2367436fe4f637aac648311c75a44ee3f845c63124be7ab4009c45dccb57
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
3
|
+
<svg width="100%" height="100%" viewBox="0 0 51 51" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
|
4
|
+
<path d="M51,25.5C51,11.44 39.56,0 25.5,0C11.44,0 0,11.44 0,25.5C0,32.927 3.194,39.621 8.277,44.285L8.253,44.306L9.08,45.003C9.134,45.049 9.192,45.086 9.246,45.13C9.685,45.495 10.141,45.841 10.604,46.175C10.755,46.284 10.905,46.392 11.058,46.498C11.553,46.839 12.061,47.163 12.58,47.47C12.693,47.537 12.807,47.602 12.922,47.666C13.49,47.99 14.07,48.295 14.665,48.575C14.708,48.596 14.753,48.614 14.796,48.635C16.734,49.535 18.801,50.196 20.964,50.586C21.02,50.597 21.077,50.607 21.134,50.617C21.806,50.733 22.485,50.826 23.172,50.888C23.255,50.895 23.339,50.9 23.423,50.907C24.107,50.964 24.799,51 25.5,51C26.195,51 26.88,50.964 27.56,50.909C27.647,50.902 27.733,50.897 27.819,50.89C28.501,50.828 29.174,50.738 29.839,50.624C29.896,50.613 29.955,50.603 30.012,50.592C32.142,50.21 34.18,49.564 36.092,48.686C36.163,48.654 36.234,48.623 36.305,48.59C36.877,48.321 37.436,48.031 37.984,47.722C38.12,47.645 38.256,47.567 38.391,47.487C38.89,47.194 39.38,46.887 39.857,46.56C40.029,46.443 40.196,46.32 40.366,46.198C40.773,45.905 41.173,45.602 41.561,45.286C41.648,45.217 41.74,45.156 41.825,45.085L42.673,44.376L42.648,44.355C47.776,39.689 51,32.965 51,25.5ZM1.855,25.5C1.855,12.462 12.462,1.855 25.5,1.855C38.538,1.855 49.145,12.462 49.145,25.5C49.145,32.526 46.062,38.843 41.181,43.177C40.908,42.988 40.634,42.82 40.353,42.679L32.502,38.754C31.797,38.401 31.359,37.693 31.359,36.905L31.359,34.164C31.541,33.939 31.733,33.685 31.932,33.406C32.948,31.971 33.763,30.374 34.357,28.656C35.532,28.097 36.291,26.927 36.291,25.606L36.291,22.319C36.291,21.515 35.996,20.735 35.468,20.122L35.468,15.794C35.516,15.312 35.687,12.597 33.722,10.357C32.013,8.406 29.247,7.418 25.5,7.418C21.753,7.418 18.987,8.406 17.278,10.356C15.313,12.596 15.484,15.313 15.532,15.793L15.532,20.121C15.005,20.734 14.709,21.514 14.709,22.318L14.709,25.605C14.709,26.626 15.167,27.578 15.952,28.221C16.703,31.163 18.249,33.39 18.82,34.145L18.82,36.828C18.82,37.585 18.407,38.281 17.742,38.644L10.41,42.643C10.177,42.77 9.945,42.919 9.713,43.085C4.892,38.753 1.855,32.475 1.855,25.5Z" style="fill:white;fill-rule:nonzero;"/>
|
5
|
+
</svg>
|
@@ -0,0 +1,46 @@
|
|
1
|
+
// https://stackoverflow.com/questions/8578617/inject-a-script-tag-with-remote-src-and-wait-for-it-to-execute
|
2
|
+
function prxInjectScript(src, callback) {
|
3
|
+
const script = document.createElement('script');
|
4
|
+
|
5
|
+
script.type = 'text/javascript';
|
6
|
+
script.async = false;
|
7
|
+
script.src = src;
|
8
|
+
|
9
|
+
script.onload = function () { script.onload = null; callback(); }
|
10
|
+
|
11
|
+
document.getElementsByTagName('head')[0].appendChild(script);
|
12
|
+
}
|
13
|
+
|
14
|
+
document.addEventListener('DOMContentLoaded', function () {
|
15
|
+
|
16
|
+
const widget = document.getElementById('prx-user-widget');
|
17
|
+
const account = document.getElementById('prx-user-widget-menu-account');
|
18
|
+
|
19
|
+
const idHost = 'https://' + widget.getAttribute('data-id-host');;
|
20
|
+
const scriptUrl = idHost + '/widget.js';
|
21
|
+
|
22
|
+
prxInjectScript(scriptUrl, function () {
|
23
|
+
const signIn = new PRXSignIn(idHost);
|
24
|
+
|
25
|
+
signIn.signedIn(function (prx) {
|
26
|
+
|
27
|
+
if (!prx.userinfo) {
|
28
|
+
// Not logged in
|
29
|
+
widget.classList.add('no-user-info');
|
30
|
+
|
31
|
+
const url = idHost + '/session?return_to=' + encodeURIComponent(window.location);
|
32
|
+
|
33
|
+
account.innerHTML = '<a class=sign-in href="' + url + '">Sign in</a>';
|
34
|
+
} else {
|
35
|
+
// Logged in
|
36
|
+
widget.classList.add('user-info');
|
37
|
+
|
38
|
+
const account = document.getElementById('prx-user-widget-menu-account');
|
39
|
+
account.innerText = prx.userinfo.email;
|
40
|
+
|
41
|
+
signIn.listApps('prx-user-widget-menu-apps');
|
42
|
+
}
|
43
|
+
});
|
44
|
+
});
|
45
|
+
});
|
46
|
+
|
@@ -0,0 +1,69 @@
|
|
1
|
+
#prx-user-widget {
|
2
|
+
display: flex;
|
3
|
+
flex-direction: column;
|
4
|
+
height: 100%;
|
5
|
+
justify-content: center;
|
6
|
+
padding: 0 20px;
|
7
|
+
position: absolute;
|
8
|
+
right: 0;
|
9
|
+
transition-property: opacity;
|
10
|
+
transition-duration: 0.2s;
|
11
|
+
}
|
12
|
+
@media (max-width: ) {
|
13
|
+
#prx-user-widget {
|
14
|
+
height: auto;
|
15
|
+
top: 0;
|
16
|
+
}
|
17
|
+
}
|
18
|
+
#prx-user-widget:hover {
|
19
|
+
}
|
20
|
+
#prx-user-widget:hover .user-icon {
|
21
|
+
opacity: 1;
|
22
|
+
}
|
23
|
+
#prx-user-widget:hover #prx-user-widget-menu {
|
24
|
+
display: block;
|
25
|
+
}
|
26
|
+
#prx-user-widget .user-icon {
|
27
|
+
cursor: pointer;
|
28
|
+
height: 2em;
|
29
|
+
opacity: 0.7;
|
30
|
+
width: 2em;
|
31
|
+
}
|
32
|
+
#prx-user-widget #prx-user-widget-menu {
|
33
|
+
background-color: #1a1a1a;
|
34
|
+
display: none;
|
35
|
+
right: 0;
|
36
|
+
padding: 10px 20px;
|
37
|
+
position: absolute;
|
38
|
+
top: 100%;
|
39
|
+
z-index: 999;
|
40
|
+
display: none;
|
41
|
+
}
|
42
|
+
|
43
|
+
#prx-user-widget #prx-user-widget-menu h1 {
|
44
|
+
color: white;
|
45
|
+
font-size: .9em;
|
46
|
+
font-weight: 700;
|
47
|
+
}
|
48
|
+
|
49
|
+
#prx-user-widget #prx-user-widget-menu-apps {
|
50
|
+
padding: 0;
|
51
|
+
}
|
52
|
+
#prx-user-widget #prx-user-widget-menu-apps ul {
|
53
|
+
border-top: 1px solid #ddd;
|
54
|
+
padding: 15px 0 0;
|
55
|
+
}
|
56
|
+
|
57
|
+
#prx-user-widget #prx-user-widget-menu-apps ul li a {
|
58
|
+
display: block;
|
59
|
+
font-weight: normal;
|
60
|
+
opacity: 0.7;
|
61
|
+
padding: 5px 0;
|
62
|
+
text-transform: none;
|
63
|
+
}
|
64
|
+
#prx-user-widget #prx-user-widget-menu-apps ul li a:hover {
|
65
|
+
opacity: 1;
|
66
|
+
}
|
67
|
+
.prx-home #prx-user-widget.loaded:hover {
|
68
|
+
background: transparent;
|
69
|
+
}
|
@@ -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
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
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
|
-
|
63
|
-
validate_token(id_token)
|
76
|
+
@id_claims ||= validate_token(id_token)
|
64
77
|
end
|
65
78
|
|
66
79
|
def access_claims
|
67
|
-
|
68
|
-
validate_token(access_token)
|
80
|
+
@access_claims ||= validate_token(access_token)
|
69
81
|
end
|
70
82
|
|
71
|
-
def
|
72
|
-
session
|
83
|
+
def clear_nonce!
|
84
|
+
session.delete(ID_NONCE_SESSION_KEY)
|
73
85
|
end
|
74
86
|
|
75
87
|
def set_nonce!
|
76
|
-
|
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?
|
87
|
-
|
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?
|
93
|
-
|
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
|
-
|
104
|
-
|
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,10 @@ module PrxAuth
|
|
2
2
|
module Rails
|
3
3
|
class Engine < ::Rails::Engine
|
4
4
|
config.to_prepare do
|
5
|
-
::ApplicationController.helper_method [
|
5
|
+
::ApplicationController.helper_method [
|
6
|
+
:current_user, :prx_jwt,
|
7
|
+
:account_name_for, :account_for, :accounts_for,
|
8
|
+
]
|
6
9
|
end
|
7
10
|
end
|
8
11
|
end
|
@@ -4,14 +4,24 @@ require 'open-uri'
|
|
4
4
|
module PrxAuth
|
5
5
|
module Rails
|
6
6
|
module Controller
|
7
|
+
class SessionTokenExpiredError < RuntimeError; end
|
7
8
|
|
8
|
-
|
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_REFRESH_BACK_KEY = 'prx.auth.back'.freeze
|
9
14
|
|
10
15
|
def prx_auth_token
|
11
|
-
|
12
|
-
|
16
|
+
env_token || session_token
|
17
|
+
rescue SessionTokenExpiredError
|
18
|
+
reset_session
|
19
|
+
session[PRX_REFRESH_BACK_KEY] = request.fullpath
|
20
|
+
redirect_to PrxAuth::Rails::Engine.routes.url_helpers.new_sessions_path
|
21
|
+
end
|
13
22
|
|
14
|
-
|
23
|
+
def prx_jwt
|
24
|
+
session[PRX_JWT_SESSION_KEY]
|
15
25
|
end
|
16
26
|
|
17
27
|
def prx_authenticated?
|
@@ -25,45 +35,51 @@ module PrxAuth
|
|
25
35
|
end
|
26
36
|
|
27
37
|
def current_user
|
28
|
-
|
29
|
-
|
30
|
-
PrxAuth::Rails::Token.new(prx_auth_token)
|
38
|
+
prx_auth_token
|
31
39
|
end
|
32
40
|
|
33
|
-
def
|
34
|
-
session[
|
35
|
-
|
41
|
+
def sign_in_user(token)
|
42
|
+
session[PRX_JWT_SESSION_KEY] = token
|
43
|
+
accounts_for(current_user.resources)
|
36
44
|
end
|
37
45
|
|
38
|
-
def
|
39
|
-
|
46
|
+
def after_sign_in_user_redirect
|
47
|
+
session.delete(PRX_REFRESH_BACK_KEY)
|
48
|
+
end
|
40
49
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
else
|
45
|
-
session[PRX_ACCOUNT_NAME_MAPPING_KEY][id] = lookup_account_name_for(id)
|
46
|
-
end
|
50
|
+
def sign_out_user
|
51
|
+
reset_session
|
52
|
+
end
|
47
53
|
|
48
|
-
|
54
|
+
def account_name_for(account_id)
|
55
|
+
account_for(account_id)[:name]
|
56
|
+
end
|
49
57
|
|
50
|
-
|
58
|
+
def account_for(account_id)
|
59
|
+
lookup_accounts([account_id]).first
|
51
60
|
end
|
52
61
|
|
53
|
-
def
|
54
|
-
|
62
|
+
def accounts_for(account_ids)
|
63
|
+
lookup_accounts(account_ids)
|
55
64
|
end
|
56
65
|
|
57
66
|
private
|
58
67
|
|
59
|
-
def
|
60
|
-
|
68
|
+
def lookup_accounts(ids)
|
69
|
+
session[PRX_ACCOUNT_MAPPING_SESSION_KEY] ||= {}
|
61
70
|
|
62
|
-
|
63
|
-
|
71
|
+
# fetch any accounts we don't have yet
|
72
|
+
missing = ids - session[PRX_ACCOUNT_MAPPING_SESSION_KEY].keys
|
73
|
+
if missing.present?
|
74
|
+
fetch_accounts(missing).each do |account|
|
75
|
+
session[PRX_ACCOUNT_MAPPING_SESSION_KEY][account['id']] = account.with_indifferent_access
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
ids.map { |id| session[PRX_ACCOUNT_MAPPING_SESSION_KEY][id] }
|
64
80
|
end
|
65
81
|
|
66
|
-
def
|
82
|
+
def fetch_accounts(ids)
|
67
83
|
id_host = PrxAuth::Rails.configuration.id_host
|
68
84
|
ids_param = ids.map(&:to_s).join(',')
|
69
85
|
|
@@ -72,16 +88,31 @@ module PrxAuth
|
|
72
88
|
|
73
89
|
accounts = URI.open("https://#{id_host}/api/v1/accounts?account_ids=#{ids_param}", options).read
|
74
90
|
|
75
|
-
|
91
|
+
JSON.parse(accounts)['accounts']
|
92
|
+
end
|
76
93
|
|
77
|
-
|
94
|
+
# token from data set by prx_auth rack middleware
|
95
|
+
def env_token
|
96
|
+
@env_token_data ||= if request.env[PRX_AUTH_ENV_KEY]
|
97
|
+
token_data = request.env[PRX_AUTH_ENV_KEY]
|
98
|
+
PrxAuth::Rails::Token.new(token_data)
|
99
|
+
end
|
78
100
|
end
|
79
101
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
102
|
+
# token from jwt stored in session
|
103
|
+
def session_token
|
104
|
+
@session_prx_auth_token ||= if prx_jwt
|
105
|
+
# NOTE: we already validated this jwt - so just decode it
|
106
|
+
validator = Rack::PrxAuth::AuthValidator.new(prx_jwt)
|
107
|
+
|
108
|
+
# try to refresh auth session on GET requests
|
109
|
+
if request.get? && validator.time_to_live < PRX_JWT_REFRESH_TTL
|
110
|
+
raise SessionTokenExpiredError.new
|
111
|
+
end
|
112
|
+
|
113
|
+
# create new data/token from access claims
|
114
|
+
token_data = Rack::PrxAuth::TokenData.new(validator.claims)
|
115
|
+
PrxAuth::Rails::Token.new(token_data)
|
85
116
|
end
|
86
117
|
end
|
87
118
|
end
|
data/prx_auth-rails.gemspec
CHANGED
@@ -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 =
|
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
|
|
@@ -33,7 +31,5 @@ Gem::Specification.new do |spec|
|
|
33
31
|
spec.add_development_dependency 'pry'
|
34
32
|
spec.add_development_dependency 'sqlite3'
|
35
33
|
|
36
|
-
|
37
|
-
|
38
|
-
spec.add_runtime_dependency 'prx_auth', "~> 1.2"
|
34
|
+
spec.add_runtime_dependency 'prx_auth', ">= 1.7.0"
|
39
35
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
the controller index!
|
data/test/dummy/config/routes.rb
CHANGED
@@ -0,0 +1,49 @@
|
|
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
|
+
@stub_claims = {'iat' => Time.now.to_i, 'exp' => Time.now.to_i + 3600}
|
10
|
+
end
|
11
|
+
|
12
|
+
test 'redirects unless you are authenticated' do
|
13
|
+
get :index
|
14
|
+
assert_equal response.code, '302'
|
15
|
+
assert response.headers['Location'].ends_with?('/sessions/new')
|
16
|
+
end
|
17
|
+
|
18
|
+
test 'uses a valid session token' do
|
19
|
+
session[@jwt_session_key] = 'some-jwt'
|
20
|
+
JSON::JWT.stub(:decode, @stub_claims) do
|
21
|
+
get :index
|
22
|
+
assert_equal response.code, '200'
|
23
|
+
assert response.body.include?('the controller index!')
|
24
|
+
assert @controller.current_user.is_a?(PrxAuth::Rails::Token)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
test 'redirects if your token is nearing expiration' do
|
29
|
+
session[@jwt_session_key] = 'some-jwt'
|
30
|
+
@stub_claims['exp'] = Time.now.to_i + 10
|
31
|
+
JSON::JWT.stub(:decode, @stub_claims) do
|
32
|
+
get :index
|
33
|
+
assert_equal response.code, '302'
|
34
|
+
assert response.headers['Location'].ends_with?('/sessions/new')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
test 'does not redirect if your token has expired on a non-GET request' do
|
39
|
+
session[@jwt_session_key] = 'some-jwt'
|
40
|
+
@stub_claims['exp'] = Time.now.to_i + 10
|
41
|
+
JSON::JWT.stub(:decode, @stub_claims) do
|
42
|
+
put :index
|
43
|
+
assert_equal response.code, '200'
|
44
|
+
assert response.body.include?('the controller index!')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
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
|
-
@
|
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,10 +33,13 @@ 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
|
-
|
36
|
-
|
37
|
-
|
38
|
+
@controller.stub(:session_token, @stub_token) do
|
39
|
+
session[@nonce_session_key] = '123'
|
40
|
+
post :create, params: @token_params, format: :json
|
41
|
+
assert session[SessionsController::PRX_JWT_SESSION_KEY] == 'accesstok'
|
42
|
+
end
|
38
43
|
end
|
39
44
|
end
|
40
45
|
|
@@ -48,16 +53,32 @@ module PrxAuth::Rails
|
|
48
53
|
|
49
54
|
test 'create should reset the nonce after consumed' do
|
50
55
|
@controller.stub(:validate_token, @stub_claims) do
|
51
|
-
|
52
|
-
|
56
|
+
@controller.stub(:session_token, @stub_token) do
|
57
|
+
session[@nonce_session_key] = '123'
|
58
|
+
post :create, params: @token_params, format: :json
|
59
|
+
|
60
|
+
assert session[@nonce_session_key] == nil
|
61
|
+
assert response.code == '302'
|
62
|
+
assert response.body.match?(/after-sign-in-path/)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
53
66
|
|
54
|
-
|
55
|
-
|
56
|
-
|
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
|
57
78
|
end
|
58
79
|
end
|
59
80
|
|
60
|
-
test 'should respond with
|
81
|
+
test 'should respond with redirect to the auth error page / code if the nonce does not match' do
|
61
82
|
@controller.stub(:validate_token, @stub_claims) do
|
62
83
|
session[@nonce_session_key] = 'nonce-does-not-match'
|
63
84
|
post :create, params: @token_params, format: :json
|
@@ -82,13 +103,19 @@ module PrxAuth::Rails
|
|
82
103
|
@controller.stub(:id_claims, @stub_claims) do
|
83
104
|
@controller.stub(:access_claims, @stub_claims.merge('sub' => '444')) do
|
84
105
|
|
85
|
-
|
86
|
-
|
106
|
+
session[@nonce_session_key] = '123'
|
107
|
+
post :create, params: @token_params, format: :json
|
87
108
|
|
88
|
-
|
89
|
-
|
90
|
-
|
109
|
+
assert response.code == '302'
|
110
|
+
assert response.body.match?(/error=verification_failed/)
|
111
|
+
end
|
91
112
|
end
|
92
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
|
93
120
|
end
|
94
121
|
end
|
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
|
+
version: 1.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Rhoden
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-03-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -140,19 +140,17 @@ dependencies:
|
|
140
140
|
name: prx_auth
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
|
-
- - "
|
143
|
+
- - ">="
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version:
|
145
|
+
version: 1.7.0
|
146
146
|
type: :runtime
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
|
-
- - "
|
150
|
+
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version:
|
153
|
-
description:
|
154
|
-
|
155
|
-
'
|
152
|
+
version: 1.7.0
|
153
|
+
description: Rails integration for next generation PRX Authorization system.
|
156
154
|
email:
|
157
155
|
- carhoden@gmail.com
|
158
156
|
executables: []
|
@@ -165,9 +163,14 @@ files:
|
|
165
163
|
- LICENSE.txt
|
166
164
|
- README.md
|
167
165
|
- Rakefile
|
166
|
+
- app/assets/config/prx_auth-rails_manifest.js
|
167
|
+
- app/assets/images/prx_auth-rails/user.svg
|
168
|
+
- app/assets/javascripts/prx_auth-rails/user_widget.js.erb
|
169
|
+
- app/assets/stylesheets/prx_auth-rails/user_widget.css
|
168
170
|
- app/controllers/prx_auth/rails/sessions_controller.rb
|
169
171
|
- app/views/prx_auth/rails/sessions/auth_error.html.erb
|
170
172
|
- app/views/prx_auth/rails/sessions/show.html.erb
|
173
|
+
- config/initializers/assets.rb
|
171
174
|
- config/routes.rb
|
172
175
|
- lib/prx_auth/rails.rb
|
173
176
|
- lib/prx_auth/rails/configuration.rb
|
@@ -191,6 +194,7 @@ files:
|
|
191
194
|
- test/dummy/app/mailers/application_mailer.rb
|
192
195
|
- test/dummy/app/models/application_record.rb
|
193
196
|
- test/dummy/app/models/concerns/.keep
|
197
|
+
- test/dummy/app/views/application/index.html.erb
|
194
198
|
- test/dummy/app/views/layouts/application.html.erb
|
195
199
|
- test/dummy/app/views/layouts/mailer.html.erb
|
196
200
|
- test/dummy/app/views/layouts/mailer.text.erb
|
@@ -234,6 +238,7 @@ files:
|
|
234
238
|
- test/dummy/storage/.keep
|
235
239
|
- test/log/development.log
|
236
240
|
- test/prx_auth/rails/configuration_test.rb
|
241
|
+
- test/prx_auth/rails/ext/controller_test.rb
|
237
242
|
- test/prx_auth/rails/sessions_controller_test.rb
|
238
243
|
- test/prx_auth/rails/token_test.rb
|
239
244
|
- test/test_helper.rb
|
@@ -241,7 +246,7 @@ homepage: https://github.com/PRX/prx_auth-rails
|
|
241
246
|
licenses:
|
242
247
|
- MIT
|
243
248
|
metadata: {}
|
244
|
-
post_install_message:
|
249
|
+
post_install_message:
|
245
250
|
rdoc_options: []
|
246
251
|
require_paths:
|
247
252
|
- lib
|
@@ -256,9 +261,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
256
261
|
- !ruby/object:Gem::Version
|
257
262
|
version: '0'
|
258
263
|
requirements: []
|
259
|
-
|
260
|
-
|
261
|
-
signing_key:
|
264
|
+
rubygems_version: 3.0.3
|
265
|
+
signing_key:
|
262
266
|
specification_version: 4
|
263
267
|
summary: Rails integration for next generation PRX Authorization system.
|
264
268
|
test_files:
|
@@ -276,6 +280,7 @@ test_files:
|
|
276
280
|
- test/dummy/app/mailers/application_mailer.rb
|
277
281
|
- test/dummy/app/models/application_record.rb
|
278
282
|
- test/dummy/app/models/concerns/.keep
|
283
|
+
- test/dummy/app/views/application/index.html.erb
|
279
284
|
- test/dummy/app/views/layouts/application.html.erb
|
280
285
|
- test/dummy/app/views/layouts/mailer.html.erb
|
281
286
|
- test/dummy/app/views/layouts/mailer.text.erb
|
@@ -319,6 +324,7 @@ test_files:
|
|
319
324
|
- test/dummy/storage/.keep
|
320
325
|
- test/log/development.log
|
321
326
|
- test/prx_auth/rails/configuration_test.rb
|
327
|
+
- test/prx_auth/rails/ext/controller_test.rb
|
322
328
|
- test/prx_auth/rails/sessions_controller_test.rb
|
323
329
|
- test/prx_auth/rails/token_test.rb
|
324
330
|
- test/test_helper.rb
|