hubssolib 3.0.0 → 3.0.1

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: f418c1a21497375e396be12fd95387b6a436ed42c8145dc681ee041eded447a3
4
- data.tar.gz: 06d7868acf059c7c9df758d960b508e6e063fb0f1b012ff520a549772079a486
3
+ metadata.gz: 36b026e98baa7f70c200a5abe0ff7e5e3a874e9aaf5a1f88c33114e45cb1ab14
4
+ data.tar.gz: d19ff3d675d0b63286e06c03b6c3bce05be434a16f554533efde1152bb9c2641
5
5
  SHA512:
6
- metadata.gz: fa015b2a0853402ee85b23c788bfd52a15cbda02c000ad0c6f6eba882e664393fe7927119f2b53c2f396d9b8f6d9337b85bdfa5fe50866e07a9fe7942b8700cf
7
- data.tar.gz: 006b768e21fe802806c946062b0e74be65cad124833f861455f09f684887c09104f281450b08295bf9c17f472e1839c291b6f6422212cbf9717d03d8925ba3c6
6
+ metadata.gz: a8d0724e454ffab27e616a91b1aa9837d4aefa5dff6d871bb92671ddefda789626e7cf3ed2dc523b48d4a09bcb3210c81ff279c7e553d2d579c8b00d6af693dd
7
+ data.tar.gz: 36f17712168ba66f8de41193c41959dfa3ddb81e1ae5c683f4f747d177a6e4f5643aee2a8b387eaa244f0945608ee88f70552143f58f344e2a4078dabbf65ea4
data/CHANGELOG.md CHANGED
@@ -1,22 +1,55 @@
1
- ## 3.0.0, 28-Jan-2025
1
+ ## 3.0.0, 28-Jan-2025 and 3.0.1, 03-Feb-2025
2
2
 
3
- * The Hub "login indication" URL approach is now dropped, so layout templates **must be updated.**
3
+ * The Hub "login indication" URL approach is now dropped, so layout templates **should be updated.**
4
4
 
5
5
  In Hub v1 and v2, login indication was done via an image that was served by the Hub application itself, wrapped in a link that visited a "conditional login" endpoint which stored the return-to URL, ensured HTTPS was in use and visited either the log in, or log out page as required. In client applications it looked a bit like this:
6
6
 
7
7
  ```html
8
- <a class="img" href="<%= ENV['HUB_PATH_PREFIX'] %>/account/login_conditional">
9
- <img src="<%= ENV['HUB_PATH_PREFIX'] %>/account/login_indication" alt="Account" height="22" width="90" />
10
- </a>
8
+ <a class="img" href="<%= ENV['HUB_PATH_PREFIX'] %>/account/login_conditional">
9
+ <img src="<%= ENV['HUB_PATH_PREFIX'] %>/account/login_indication" alt="Account" height="22" width="90" />
10
+ </a>
11
11
  ```
12
12
 
13
- This dates back to a time when CSS support was not that widespread and RISC OS Open needed the web site to work well on web browsers available at the time. Things have improved enormously since then, so now a cleaner, pure CSS solution is used. This has the enormous advantage of requiring no image fetch request-response into the Hub application. Just use:
13
+ This dates back to a time when CSS support was not that widespread and RISC OS Open needed the web site to work well on web browsers available at the time. Things have improved considerably since then, so now a cleaner, pure CSS solution is used. This requires no image fetch via the Hub application. Just use:
14
14
 
15
15
  ```ruby
16
16
  <%= hubssolib_account_link() %>
17
17
  ```
18
18
 
19
- ...in place of the markup above.
19
+ ...in place of the markup above. You probably want to add some supporting CSS too; for example:
20
+
21
+ ```css
22
+ #hubssolib_login_indication a#hubssolib_logged_in_link,
23
+ #hubssolib_login_indication a#hubssolib_logged_out_link {
24
+ display: block;
25
+ text-align: center;
26
+ text-decoration: none;
27
+ font: sans-serif;
28
+ font-size: 10pt;
29
+ line-height: 20px;
30
+ height: 20px;
31
+ width: 88px;
32
+ border: 1px solid #ccc;
33
+ }
34
+
35
+ #hubssolib_login_indication a#hubssolib_logged_in_link {
36
+ color: #050;
37
+ border-color: #050;
38
+ background: #efe;
39
+ }
40
+
41
+ #hubssolib_login_indication a#hubssolib_logged_out_link {
42
+ color: #500;
43
+ border-color: #500;
44
+ background: #fee;
45
+ }
46
+
47
+ #hubssolib_login_indication a#hubssolib_login_noscript {
48
+ text-decoration: none;
49
+ }
50
+ ```
51
+
52
+ Version 3.0.1 patches the system to make sure that the correct current login state is shown even if a browser has a page cached. To achieve this, JavaScript is used to check cookie state and update the indication on-the-fly. There is a `noscript` fallback that uses the old, inefficient `login_indication` image mechanism - just in case. The CSS styles above are designed to match those images, though of course, they certainly don't have to!
20
53
 
21
54
 
22
55
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- hubssolib (3.0.0)
4
+ hubssolib (3.0.1)
5
5
  base64 (~> 0.2)
6
6
  drb (~> 2.2)
7
7
 
data/README.md CHANGED
@@ -48,7 +48,7 @@ Finally you can install the Hub application using whatever mechanism you prefer
48
48
 
49
49
  Some configuration is needed using externally set environment variables. These are actually picked up by the Hub gem but you won't know what values to set until the application, DRb server and gem are all installed.
50
50
 
51
- * `HUB_CONNECTION_URI` — as already discussed, this must hold a DRb URI giving the connection socket on which the server listens and to which clients connect.
51
+ * `HUB_CONNECTION_URI` — as already discussed, this holds a DRb URI giving the connection socket on which the server listens and to which clients connect; it defaults to `~/.hub_drb`.
52
52
  * `HUB_PATH_PREFIX` — sometimes the Hub Gem redirects to various locations within the Hub application. If you have installed the application away from document root, specify the prefix to put onto redirection paths here (otherwise, provide an empty string). For example, when redirecting to the `account` controller's `login` method, the path used is `HUB_PATH_PREFIX + '/account/login'`.
53
53
  * `HUB_BYPASS_SSL` - normally Hub sets cookies as secure-only in Production mode, requiring `https` fetches. This isn't enforced in e.g. development mode. If you want to allow insecure transport in Production, set `HUB_BYPASS_SSL` to `true`.
54
54
 
@@ -69,11 +69,22 @@ bundle exec rails s -b 127.0.0.1 --port 3000
69
69
  ...and then launch integrating applications with:
70
70
 
71
71
  ```
72
- HUB_PATH_PREFIX="http://127.0.0.1:3000" be rails s -b 127.0.0.1 --port <other-port>
72
+ HUB_BYPASS_SSL="true" HUB_PATH_PREFIX="http://127.0.0.1:3000" be rails s -b 127.0.0.1 --port <other-port>
73
73
  ```
74
74
 
75
75
  ...and fetch `http://127.0.0.1:<other-port>` in your web browser.
76
76
 
77
+ ## Your application's session cookies
78
+
79
+ It is often a good idea to clear application cookies when Hub users log in or out, so that there is no stale session data hanging around. **The Hub application auto-clears *all* cookies *ending with* the name `app_session`** for this purpose. Therefore, your application might include a `config/initializers/session_store.rb` file that says something like this:
80
+
81
+ ```ruby
82
+ # Be sure to restart your server when you modify this file.
83
+ Rails.application.config.session_store :cookie_store, key: 'yourappname_app_session'
84
+ ```
85
+
86
+ This of course only applies if you're using cookies for your session data.
87
+
77
88
  ## Testing the installation
78
89
 
79
90
  Visit your application in a Web browser and follow the links to sign up for a new account. To sign up, provide a name that will be displayed to users and a valid e-mail address. A confirmation message is sent to the address, containing a link that must be followed to activate the account. One created, users can log in and out of their accounts (with the possibility of sending a password reset request to their e-mail address in case they forget how to log in) and change their screen names. Users cannot change their recorded e-mail address — instead, they must create a new account under the new address.
data/hubssolib.gemspec CHANGED
@@ -4,7 +4,7 @@ spec = Gem::Specification.new do |s|
4
4
  s.platform = Gem::Platform::RUBY
5
5
  s.name = 'hubssolib'
6
6
 
7
- s.version = '3.0.0'
7
+ s.version = '3.0.1'
8
8
  s.author = 'Andrew Hodgkinson and others'
9
9
  s.email = 'ahodgkin@rowing.org.uk'
10
10
  s.homepage = 'http://pond.org.uk/'
data/lib/hub_sso_lib.rb CHANGED
@@ -44,6 +44,10 @@ module HubSsoLib
44
44
  # Shared cookie name.
45
45
  HUB_COOKIE_NAME = 'hubapp_shared_id'
46
46
 
47
+ # Principally for #hubssolib_account_link.
48
+ HUB_LOGIN_INDICATOR_COOKIE = 'hubapp_shared_id_alive'
49
+ HUB_LOGIN_INDICATOR_COOKIE_VALUE = 'Y'
50
+
47
51
  # Bypass SSL, for testing purposes? Rails 'production' mode will
48
52
  # insist on SSL otherwise. Development & test environments do not,
49
53
  # so do not need this variable setting.
@@ -523,20 +527,60 @@ module HubSsoLib
523
527
  # used in page templates to avoid needing any additional images or other
524
528
  # such resources and using pure HTML + CSS for the login indication.
525
529
  #
530
+ # JavaScript is used so that e.g. "back" button fully-cached displays by a
531
+ # browser will get updated with the correct login state, where needed (so
532
+ # long as the 'pageshow' event is supported). NOSCRIPT browsers use the old
533
+ # no-cache image fallback, which is much less efficient, but works.
534
+ #
526
535
  def hubssolib_account_link
527
- logged_in = self.hubssolib_logged_in?()
536
+ logged_in = self.hubssolib_logged_in?()
528
537
 
529
- text, klass, style = if logged_in
530
- ['Account', 'hubssolib_logged_in', 'border: 1px solid #050; color: #050; background: #efe;']
531
- else
532
- ['Log in', 'hubssolib_logged_out', 'border: 1px solid #500; color: #500; background: #fee;']
533
- end
538
+ ui_href = "#{HUB_PATH_PREFIX}/account/login_conditional"
539
+ noscript_img_src = "#{HUB_PATH_PREFIX}/account/login_indication.png"
540
+ noscript_img_tag = helpers.image_tag(noscript_img_src, size: '90x22', border: '0', alt: 'Log in or out')
534
541
 
535
- style << ' display: block; width: 88px; height; 20px;'
536
- style << ' text-align: center; line-height: 20px;'
537
- style << ' font: sans-serif; font-size: 10pt'
542
+ logged_in_link = helpers.link_to('Account', ui_href, id: 'hubssolib_logged_in_link')
543
+ logged_out_link = helpers.link_to('Log in', ui_href, id: 'hubssolib_logged_out_link')
544
+ noscript_link = helpers.link_to(noscript_img_tag, ui_href, id: 'hubssolib_login_noscript')
538
545
 
539
- "<a href=\"#{HUB_PATH_PREFIX}/account/login_conditional\" class=\"#{klass}\" style=\"#{style}\">#{text}</a>".html_safe()
546
+ # Yes, it's ugly, but yes, it works and it's a lot better for the server
547
+ # to avoid the repeated image fetches. It probably works out as overall
548
+ # more efficient for clients too - despite all the JS etc. work, there's
549
+ # no network fetch overhead or image rendering. On mobile in particular,
550
+ # the JS solution is likely to use less battery power.
551
+ #
552
+ safe_markup = <<~HTML
553
+ <div id="hubssolib_login_indication">
554
+ <noscript>
555
+ #{noscript_link}
556
+ </noscript>
557
+ </div>
558
+ <script type="text/javascript">
559
+ const logged_in_html = "#{helpers.j(logged_in_link)}";
560
+ const logged_out_html = "#{helpers.j(logged_out_link)}";
561
+ const container = document.getElementById('hubssolib_login_indication')
562
+
563
+ function hubSsoLibLoginStateWriteLink() {
564
+ const regexp = '#{helpers.j(HUB_LOGIN_INDICATOR_COOKIE)}\\s*=\\s*([^;]+)';
565
+ const flag = document.cookie.match(regexp)?.pop() || '';
566
+
567
+ if (flag === '#{HUB_LOGIN_INDICATOR_COOKIE_VALUE}') {
568
+ container.innerHTML = logged_in_html;
569
+ } else {
570
+ container.innerHTML = logged_out_html;
571
+ }
572
+ }
573
+ #{
574
+ # Immediate update, plus on-load update - including fully cached
575
+ # loads in the browser when the "Back" button is used. No stale
576
+ # login indications should thus arise from cached data.
577
+ }
578
+ hubSsoLibLoginStateWriteLink();
579
+ window.addEventListener('pageshow', hubSsoLibLoginStateWriteLink);
580
+ </script>
581
+ HTML
582
+
583
+ return safe_markup.html_safe()
540
584
  end
541
585
 
542
586
  # Check if the user is authorized to perform the current action. If calling
@@ -665,7 +709,7 @@ module HubSsoLib
665
709
  def hubssolib_beforehand
666
710
 
667
711
  # Does this action require a logged in user?
668
-
712
+ #
669
713
  if (self.class.respond_to? :hubssolib_permissions)
670
714
  login_is_required = !self.class.hubssolib_permissions.permitted?('', action_name)
671
715
  else
@@ -673,19 +717,30 @@ module HubSsoLib
673
717
  end
674
718
 
675
719
  # If we require login but we're logged out, redirect to Hub login.
676
-
720
+ # NOTE EARLY EXIT
721
+ #
677
722
  logged_in = hubssolib_logged_in?
678
723
 
679
- if (login_is_required and logged_in == false)
680
- hubssolib_store_location
681
- return hubssolib_must_login
682
- end
724
+ if logged_in == false
725
+ cookies.delete(HUB_LOGIN_INDICATOR_COOKIE)
683
726
 
684
- # If we reach here the user is either logged, or the method does
685
- # not require them to be. In the latter case, if we're not logged
686
- # in there is no more work to do - exit early.
727
+ if login_is_required
728
+ hubssolib_store_location
729
+ return hubssolib_must_login
730
+ else
731
+ return true
732
+ end
733
+ end
687
734
 
688
- return true unless logged_in # true -> let action processing continue
735
+ # Definitely logged in.
736
+ #
737
+ cookies[HUB_LOGIN_INDICATOR_COOKIE] = {
738
+ value: HUB_LOGIN_INDICATOR_COOKIE_VALUE,
739
+ domain: :all,
740
+ path: '/',
741
+ secure: ! hub_bypass_ssl?,
742
+ httponly: false
743
+ }
689
744
 
690
745
  # So we reach here knowing we're logged in, but the action may or
691
746
  # may not require authorisation.
@@ -983,11 +1038,11 @@ module HubSsoLib
983
1038
  key = hub_session.session_key_rotation unless hub_session.nil?
984
1039
 
985
1040
  cookies[HUB_COOKIE_NAME] = {
986
- :value => key,
987
- :domain => :all,
988
- :path => '/',
989
- :secure => ! hub_bypass_ssl?,
990
- :httponly => true
1041
+ value: key,
1042
+ domain: :all,
1043
+ path: '/',
1044
+ secure: ! hub_bypass_ssl?,
1045
+ httponly: true
991
1046
  }
992
1047
 
993
1048
  return hub_session
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hubssolib
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Hodgkinson and others
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-01-28 00:00:00.000000000 Z
10
+ date: 2025-02-03 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: drb