hubssolib 3.8.0 → 3.8.2

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: 32438e5c41d655367f4bb0e8385b9d972645f2649871a09ab7b09dc5d617fe9e
4
- data.tar.gz: a999f01f88325690644675acc1b06b33b7b275374e980c6c3f2fa346c3875d93
3
+ metadata.gz: 6b90f9617fc1a625f402510ee5497d4d357f914d7f35284e6c1e25b62ae07f4b
4
+ data.tar.gz: 450ead4d1423e6b42fd6a0aba65fdf043d6c5e3a6c3dc1b7b04412b2fcd4e65c
5
5
  SHA512:
6
- metadata.gz: 881e57fa9c2e42ed8465b2faabf98cabdacf2dcea5df20d3c617836e50ff74d2255bbe1b8c11ca39b0bb3d57f2927e229ca1a390de11d0fcff9b8e4b32851ae6
7
- data.tar.gz: 15aa2e97054fe9a8a86e45d901bdfa36bff0d0a6473ba88d279ec0bf622ce8413e6bc1a7b0427bac1f0e2bc0c2b994d9a3550d48897a8efec7cf2acf0c74abfa
6
+ metadata.gz: 1a03c285659733df8dd98c93faaf458549229c8a096cba58c797c04139788bddf2592c2a12b99a5c87d02ffac4a936db703317d4957ec48d25790a21eb3ddadb
7
+ data.tar.gz: b392255f66a678625bab09ec613d69f77ab8cf60818764fcc4b2b55028e317854e24e8125a527ccac598b6845ba10f794524ffa82579a2f5ef30258fafbba887
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## 3.8.2, 17-May-2025
2
+
3
+ * General maintenance update.
4
+
5
+ ## 3.8.1, 09-Apr-2025
6
+
7
+ * It's been too long since I worked with DRb! Important fix for "live" (undumpable) vs copied objects which could lead to session enumeration problems in clients. Now, sessions enumerated by user ID are copies as is user data returned by HubSsoLib::Core#hubssolib_enumerate_users.
8
+ * Other data is still live, since there's a fair amount of write-back that expects to be updating objects held by the DRb server itself. This will all get replaced by database storage in HubSsoLib 4, so I'm not going to address the weaknesses present wherein a session might be expired or deleted "under the feet" of a client. The Hub gem's own write-based operations are all on a "current" session, so that could only vanish if an admin independently elected to destroy all user sessions via the Hub Rails app front-end. The implication is that the other user was probably up to no good, and I don't really mind if they just seem to be suddenly logged out, or see a 500 error due to a _very_ inconveniently-timed page fetch.
9
+
1
10
  ## 3.8.0, 03-Apr-2025
2
11
 
3
12
  * Adds helper `HubSsoLib::Core#hubssolib_flash_markup` to compliment `HubSsoLib::Core#hubssolib_flash_data` and help make Flash presentation simpler and more consistent across integrated applications.
data/Gemfile.lock CHANGED
@@ -1,36 +1,38 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- hubssolib (3.8.0)
4
+ hubssolib (3.8.2)
5
5
  base64 (~> 0.2)
6
6
  drb (~> 2.2)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- actioncable (8.0.2)
12
- actionpack (= 8.0.2)
13
- activesupport (= 8.0.2)
11
+ action_text-trix (2.1.19)
12
+ railties
13
+ actioncable (8.1.3)
14
+ actionpack (= 8.1.3)
15
+ activesupport (= 8.1.3)
14
16
  nio4r (~> 2.0)
15
17
  websocket-driver (>= 0.6.1)
16
18
  zeitwerk (~> 2.6)
17
- actionmailbox (8.0.2)
18
- actionpack (= 8.0.2)
19
- activejob (= 8.0.2)
20
- activerecord (= 8.0.2)
21
- activestorage (= 8.0.2)
22
- activesupport (= 8.0.2)
19
+ actionmailbox (8.1.3)
20
+ actionpack (= 8.1.3)
21
+ activejob (= 8.1.3)
22
+ activerecord (= 8.1.3)
23
+ activestorage (= 8.1.3)
24
+ activesupport (= 8.1.3)
23
25
  mail (>= 2.8.0)
24
- actionmailer (8.0.2)
25
- actionpack (= 8.0.2)
26
- actionview (= 8.0.2)
27
- activejob (= 8.0.2)
28
- activesupport (= 8.0.2)
26
+ actionmailer (8.1.3)
27
+ actionpack (= 8.1.3)
28
+ actionview (= 8.1.3)
29
+ activejob (= 8.1.3)
30
+ activesupport (= 8.1.3)
29
31
  mail (>= 2.8.0)
30
32
  rails-dom-testing (~> 2.2)
31
- actionpack (8.0.2)
32
- actionview (= 8.0.2)
33
- activesupport (= 8.0.2)
33
+ actionpack (8.1.3)
34
+ actionview (= 8.1.3)
35
+ activesupport (= 8.1.3)
34
36
  nokogiri (>= 1.8.5)
35
37
  rack (>= 2.2.4)
36
38
  rack-session (>= 1.0.1)
@@ -38,87 +40,93 @@ GEM
38
40
  rails-dom-testing (~> 2.2)
39
41
  rails-html-sanitizer (~> 1.6)
40
42
  useragent (~> 0.16)
41
- actiontext (8.0.2)
42
- actionpack (= 8.0.2)
43
- activerecord (= 8.0.2)
44
- activestorage (= 8.0.2)
45
- activesupport (= 8.0.2)
43
+ actiontext (8.1.3)
44
+ action_text-trix (~> 2.1.15)
45
+ actionpack (= 8.1.3)
46
+ activerecord (= 8.1.3)
47
+ activestorage (= 8.1.3)
48
+ activesupport (= 8.1.3)
46
49
  globalid (>= 0.6.0)
47
50
  nokogiri (>= 1.8.5)
48
- actionview (8.0.2)
49
- activesupport (= 8.0.2)
51
+ actionview (8.1.3)
52
+ activesupport (= 8.1.3)
50
53
  builder (~> 3.1)
51
54
  erubi (~> 1.11)
52
55
  rails-dom-testing (~> 2.2)
53
56
  rails-html-sanitizer (~> 1.6)
54
- activejob (8.0.2)
55
- activesupport (= 8.0.2)
57
+ activejob (8.1.3)
58
+ activesupport (= 8.1.3)
56
59
  globalid (>= 0.3.6)
57
- activemodel (8.0.2)
58
- activesupport (= 8.0.2)
59
- activerecord (8.0.2)
60
- activemodel (= 8.0.2)
61
- activesupport (= 8.0.2)
60
+ activemodel (8.1.3)
61
+ activesupport (= 8.1.3)
62
+ activerecord (8.1.3)
63
+ activemodel (= 8.1.3)
64
+ activesupport (= 8.1.3)
62
65
  timeout (>= 0.4.0)
63
- activestorage (8.0.2)
64
- actionpack (= 8.0.2)
65
- activejob (= 8.0.2)
66
- activerecord (= 8.0.2)
67
- activesupport (= 8.0.2)
66
+ activestorage (8.1.3)
67
+ actionpack (= 8.1.3)
68
+ activejob (= 8.1.3)
69
+ activerecord (= 8.1.3)
70
+ activesupport (= 8.1.3)
68
71
  marcel (~> 1.0)
69
- activesupport (8.0.2)
72
+ activesupport (8.1.3)
70
73
  base64
71
- benchmark (>= 0.3)
72
74
  bigdecimal
73
75
  concurrent-ruby (~> 1.0, >= 1.3.1)
74
76
  connection_pool (>= 2.2.5)
75
77
  drb
76
78
  i18n (>= 1.6, < 2)
79
+ json
77
80
  logger (>= 1.4.2)
78
81
  minitest (>= 5.1)
79
82
  securerandom (>= 0.3)
80
83
  tzinfo (~> 2.0, >= 2.0.5)
81
84
  uri (>= 0.13.1)
82
- base64 (0.2.0)
83
- benchmark (0.4.0)
84
- bigdecimal (3.1.9)
85
+ base64 (0.3.0)
86
+ bigdecimal (4.1.2)
85
87
  builder (3.3.0)
86
- concurrent-ruby (1.3.5)
87
- connection_pool (2.5.0)
88
+ concurrent-ruby (1.3.6)
89
+ connection_pool (3.0.2)
88
90
  crass (1.0.6)
89
- date (3.4.1)
90
- debug (1.10.0)
91
+ date (3.5.1)
92
+ debug (1.11.1)
91
93
  irb (~> 1.10)
92
94
  reline (>= 0.3.8)
93
- diff-lcs (1.6.1)
95
+ diff-lcs (1.6.2)
94
96
  docile (1.4.1)
95
97
  doggo (1.4.0)
96
98
  rspec-core (~> 3.13)
97
- drb (2.2.1)
99
+ drb (2.2.3)
100
+ erb (6.0.4)
98
101
  erubi (1.13.1)
99
- globalid (1.2.1)
102
+ globalid (1.3.0)
100
103
  activesupport (>= 6.1)
101
- i18n (1.14.7)
104
+ i18n (1.14.8)
102
105
  concurrent-ruby (~> 1.0)
103
- io-console (0.8.0)
104
- irb (1.15.2)
106
+ io-console (0.8.2)
107
+ irb (1.18.0)
105
108
  pp (>= 0.6.0)
109
+ prism (>= 1.3.0)
106
110
  rdoc (>= 4.0.0)
107
111
  reline (>= 0.4.2)
112
+ json (2.19.5)
108
113
  logger (1.7.0)
109
- loofah (2.24.0)
114
+ loofah (2.25.1)
110
115
  crass (~> 1.0.2)
111
116
  nokogiri (>= 1.12.0)
112
- mail (2.8.1)
117
+ mail (2.9.0)
118
+ logger
113
119
  mini_mime (>= 0.1.1)
114
120
  net-imap
115
121
  net-pop
116
122
  net-smtp
117
- marcel (1.0.4)
123
+ marcel (1.1.0)
118
124
  mini_mime (1.1.5)
119
- mini_portile2 (2.8.8)
120
- minitest (5.25.5)
121
- net-imap (0.5.6)
125
+ mini_portile2 (2.8.9)
126
+ minitest (6.0.6)
127
+ drb (~> 2.0)
128
+ prism (~> 1.5)
129
+ net-imap (0.6.4)
122
130
  date
123
131
  net-protocol
124
132
  net-pop (0.1.2)
@@ -127,91 +135,96 @@ GEM
127
135
  timeout
128
136
  net-smtp (0.5.1)
129
137
  net-protocol
130
- nio4r (2.7.4)
131
- nokogiri (1.18.7)
138
+ nio4r (2.7.5)
139
+ nokogiri (1.19.3)
132
140
  mini_portile2 (~> 2.8.2)
133
141
  racc (~> 1.4)
134
- pp (0.6.2)
142
+ pp (0.6.3)
135
143
  prettyprint
136
144
  prettyprint (0.2.0)
137
- psych (5.2.3)
145
+ prism (1.9.0)
146
+ psych (5.3.1)
138
147
  date
139
148
  stringio
140
149
  racc (1.8.1)
141
- rack (3.1.12)
142
- rack-session (2.1.0)
150
+ rack (3.2.6)
151
+ rack-session (2.1.2)
143
152
  base64 (>= 0.1.0)
144
153
  rack (>= 3.0.0)
145
154
  rack-test (2.2.0)
146
155
  rack (>= 1.3)
147
- rackup (2.2.1)
156
+ rackup (2.3.1)
148
157
  rack (>= 3)
149
- rails (8.0.2)
150
- actioncable (= 8.0.2)
151
- actionmailbox (= 8.0.2)
152
- actionmailer (= 8.0.2)
153
- actionpack (= 8.0.2)
154
- actiontext (= 8.0.2)
155
- actionview (= 8.0.2)
156
- activejob (= 8.0.2)
157
- activemodel (= 8.0.2)
158
- activerecord (= 8.0.2)
159
- activestorage (= 8.0.2)
160
- activesupport (= 8.0.2)
158
+ rails (8.1.3)
159
+ actioncable (= 8.1.3)
160
+ actionmailbox (= 8.1.3)
161
+ actionmailer (= 8.1.3)
162
+ actionpack (= 8.1.3)
163
+ actiontext (= 8.1.3)
164
+ actionview (= 8.1.3)
165
+ activejob (= 8.1.3)
166
+ activemodel (= 8.1.3)
167
+ activerecord (= 8.1.3)
168
+ activestorage (= 8.1.3)
169
+ activesupport (= 8.1.3)
161
170
  bundler (>= 1.15.0)
162
- railties (= 8.0.2)
163
- rails-dom-testing (2.2.0)
171
+ railties (= 8.1.3)
172
+ rails-dom-testing (2.3.0)
164
173
  activesupport (>= 5.0.0)
165
174
  minitest
166
175
  nokogiri (>= 1.6)
167
- rails-html-sanitizer (1.6.2)
168
- loofah (~> 2.21)
176
+ rails-html-sanitizer (1.7.0)
177
+ loofah (~> 2.25)
169
178
  nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
170
- railties (8.0.2)
171
- actionpack (= 8.0.2)
172
- activesupport (= 8.0.2)
179
+ railties (8.1.3)
180
+ actionpack (= 8.1.3)
181
+ activesupport (= 8.1.3)
173
182
  irb (~> 1.13)
174
183
  rackup (>= 1.0.0)
175
184
  rake (>= 12.2)
176
185
  thor (~> 1.0, >= 1.2.2)
186
+ tsort (>= 0.2)
177
187
  zeitwerk (~> 2.6)
178
- rake (13.2.1)
179
- rdoc (6.13.1)
188
+ rake (13.4.2)
189
+ rdoc (7.2.0)
190
+ erb
180
191
  psych (>= 4.0.0)
181
- reline (0.6.0)
192
+ tsort
193
+ reline (0.6.3)
182
194
  io-console (~> 0.5)
183
- rspec (3.13.0)
195
+ rspec (3.13.2)
184
196
  rspec-core (~> 3.13.0)
185
197
  rspec-expectations (~> 3.13.0)
186
198
  rspec-mocks (~> 3.13.0)
187
- rspec-core (3.13.3)
199
+ rspec-core (3.13.6)
188
200
  rspec-support (~> 3.13.0)
189
- rspec-expectations (3.13.3)
201
+ rspec-expectations (3.13.5)
190
202
  diff-lcs (>= 1.2.0, < 2.0)
191
203
  rspec-support (~> 3.13.0)
192
- rspec-mocks (3.13.2)
204
+ rspec-mocks (3.13.8)
193
205
  diff-lcs (>= 1.2.0, < 2.0)
194
206
  rspec-support (~> 3.13.0)
195
- rspec-support (3.13.2)
207
+ rspec-support (3.13.7)
196
208
  securerandom (0.4.1)
197
209
  simplecov (0.22.0)
198
210
  docile (~> 1.1)
199
211
  simplecov-html (~> 0.11)
200
212
  simplecov_json_formatter (~> 0.1)
201
- simplecov-html (0.13.1)
213
+ simplecov-html (0.13.2)
202
214
  simplecov_json_formatter (0.1.4)
203
- stringio (3.1.6)
204
- thor (1.3.2)
205
- timeout (0.4.3)
215
+ stringio (3.2.0)
216
+ thor (1.5.0)
217
+ timeout (0.6.1)
218
+ tsort (0.2.0)
206
219
  tzinfo (2.0.6)
207
220
  concurrent-ruby (~> 1.0)
208
- uri (1.0.3)
221
+ uri (1.1.1)
209
222
  useragent (0.16.11)
210
- websocket-driver (0.7.7)
223
+ websocket-driver (0.8.0)
211
224
  base64
212
225
  websocket-extensions (>= 0.1.0)
213
226
  websocket-extensions (0.1.5)
214
- zeitwerk (2.7.2)
227
+ zeitwerk (2.7.5)
215
228
 
216
229
  PLATFORMS
217
230
  ruby
@@ -226,4 +239,4 @@ DEPENDENCIES
226
239
  simplecov (~> 0.22)
227
240
 
228
241
  BUNDLED WITH
229
- 2.6.2
242
+ 4.0.10
data/README.md CHANGED
@@ -462,7 +462,7 @@ The payload items shown above are both mandatory:
462
462
 
463
463
  If either item is missing or blank, or if for any reason Hub finds itself unable to associated the action with a user record on Hub's side, then no e-mail message will be sent.
464
464
 
465
- **IMPORTANT:** The Hub application's database migration at the time you updated to 3.7.0 will have set existing users to trusted for historic data, but new users are untrusted. If you introduce trust integration to your site's other apps after this, you might want to enter the console to update any new users added since likewise; inside `app/hub`, issue:
465
+ **OPTIONAL DATA MIGRATION:** The Hub application's database migration at the time you updated to 3.7.0 will have set existing users to trusted for historic data, but new users are untrusted. If you introduce trust integration to your site's other apps after this, you might want to enter the console to update any new users added since likewise; inside `app/hub`, issue:
466
466
 
467
467
  ```
468
468
  $ bundle exec rails c
@@ -471,3 +471,17 @@ $ bundle exec rails c
471
471
  ```
472
472
 
473
473
  The trust mechanism involves a fair amount of effort on the integrating app's side but it can be very useful if you have a site where, despite your best efforts, sometimes spam/bot accounts manage to get inside and try to flood the system with spam. It's just one of many different potential protection and mitigation mechanisms that your site might choose to employ.
474
+
475
+ **SERVER NOTE:** The Trust DRb server runs inside the Hub application, which runs using Puma as a server by default. The Trust server is started within the Hub application's `puma.rb` configuration file, because it needs to make sure it runs once, after booting, and is not destroyed by worker fork teardown/standup. If you aren't going to use Puma, you'll need to find a way to set this up; you'll want code akin to this in `app/hub/config/application.rb`:
476
+
477
+ ```ruby
478
+ if defined? Rails::Server
479
+ Rails::Application::Finisher.initializer 'uk.org.pond.hubssolib.trustserver' do
480
+ Thread.new do
481
+ HubSsoLib::Trust.launch_server()
482
+ end
483
+ end
484
+ end
485
+ ```
486
+
487
+ ...but that only works if the code would be run once and never torn down (a one-process server setup). There are many different Ruby web server approaches and it's not possible to be more specific; you just need to read the documentation about lifecycles and callbacks for the server you choose.
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.8.0'
7
+ s.version = '3.8.2'
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
@@ -366,17 +366,16 @@ module HubSsoLib
366
366
  # 26-Feb-2025 (ADH): Add 'trusted' concept. #
367
367
  #######################################################################
368
368
 
369
+ # This *must not* be 'undumped', since it gets passed from clients back to
370
+ # the persistent DRb server process. A client thread may disappear and be
371
+ # recreated by the web server at any time; if the user object is undumpable,
372
+ # then the DRb server has to *call back to the client* (in DRb, clients are
373
+ # also servers...!) to find out about the object. Trouble is, if the client
374
+ # thread has been recreated, the server will be trying to access to stale
375
+ # objects that only exist if the garbage collector hasn't got to them yet.
376
+ #
369
377
  class User
370
378
 
371
- # This *must not* be 'undumped', since it gets passed from clients
372
- # back to the persistent DRb server process. A client thread may
373
- # disappear and be recreated by the web server at any time; if the
374
- # user object is undumpable, then the DRb server has to *call back
375
- # to the client* (in DRb, clients are also servers...!) to find out
376
- # about the object. Trouble is, if the client thread has been
377
- # recreated, the server will be trying to access to stale objects
378
- # that only exist if the garbage collector hasn't got to them yet.
379
-
380
379
  attr_accessor :user_salt
381
380
  attr_accessor :user_roles
382
381
  attr_accessor :user_updated_at
@@ -397,8 +396,8 @@ module HubSsoLib
397
396
  end # User class
398
397
 
399
398
  #######################################################################
400
- # Class: Session #
401
- # (C) Hipposoft 2006 #
399
+ # Class: Session family #
400
+ # (C) Hipposoft 2006-2025 #
402
401
  # #
403
402
  # Purpose: Session support object, used to store session metadata in #
404
403
  # an insecure cross-application cookie. #
@@ -406,37 +405,67 @@ module HubSsoLib
406
405
  # Author: A.D.Hodgkinson #
407
406
  # #
408
407
  # History: 22-Oct-2006 (ADH): Created. #
408
+ # 09-Apr-2025 (ADH): Dumpable/undumpable variants created. #
409
409
  #######################################################################
410
410
 
411
- class Session
412
-
413
- # Unlike a User, this *is* undumpable since it only gets passed from
414
- # server to client. The server's always here to service requests
415
- # from the client and used sessions are never garbage collected
416
- # since the DRb server's front object, a SessionFactory, keeps them
417
- # in a hash held within an instance variable.
418
-
419
- include DRb::DRbUndumped
420
-
421
- attr_accessor :session_last_used
422
- attr_reader :session_return_to # DEPRECATED
423
- attr_accessor :session_flash
424
- attr_accessor :session_user
425
- attr_accessor :session_rotated_key
426
-
427
- def initialize
428
- @session_last_used = Time.now.utc
429
- @session_return_to = nil
430
- @session_flash = {}
431
- @session_user = HubSsoLib::User.new
432
- @session_rotated_key = nil
411
+ # A dumpable base class that can be used for undumpable proxies, where a
412
+ # change made in an object passed to a client is reflected on the server
413
+ # where the object actually lives; or for dumpable clones of sessions sent
414
+ # as read-only copies to clients which won't disppear due to server side
415
+ # deletion from key rotation, expiry or admin-driven deletion.
416
+ #
417
+ class SessionBase
418
+
419
+ ATTRIBUTES = %i{
420
+ session_last_used
421
+ session_flash
422
+ session_user
423
+ session_rotated_key
424
+ }
425
+
426
+ ATTRIBUTES.each { | attr | attr_accessor(attr) }
427
+ attr_reader :session_return_to # DEPRECATED
428
+
429
+ def initialize(copying_session: nil)
430
+ if copying_session.nil?
431
+ self.session_last_used = Time.now.utc
432
+ self.session_flash = {}
433
+ self.session_user = HubSsoLib::User.new
434
+ self.session_rotated_key = nil
435
+ else
436
+ ATTRIBUTES.each do | attr |
437
+ self.send("#{attr}=", copying_session.send(attr))
438
+ end
439
+ end
433
440
 
434
441
  rescue => e
435
442
  Sentry.capture_exception(e) if defined?(Sentry) && Sentry.respond_to?(:capture_exception)
436
443
  raise
437
444
  end
445
+
446
+ end # SessionBase class
447
+
448
+ # Unlike a User, this *is* undumpable since it only gets passed from server
449
+ # to client. The server's always here to service requests from the client and
450
+ # used sessions are never garbage collected since the DRb server's front
451
+ # object, a SessionFactory, keeps them in a hash held within an instance
452
+ # variable.
453
+ #
454
+ # A recognised weakness here is that a session might disappear from under the
455
+ # feet of an accessing application, due to key rotation or explicit deletion.
456
+ #
457
+ class Session < SessionBase
458
+ include DRb::DRbUndumped
438
459
  end # Session class
439
460
 
461
+ # No special conditions - this is just a dumpable session. You should usually
462
+ # create it based on an undumpable, 'live' session thus:
463
+ #
464
+ # SessionCopy.new(copying_session: undumpable_session)
465
+ #
466
+ class SessionCopy < SessionBase
467
+ end # SessionCopy class
468
+
440
469
  #######################################################################
441
470
  # Class: SessionFactory #
442
471
  # (C) Hipposoft 2006 #
@@ -611,6 +640,16 @@ module HubSsoLib
611
640
  # given session key. No key rotation occurs. Returns +nil+ if no entry is
612
641
  # found for that key.
613
642
  #
643
+ # This returns a *LIVE OBJECT* owned by the DRb server. Writes made to this
644
+ # object will affect the live session state. However, the session might be
645
+ # invalidated at any time by actions such as key rotation, expiration or
646
+ # explicit user deletion. Attempts to read or write properties would then
647
+ # lead to exceptions such as:
648
+ #
649
+ # "424" is not id value (RangeError)
650
+ #
651
+ # ...where 424 is the internal object ID of meaning only to the DRb system.
652
+ #
614
653
  def retrieve_session_by_key(key)
615
654
  HUB_MUTEX.synchronize { @hub_sessions[key] }
616
655
  end
@@ -622,15 +661,24 @@ module HubSsoLib
622
661
  # values yielding HubSsoLib::Session instances as values is returned.
623
662
  #
624
663
  # The array is ordered by least-recently-active first to most-recent last.
664
+ # Returned data is a copy of internal session information and should be
665
+ # considered read-only; changes made will have no effect outside your own
666
+ # application.
625
667
  #
626
668
  # IN THE CURRENT IMPLEMENTATION THIS JUST SEQUENTIALLY SCANS ALL ACTIVE
627
669
  # SESSIONS IN THE HASH and must therefore lock on mutex for the duration.
628
670
  #
629
671
  def retrieve_sessions_by_user_id(user_id)
630
672
  HUB_MUTEX.synchronize do
631
- @hub_sessions.select do | key, session |
632
- session&.session_user&.user_id == user_id
673
+ collection = {}
674
+
675
+ @hub_sessions.each do | key, session |
676
+ if session&.session_user&.user_id == user_id
677
+ collection[key] = SessionCopy.new(copying_session: session)
678
+ end
633
679
  end
680
+
681
+ collection
634
682
  end
635
683
  end
636
684
 
@@ -647,6 +695,8 @@ module HubSsoLib
647
695
  @hub_sessions.delete(key)
648
696
  end
649
697
 
698
+ return nil
699
+
650
700
  rescue => e
651
701
  Sentry.capture_exception(e) if defined?(Sentry) && Sentry.respond_to?(:capture_exception)
652
702
  raise
@@ -672,6 +722,8 @@ module HubSsoLib
672
722
  end
673
723
  end
674
724
 
725
+ return nil
726
+
675
727
  rescue => e
676
728
  Sentry.capture_exception(e) if defined?(Sentry) && Sentry.respond_to?(:capture_exception)
677
729
  raise
@@ -696,6 +748,8 @@ module HubSsoLib
696
748
  end
697
749
  end
698
750
 
751
+ return nil
752
+
699
753
  rescue => e
700
754
  Sentry.capture_exception(e) if defined?(Sentry) && Sentry.respond_to?(:capture_exception)
701
755
  raise
@@ -738,6 +792,8 @@ module HubSsoLib
738
792
  puts "Session factory: ...Destroyed #{destroyed} session(s)"
739
793
  end
740
794
 
795
+ return nil
796
+
741
797
  rescue => e
742
798
  Sentry.capture_exception(e) if defined?(Sentry) && Sentry.respond_to?(:capture_exception)
743
799
  raise
@@ -862,13 +918,21 @@ module HubSsoLib
862
918
  HUB_TRUST_CONNECTION_URI
863
919
  end
864
920
 
921
+ # Is the server already running?
922
+ #
923
+ def self.already_running?
924
+ uri = self.get_trust_server_connection_uri()
925
+ path = URI.parse(uri).path
926
+
927
+ return File.exist?(path)
928
+ end
929
+
865
930
  # Start the trust server. This should only ever be called by the Hub Rails
866
931
  # application, which implements HubSsoLib::Trust::Server.
867
932
  #
868
933
  def self.launch_server
869
934
  uri = self.get_trust_server_connection_uri()
870
- path = URI.parse(uri).path
871
- already_running = File.exist?(path)
935
+ already_running = self.already_running?
872
936
 
873
937
  unless ENV['HUB_QUIET_SERVER'] == 'yes'
874
938
  message = unless already_running
@@ -1251,8 +1315,8 @@ module HubSsoLib
1251
1315
 
1252
1316
  unless hub_session_info[:keys].nil? # (keyset too large, enumeration prohibited)
1253
1317
  hub_session_info[:keys].each do | key |
1254
- session = hubssolib_factory().retrieve_session_by_key(key)
1255
- hub_users << session.session_user unless session&.session_user&.user_id.nil?
1318
+ session_user = hubssolib_factory().retrieve_session_by_key(key)&.session_user
1319
+ hub_users << session_user unless session_user&.user_id.nil?
1256
1320
  end
1257
1321
  end
1258
1322
 
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.8.0
4
+ version: 3.8.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Hodgkinson and others
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-04-04 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: drb
@@ -158,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
158
158
  - !ruby/object:Gem::Version
159
159
  version: '0'
160
160
  requirements: []
161
- rubygems_version: 3.6.2
161
+ rubygems_version: 4.0.10
162
162
  specification_version: 4
163
163
  summary: Cross-application single sign-on support library.
164
164
  test_files: []