prx_auth-rails 1.3.0 → 1.7.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: 3405e4e72d2c39585111bef4fca339a73ce11ec86a2c288f5c82d8934c0620fe
4
- data.tar.gz: 3450063f4c4fdae2464f755222fafee08c627eda3aa8fee1d267db1474db58de
3
+ metadata.gz: 9a692b8cc459acfdf888599245ff2db7d7ed92a3c967fbccacdd871aa4e78cd7
4
+ data.tar.gz: 17439da5ec7e7cc7f85d00083a47aaebb6d6bd495db25fa75581bf0758726d6c
5
5
  SHA512:
6
- metadata.gz: edf33f5cf4bc105818bb069554506f0b2d9ef5b8bb18cd1602b2ceb6384991804b5b3268c6bd5c519c08e8503df51c132a9bec045f13995c1d55088194fff489
7
- data.tar.gz: 4aa62706ee892c2335756e2c3ae61171b77acc69bfe0ec06433449726f8e884cee4af2031e55e418c6780e9aedc8bfb1c78359c072c089389422a2d4aa15c95b
6
+ metadata.gz: 2a185d858e8a50a33e1f18c85e7dabf5f01a46fbc068dd74d222bb48ab03732ced79c60affd45f7e70efd628cfaaf259e9d4781c390470de86a06dd46158bf0c
7
+ data.tar.gz: d8f2b9c1c1367c2954575950f1ddc731f329f59d111efcb11282d78651a06cf22c74557f834d51ff6fa3ca7360d1cb06ad4736cd2a41d0ff28c5554913fcc193
@@ -0,0 +1,3 @@
1
+ //= link_directory ../javascripts .js
2
+ //= link_directory ../stylesheets .css
3
+ //= link_tree ../images
@@ -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
+ }
@@ -1,5 +1,3 @@
1
- require 'open-uri'
2
-
3
1
  module PrxAuth::Rails
4
2
  class SessionsController < ApplicationController
5
3
  include PrxAuth::Rails::Engine.routes.url_helpers
@@ -29,6 +27,11 @@ module PrxAuth::Rails
29
27
  def show
30
28
  end
31
29
 
30
+ def destroy
31
+ sign_out_user
32
+ redirect_to after_sign_out_path
33
+ end
34
+
32
35
  def auth_error
33
36
  @auth_error_message = params.require(:error)
34
37
  end
@@ -42,6 +45,7 @@ module PrxAuth::Rails
42
45
  result_path = if valid_nonce?(jwt_id_claims['nonce']) &&
43
46
  users_match?(jwt_id_claims, jwt_access_claims)
44
47
  sign_in_user(jwt_access_claims)
48
+ lookup_and_register_accounts_names
45
49
  after_sign_in_path_for(current_user)
46
50
  else
47
51
  auth_error_sessions_path(error: 'verification_failed')
@@ -59,6 +63,12 @@ module PrxAuth::Rails
59
63
  "/"
60
64
  end
61
65
 
66
+ def after_sign_out_path
67
+ return super if defined?(super)
68
+
69
+ "https://#{id_host}/session/sign_out"
70
+ end
71
+
62
72
  def id_claims
63
73
  id_token = params.require('id_token')
64
74
  validate_token(id_token)
@@ -97,12 +107,15 @@ module PrxAuth::Rails
97
107
  end
98
108
 
99
109
  def validate_token(token)
100
- id_host = PrxAuth::Rails.configuration.id_host
101
110
  prx_auth_cert = Rack::PrxAuth::Certificate.new("https://#{id_host}/api/v1/certs")
102
111
  auth_validator = Rack::PrxAuth::AuthValidator.new(token, prx_auth_cert, id_host)
103
112
  auth_validator.
104
113
  claims.
105
114
  with_indifferent_access
106
115
  end
116
+
117
+ def id_host
118
+ PrxAuth::Rails.configuration.id_host
119
+ end
107
120
  end
108
121
  end
@@ -0,0 +1 @@
1
+ Rails.application.config.assets.precompile << %w(prx_auth-rails_manifest.js)
@@ -1,5 +1,9 @@
1
1
  module PrxAuth
2
2
  module Rails
3
- class Engine < ::Rails::Engine; end
3
+ class Engine < ::Rails::Engine
4
+ config.to_prepare do
5
+ ::ApplicationController.helper_method [:current_user, :account_name_for]
6
+ end
7
+ end
4
8
  end
5
9
  end
@@ -1,13 +1,18 @@
1
1
  require 'prx_auth/rails/token'
2
+ require 'open-uri'
2
3
 
3
4
  module PrxAuth
4
5
  module Rails
5
6
  module Controller
7
+
8
+ PRX_ACCOUNT_NAME_MAPPING_KEY = 'prx.account.name.mapping'.freeze
9
+ PRX_TOKEN_SESSION_KEY = 'prx.auth'.freeze
10
+
6
11
  def prx_auth_token
7
12
  rack_auth_token = env_prx_auth_token
8
13
  return rack_auth_token if rack_auth_token.present?
9
14
 
10
- session['prx.auth'] && Rack::PrxAuth::TokenData.new(session['prx.auth'])
15
+ session[PRX_TOKEN_SESSION_KEY] && Rack::PrxAuth::TokenData.new(session[PRX_TOKEN_SESSION_KEY])
11
16
  end
12
17
 
13
18
  def prx_authenticated?
@@ -26,12 +31,59 @@ module PrxAuth
26
31
  PrxAuth::Rails::Token.new(prx_auth_token)
27
32
  end
28
33
 
34
+ def lookup_and_register_accounts_names
35
+ session[PRX_ACCOUNT_NAME_MAPPING_KEY] =
36
+ lookup_account_names_mapping
37
+ end
38
+
39
+ def account_name_for(id)
40
+ id = id.to_i
41
+
42
+ session[PRX_ACCOUNT_NAME_MAPPING_KEY] ||= {}
43
+
44
+ name =
45
+ if session[PRX_ACCOUNT_NAME_MAPPING_KEY].has_key?(id)
46
+ session[PRX_ACCOUNT_NAME_MAPPING_KEY][id]
47
+ else
48
+ session[PRX_ACCOUNT_NAME_MAPPING_KEY][id] = lookup_account_name_for(id)
49
+ end
50
+
51
+ name = "[#{id}] Unknown Account Name" unless name.present?
52
+
53
+ name
54
+ end
55
+
29
56
  def sign_in_user(token)
30
- session['prx.auth'] = token
57
+ session[PRX_TOKEN_SESSION_KEY] = token
58
+ end
59
+
60
+ def sign_out_user
61
+ session.delete(PRX_TOKEN_SESSION_KEY)
31
62
  end
32
63
 
33
64
  private
34
65
 
66
+ def lookup_account_name_for(id)
67
+ id = id.to_i
68
+
69
+ res = lookup_account_names_mapping([id])
70
+ res[id]
71
+ end
72
+
73
+ def lookup_account_names_mapping(ids=current_user.resources)
74
+ id_host = PrxAuth::Rails.configuration.id_host
75
+ ids_param = ids.map(&:to_s).join(',')
76
+
77
+ options = {}
78
+ options[:ssl_verify_mode] = OpenSSL::SSL::VERIFY_NONE if ::Rails.env.development?
79
+
80
+ accounts = URI.open("https://#{id_host}/api/v1/accounts?account_ids=#{ids_param}", options).read
81
+
82
+ mapping = JSON.parse(accounts)['accounts'].map { |acct| [acct['id'], acct['display_name']] }.to_h
83
+
84
+ mapping
85
+ end
86
+
35
87
  def env_prx_auth_token
36
88
  if !defined? @_prx_auth_token
37
89
  @_prx_auth_token = request.env['prx.auth'] && PrxAuth::Rails::Token.new(request.env['prx.auth'])
@@ -1,5 +1,5 @@
1
1
  module PrxAuth
2
2
  module Rails
3
- VERSION = "1.3.0"
3
+ VERSION = "1.7.0"
4
4
  end
5
5
  end
@@ -32,9 +32,11 @@ module PrxAuth::Rails
32
32
 
33
33
  test 'create should validate a token and set the session variable' do
34
34
  @controller.stub(:validate_token, @stub_claims) do
35
- session[@nonce_session_key] = '123'
36
- post :create, params: @token_params, format: :json
37
- assert session['prx.auth']['id_token']['nonce'] == '123'
35
+ @controller.stub(:lookup_and_register_accounts_names, nil) do
36
+ session[@nonce_session_key] = '123'
37
+ post :create, params: @token_params, format: :json
38
+ assert session['prx.auth']['id_token']['nonce'] == '123'
39
+ end
38
40
  end
39
41
  end
40
42
 
@@ -48,16 +50,18 @@ module PrxAuth::Rails
48
50
 
49
51
  test 'create should reset the nonce after consumed' do
50
52
  @controller.stub(:validate_token, @stub_claims) do
51
- session[@nonce_session_key] = '123'
52
- post :create, params: @token_params, format: :json
53
-
54
- assert session[@nonce_session_key] == nil
55
- assert response.code == '302'
56
- assert response.body.match?(/after-sign-in-path/)
53
+ @controller.stub(:lookup_and_register_accounts_names, nil) do
54
+ session[@nonce_session_key] = '123'
55
+ post :create, params: @token_params, format: :json
56
+
57
+ assert session[@nonce_session_key] == nil
58
+ assert response.code == '302'
59
+ assert response.body.match?(/after-sign-in-path/)
60
+ end
57
61
  end
58
62
  end
59
63
 
60
- test 'should respond with aredirect to the auth error page / code if the nonce does not match' do
64
+ test 'should respond with redirect to the auth error page / code if the nonce does not match' do
61
65
  @controller.stub(:validate_token, @stub_claims) do
62
66
  session[@nonce_session_key] = 'nonce-does-not-match'
63
67
  post :create, params: @token_params, format: :json
@@ -82,13 +86,19 @@ module PrxAuth::Rails
82
86
  @controller.stub(:id_claims, @stub_claims) do
83
87
  @controller.stub(:access_claims, @stub_claims.merge('sub' => '444')) do
84
88
 
85
- session[@nonce_session_key] = '123'
86
- post :create, params: @token_params, format: :json
89
+ session[@nonce_session_key] = '123'
90
+ post :create, params: @token_params, format: :json
87
91
 
88
- assert response.code == '302'
89
- assert response.body.match?(/error=verification_failed/)
90
- end
92
+ assert response.code == '302'
93
+ assert response.body.match?(/error=verification_failed/)
94
+ end
91
95
  end
92
96
  end
97
+
98
+ test 'should clear the user token on sign out' do
99
+ session[PrxAuth::Rails::Controller::PRX_TOKEN_SESSION_KEY] = 'some-token'
100
+ post :destroy
101
+ assert session[PrxAuth::Rails::Controller::PRX_TOKEN_SESSION_KEY] == nil
102
+ end
93
103
  end
94
104
  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.3.0
4
+ version: 1.7.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-01-19 00:00:00.000000000 Z
11
+ date: 2021-03-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -165,9 +165,14 @@ files:
165
165
  - LICENSE.txt
166
166
  - README.md
167
167
  - Rakefile
168
+ - app/assets/config/prx_auth-rails_manifest.js
169
+ - app/assets/images/prx_auth-rails/user.svg
170
+ - app/assets/javascripts/prx_auth-rails/user_widget.js.erb
171
+ - app/assets/stylesheets/prx_auth-rails/user_widget.css
168
172
  - app/controllers/prx_auth/rails/sessions_controller.rb
169
173
  - app/views/prx_auth/rails/sessions/auth_error.html.erb
170
174
  - app/views/prx_auth/rails/sessions/show.html.erb
175
+ - config/initializers/assets.rb
171
176
  - config/routes.rb
172
177
  - lib/prx_auth/rails.rb
173
178
  - lib/prx_auth/rails/configuration.rb