hubssolib 3.7.0 → 3.8.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 +4 -4
- data/CHANGELOG.md +9 -2
- data/Gemfile.lock +163 -3
- data/README.md +95 -0
- data/hubssolib.gemspec +2 -1
- data/lib/hub_sso_lib.rb +225 -87
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 32438e5c41d655367f4bb0e8385b9d972645f2649871a09ab7b09dc5d617fe9e
|
4
|
+
data.tar.gz: a999f01f88325690644675acc1b06b33b7b275374e980c6c3f2fa346c3875d93
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 881e57fa9c2e42ed8465b2faabf98cabdacf2dcea5df20d3c617836e50ff74d2255bbe1b8c11ca39b0bb3d57f2927e229ca1a390de11d0fcff9b8e4b32851ae6
|
7
|
+
data.tar.gz: 15aa2e97054fe9a8a86e45d901bdfa36bff0d0a6473ba88d279ec0bf622ce8413e6bc1a7b0427bac1f0e2bc0c2b994d9a3550d48897a8efec7cf2acf0c74abfa
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,14 @@
|
|
1
|
-
## 3.
|
1
|
+
## 3.8.0, 03-Apr-2025
|
2
|
+
|
3
|
+
* 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.
|
4
|
+
* Deprecates core methods `hubssolib_store_location` (which is now a no-op) and `hubssolib_redirect_back_or_default` (which now always redirects to the default location). **These methods will be removed in Hub 4**. Ephemeral return-to location storage has only worked when sessions are _on_, which once upon a time was always - logged in or not - but changed in Hub 3.4.0, to avoid very large numbers of anonymous sessions building up into a very RAM-hungry pools in the DRb server. This has in hindsight amounted to a breaking change, and I should've bumped to Hub 4 per SemVer at that time, but it was overlooked; apologies. At least in general all it really usually means is that, instead of redirecting back to some calling application after login, the user is left in their Hub account view.
|
5
|
+
* Hub's UI element added to navigation bars by using `HubSsoLib::Core#hubssolib_account_link` plus permissions and must-log-in checking in the `HubSsoLib::Core#hubssolib_beforehand` before-action callback already dealt with and continue to deal with redirect-to-origin automatically, so often, applications did't need to store a location and then manually redirect to Hub anyway. If you do need this for some reason, though, the new workflow is create a link or redirection to the URL returned by `HubSsoLib::Core#hubssolib_returnable_account_url`. This simply encodes a return-to address in the URL where needed, removing any requirement for cross-application session storage. The method's documentation describes its uses but, for the majority of use cases, you'll probably only want to be presenting a link for the case where a user must log _in_. In that case, call `hubssolib_returnable_account_url(logged_in: false)`.
|
6
|
+
|
7
|
+
## 3.7.0 and 3.7.1, 28-Mar-2025
|
2
8
|
|
3
9
|
* Login indicator cookie wasn't updated on session timeout, so when the page loaded for pages that do *not* require authorisation, the warning flash about being timed out would show, but the indicator would still show a "logged in" state until the next page fetch.
|
4
10
|
* User trust mechanism introduced, including HubSsoLib::Core#hubssolib_trusted? convenience accessor for Hub-integrated applications to check on user trust and `HubSsoLib::Core#hubssolib_review_action` convenience alias for `HubSsoLib::Trust.get_trust_object().review_action`.
|
11
|
+
* 3.7.1, released only a few minutes after 3.7.0, added the aforementioned `#hubssolib_retrieve_action` method, previously overlooked.
|
5
12
|
|
6
13
|
## 3.6.1, 27-Mar-2025
|
7
14
|
|
@@ -84,7 +91,7 @@ In Hub v1 and v2, login indication was done via an image that was served by the
|
|
84
91
|
|
85
92
|
```html
|
86
93
|
<a class="img" href="<%= ENV['HUB_PATH_PREFIX'] %>/account/login_conditional">
|
87
|
-
<img src="<%= ENV['HUB_PATH_PREFIX'] %>/account/login_indication" alt="Account" height="22" width="90"
|
94
|
+
<img src="<%= ENV['HUB_PATH_PREFIX'] %>/account/login_indication" alt="Account" height="22" width="90">
|
88
95
|
</a>
|
89
96
|
```
|
90
97
|
|
data/Gemfile.lock
CHANGED
@@ -1,14 +1,91 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
hubssolib (3.
|
4
|
+
hubssolib (3.8.0)
|
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)
|
14
|
+
nio4r (~> 2.0)
|
15
|
+
websocket-driver (>= 0.6.1)
|
16
|
+
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)
|
23
|
+
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)
|
29
|
+
mail (>= 2.8.0)
|
30
|
+
rails-dom-testing (~> 2.2)
|
31
|
+
actionpack (8.0.2)
|
32
|
+
actionview (= 8.0.2)
|
33
|
+
activesupport (= 8.0.2)
|
34
|
+
nokogiri (>= 1.8.5)
|
35
|
+
rack (>= 2.2.4)
|
36
|
+
rack-session (>= 1.0.1)
|
37
|
+
rack-test (>= 0.6.3)
|
38
|
+
rails-dom-testing (~> 2.2)
|
39
|
+
rails-html-sanitizer (~> 1.6)
|
40
|
+
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)
|
46
|
+
globalid (>= 0.6.0)
|
47
|
+
nokogiri (>= 1.8.5)
|
48
|
+
actionview (8.0.2)
|
49
|
+
activesupport (= 8.0.2)
|
50
|
+
builder (~> 3.1)
|
51
|
+
erubi (~> 1.11)
|
52
|
+
rails-dom-testing (~> 2.2)
|
53
|
+
rails-html-sanitizer (~> 1.6)
|
54
|
+
activejob (8.0.2)
|
55
|
+
activesupport (= 8.0.2)
|
56
|
+
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)
|
62
|
+
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)
|
68
|
+
marcel (~> 1.0)
|
69
|
+
activesupport (8.0.2)
|
70
|
+
base64
|
71
|
+
benchmark (>= 0.3)
|
72
|
+
bigdecimal
|
73
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
74
|
+
connection_pool (>= 2.2.5)
|
75
|
+
drb
|
76
|
+
i18n (>= 1.6, < 2)
|
77
|
+
logger (>= 1.4.2)
|
78
|
+
minitest (>= 5.1)
|
79
|
+
securerandom (>= 0.3)
|
80
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
81
|
+
uri (>= 0.13.1)
|
11
82
|
base64 (0.2.0)
|
83
|
+
benchmark (0.4.0)
|
84
|
+
bigdecimal (3.1.9)
|
85
|
+
builder (3.3.0)
|
86
|
+
concurrent-ruby (1.3.5)
|
87
|
+
connection_pool (2.5.0)
|
88
|
+
crass (1.0.6)
|
12
89
|
date (3.4.1)
|
13
90
|
debug (1.10.0)
|
14
91
|
irb (~> 1.10)
|
@@ -18,18 +95,88 @@ GEM
|
|
18
95
|
doggo (1.4.0)
|
19
96
|
rspec-core (~> 3.13)
|
20
97
|
drb (2.2.1)
|
98
|
+
erubi (1.13.1)
|
99
|
+
globalid (1.2.1)
|
100
|
+
activesupport (>= 6.1)
|
101
|
+
i18n (1.14.7)
|
102
|
+
concurrent-ruby (~> 1.0)
|
21
103
|
io-console (0.8.0)
|
22
|
-
irb (1.15.
|
104
|
+
irb (1.15.2)
|
23
105
|
pp (>= 0.6.0)
|
24
106
|
rdoc (>= 4.0.0)
|
25
107
|
reline (>= 0.4.2)
|
108
|
+
logger (1.7.0)
|
109
|
+
loofah (2.24.0)
|
110
|
+
crass (~> 1.0.2)
|
111
|
+
nokogiri (>= 1.12.0)
|
112
|
+
mail (2.8.1)
|
113
|
+
mini_mime (>= 0.1.1)
|
114
|
+
net-imap
|
115
|
+
net-pop
|
116
|
+
net-smtp
|
117
|
+
marcel (1.0.4)
|
118
|
+
mini_mime (1.1.5)
|
119
|
+
mini_portile2 (2.8.8)
|
120
|
+
minitest (5.25.5)
|
121
|
+
net-imap (0.5.6)
|
122
|
+
date
|
123
|
+
net-protocol
|
124
|
+
net-pop (0.1.2)
|
125
|
+
net-protocol
|
126
|
+
net-protocol (0.2.2)
|
127
|
+
timeout
|
128
|
+
net-smtp (0.5.1)
|
129
|
+
net-protocol
|
130
|
+
nio4r (2.7.4)
|
131
|
+
nokogiri (1.18.7)
|
132
|
+
mini_portile2 (~> 2.8.2)
|
133
|
+
racc (~> 1.4)
|
26
134
|
pp (0.6.2)
|
27
135
|
prettyprint
|
28
136
|
prettyprint (0.2.0)
|
29
137
|
psych (5.2.3)
|
30
138
|
date
|
31
139
|
stringio
|
32
|
-
|
140
|
+
racc (1.8.1)
|
141
|
+
rack (3.1.12)
|
142
|
+
rack-session (2.1.0)
|
143
|
+
base64 (>= 0.1.0)
|
144
|
+
rack (>= 3.0.0)
|
145
|
+
rack-test (2.2.0)
|
146
|
+
rack (>= 1.3)
|
147
|
+
rackup (2.2.1)
|
148
|
+
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)
|
161
|
+
bundler (>= 1.15.0)
|
162
|
+
railties (= 8.0.2)
|
163
|
+
rails-dom-testing (2.2.0)
|
164
|
+
activesupport (>= 5.0.0)
|
165
|
+
minitest
|
166
|
+
nokogiri (>= 1.6)
|
167
|
+
rails-html-sanitizer (1.6.2)
|
168
|
+
loofah (~> 2.21)
|
169
|
+
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)
|
173
|
+
irb (~> 1.13)
|
174
|
+
rackup (>= 1.0.0)
|
175
|
+
rake (>= 12.2)
|
176
|
+
thor (~> 1.0, >= 1.2.2)
|
177
|
+
zeitwerk (~> 2.6)
|
178
|
+
rake (13.2.1)
|
179
|
+
rdoc (6.13.1)
|
33
180
|
psych (>= 4.0.0)
|
34
181
|
reline (0.6.0)
|
35
182
|
io-console (~> 0.5)
|
@@ -46,6 +193,7 @@ GEM
|
|
46
193
|
diff-lcs (>= 1.2.0, < 2.0)
|
47
194
|
rspec-support (~> 3.13.0)
|
48
195
|
rspec-support (3.13.2)
|
196
|
+
securerandom (0.4.1)
|
49
197
|
simplecov (0.22.0)
|
50
198
|
docile (~> 1.1)
|
51
199
|
simplecov-html (~> 0.11)
|
@@ -53,6 +201,17 @@ GEM
|
|
53
201
|
simplecov-html (0.13.1)
|
54
202
|
simplecov_json_formatter (0.1.4)
|
55
203
|
stringio (3.1.6)
|
204
|
+
thor (1.3.2)
|
205
|
+
timeout (0.4.3)
|
206
|
+
tzinfo (2.0.6)
|
207
|
+
concurrent-ruby (~> 1.0)
|
208
|
+
uri (1.0.3)
|
209
|
+
useragent (0.16.11)
|
210
|
+
websocket-driver (0.7.7)
|
211
|
+
base64
|
212
|
+
websocket-extensions (>= 0.1.0)
|
213
|
+
websocket-extensions (0.1.5)
|
214
|
+
zeitwerk (2.7.2)
|
56
215
|
|
57
216
|
PLATFORMS
|
58
217
|
ruby
|
@@ -61,6 +220,7 @@ DEPENDENCIES
|
|
61
220
|
debug (~> 1.1)
|
62
221
|
doggo (~> 1.4)
|
63
222
|
hubssolib!
|
223
|
+
rails (~> 8.0)
|
64
224
|
rspec (~> 3.13)
|
65
225
|
rspec-mocks (~> 3.13)
|
66
226
|
simplecov (~> 0.22)
|
data/README.md
CHANGED
@@ -376,3 +376,98 @@ In the example of "permissions for arbitrary user" you may well not have ready a
|
|
376
376
|
When a user logs in with a traditional log-in system, there's usually some message shown on the page presented when log-in is successful. This is achieved through the Hub equivalent of the Rails `flash` hash. Replace your preferred mechanism for including contents of the `flash` hash into your views (usually via one or more layout files) with an equivalent which calls Hub's flash handling code, which aggregates both current application and cross-application flash content into one.
|
377
377
|
|
378
378
|
Just using `<%= hubssolib_flash_tags -%>` in your layout(s) and/or view(s) will output merged flash data. HTML is generated consisting of `h2` tags with class names derived from the keys used in the flash tag. Each heading tag encapsulates the value for the key and is followed by an empty paragraph tag for spacing reasons on older browsers when more than one key is present, though normally there is only one. Hub itself commonly uses keys `:notice` ("green" / general information - e.g. "you are now logged in"), `:attention` ("orange" / something unusual happened - e.g. "your session timed out so you were logged out") and `:alert` ("red" / something bad happened - e.g. "incorrect password given").
|
379
|
+
|
380
|
+
|
381
|
+
|
382
|
+
## Trust mechanism
|
383
|
+
|
384
|
+
Hub 3.7.0 and later introduce a trust mechanism. Users have a "trusted" flag that's off by default for any new user. Participating applications can check the current user trust with `hubssolib_trusted?`. For actions where you care about trust - which are typically for creations (e.g. post to a forum, comment on an article) then:
|
385
|
+
|
386
|
+
* The relevant controller action proceeds as normal to the point of being ready to save new or updated record(s)
|
387
|
+
* If the user is untrusted and the to-be-saved record(s) is/are valid, and so should save OK...
|
388
|
+
- ...instead assemble information about the action and send it to Hub
|
389
|
+
- ...and *do not* save anything but instead exit with an appropriate flash message (e.g. "Thanks, that's gone into our moderation queue and should show up soon - please check back later!").
|
390
|
+
|
391
|
+
You send an action to Hub with an alias method `hubssolib_review_action` which has this effective signature:
|
392
|
+
|
393
|
+
```ruby
|
394
|
+
def hubssolib_review_action(
|
395
|
+
user_email:,
|
396
|
+
action_scheme:,
|
397
|
+
action_url:,
|
398
|
+
action_payload:,
|
399
|
+
action_as_html:,
|
400
|
+
callback_url:
|
401
|
+
)
|
402
|
+
```
|
403
|
+
|
404
|
+
...where you pass:
|
405
|
+
|
406
|
+
* The user's email address _as known to Hub_, which is used to look up the user on the Hub side
|
407
|
+
* The HTTP method that was being used as a string, case insensitive, e.g. `POST`, for display to admins only
|
408
|
+
* The URL in full upon which this current request was made, for display to admins only
|
409
|
+
* The payload - usually just `params`, as-is - you'll get send this back again later, so include everything you need to reprocess the action
|
410
|
+
* Your choice of **safe** HTML that the Hub application will show as a preview (this may undergo some allow-list sanitisation; Hub does not expect a malicious integrated application to send it bad HTML which attempts skullduggery, but it shouldn't compromise its view layer just because something unsafe got sent accidentally, either!)
|
411
|
+
* **A callback URL** described below
|
412
|
+
|
413
|
+
If an admin thinks that the submission is bad - e.g. spam - then you won't hear about it again. Otherwise, the admin thinks the delayed action should now be taken for real. To accomplish this, Hub will `POST` back (and always uses `POST`) to your `callback_url` **in JSON** with an object that just has a key, `id`.
|
414
|
+
|
415
|
+
You create a controller action for your endpoint which retrieves the action details using code similar to this:
|
416
|
+
|
417
|
+
```ruby
|
418
|
+
# The request format might be JSON because ".json" ended the path of the
|
419
|
+
# URI used to call here, but a missing or incorrect Content-Type header
|
420
|
+
# may mean that Rack/Rails doesn't process the body into "params" as
|
421
|
+
# expected. The latter would result in a nonsense database lookup which
|
422
|
+
# is harmless but wasteful, so don't do it.
|
423
|
+
#
|
424
|
+
if request.format.json? && request.headers['Content-Type']&.downcase == 'application/json'
|
425
|
+
@details = hubssolib_retrieve_action(id: params[:id])
|
426
|
+
head :unprocessable_entity if @details.nil?
|
427
|
+
else
|
428
|
+
head :unsupported_media_type
|
429
|
+
end
|
430
|
+
```
|
431
|
+
|
432
|
+
...then uses the object to work out what to do next. The retrieved object is a Hash, with **Symbol keys at the top level** but **String keys in `action_payload`**:
|
433
|
+
|
434
|
+
```
|
435
|
+
{
|
436
|
+
timestamp: untrusted_action.created_at,
|
437
|
+
user_email: untrusted_action.user_email,
|
438
|
+
user_unique_name: user_unique_name,
|
439
|
+
action_scheme: untrusted_action.action_scheme,
|
440
|
+
action_url: untrusted_action.action_url,
|
441
|
+
action_payload: untrusted_action.action_payload
|
442
|
+
}
|
443
|
+
```
|
444
|
+
|
445
|
+
...so that's:
|
446
|
+
|
447
|
+
* The created-at time when you sent the action for review. This is usually only needed if you're dealing with a delayed edit/update action, where you might need to make sure that nobody else had edited the same entity in the mean time.
|
448
|
+
* The previously submitted user e-mail is given so you know _who_ it was that is now being trusted, along with the associated Hub "unique display name" (e.g. `Jane Doe (14510)`).
|
449
|
+
* Your previously submitted action scheme and URL are also given in case you need them because you've decided to implement one callback handler for different kinds of untrusted action.
|
450
|
+
* The `action_payload` is where all your important data, meaningful only to you, resides and this must contain everything else, other than the above parameters, required to complete the action previously sent for review, _while making sure things are attributed to the correct user_.
|
451
|
+
|
452
|
+
Use `head ...` to indicate non-200 responses. If you don't want the originating user to get notified of a successful run, then on-success, also reply with `head :ok` or `head 200` (according to style preference). If you want to ask Hub to notify the user, then on-success instead do this:
|
453
|
+
|
454
|
+
```ruby
|
455
|
+
render json: { mail_item_url: ..., mail_subject: ... }, status: :ok
|
456
|
+
```
|
457
|
+
|
458
|
+
The payload items shown above are both mandatory:
|
459
|
+
|
460
|
+
* `mail_item_url` is the full URL of the entity that you just successfully edited, updated, or some other sensible URL to take the user (this will be included verbatim in the e-mail)
|
461
|
+
* `mail_subject` is a subject line of your choosing - for example, `"Your new forum post is now visible"`. Hub might add a prefix such as `[ORGNAME] ...`
|
462
|
+
|
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
|
+
|
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:
|
466
|
+
|
467
|
+
```
|
468
|
+
$ bundle exec rails c
|
469
|
+
> User.update_all(trusted: true)
|
470
|
+
> exit
|
471
|
+
```
|
472
|
+
|
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.
|
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.
|
7
|
+
s.version = '3.8.0'
|
8
8
|
s.author = 'Andrew Hodgkinson and others'
|
9
9
|
s.email = 'ahodgkin@rowing.org.uk'
|
10
10
|
s.homepage = 'http://pond.org.uk/'
|
@@ -28,6 +28,7 @@ spec = Gem::Specification.new do |s|
|
|
28
28
|
s.add_dependency 'base64', '~> 0.2'
|
29
29
|
|
30
30
|
s.add_development_dependency 'debug', '~> 1.1'
|
31
|
+
s.add_development_dependency 'rails', '~> 8.0'
|
31
32
|
s.add_development_dependency 'simplecov', '~> 0.22'
|
32
33
|
s.add_development_dependency 'doggo', '~> 1.4'
|
33
34
|
s.add_development_dependency 'rspec', '~> 3.13'
|
data/lib/hub_sso_lib.rb
CHANGED
@@ -69,7 +69,7 @@ module HubSsoLib
|
|
69
69
|
|
70
70
|
# Location of Hub application root.
|
71
71
|
#
|
72
|
-
HUB_PATH_PREFIX = ENV['HUB_PATH_PREFIX'] || ''
|
72
|
+
HUB_PATH_PREFIX = (ENV['HUB_PATH_PREFIX'] || '').sub(/(\/)+$/, '')
|
73
73
|
|
74
74
|
# Time limit, *in seconds*, for the account inactivity timeout. If a user
|
75
75
|
# performs no Hub actions during this time they will be automatically logged
|
@@ -394,24 +394,6 @@ module HubSsoLib
|
|
394
394
|
attr_accessor :user_password_reset_code_expires_at
|
395
395
|
attr_accessor :user_trusted
|
396
396
|
|
397
|
-
def initialize
|
398
|
-
@user_salt = nil
|
399
|
-
@user_roles = nil
|
400
|
-
@user_updated_at = nil
|
401
|
-
@user_activated_at = nil
|
402
|
-
@user_real_name = nil
|
403
|
-
@user_crypted_password = nil
|
404
|
-
@user_remember_token_expires_at = nil
|
405
|
-
@user_activation_code = nil
|
406
|
-
@user_member_id = nil
|
407
|
-
@user_id = nil
|
408
|
-
@user_password_reset_code = nil
|
409
|
-
@user_remember_token = nil
|
410
|
-
@user_email = nil
|
411
|
-
@user_created_at = nil
|
412
|
-
@user_password_reset_code_expires_at = nil
|
413
|
-
@user_trusted = nil
|
414
|
-
end
|
415
397
|
end # User class
|
416
398
|
|
417
399
|
#######################################################################
|
@@ -437,7 +419,7 @@ module HubSsoLib
|
|
437
419
|
include DRb::DRbUndumped
|
438
420
|
|
439
421
|
attr_accessor :session_last_used
|
440
|
-
|
422
|
+
attr_reader :session_return_to # DEPRECATED
|
441
423
|
attr_accessor :session_flash
|
442
424
|
attr_accessor :session_user
|
443
425
|
attr_accessor :session_rotated_key
|
@@ -613,7 +595,9 @@ module HubSsoLib
|
|
613
595
|
keys = if count > HUB_SESSION_ENUMERATION_KEY_MAX
|
614
596
|
nil
|
615
597
|
else
|
616
|
-
|
598
|
+
HUB_MUTEX.synchronize do
|
599
|
+
@hub_sessions.keys # (Hash#keys returns a new array)
|
600
|
+
end
|
617
601
|
end
|
618
602
|
|
619
603
|
return { count: count, keys: keys }
|
@@ -628,7 +612,7 @@ module HubSsoLib
|
|
628
612
|
# found for that key.
|
629
613
|
#
|
630
614
|
def retrieve_session_by_key(key)
|
631
|
-
@hub_sessions[key]
|
615
|
+
HUB_MUTEX.synchronize { @hub_sessions[key] }
|
632
616
|
end
|
633
617
|
|
634
618
|
# WARNING: Comparatively slow.
|
@@ -655,6 +639,10 @@ module HubSsoLib
|
|
655
639
|
# session data. Does nothing if the key is not found.
|
656
640
|
#
|
657
641
|
def destroy_session_by_key(key)
|
642
|
+
unless @hub_be_quiet
|
643
|
+
puts "Session factory: Deleting session with key #{key}"
|
644
|
+
end
|
645
|
+
|
658
646
|
HUB_MUTEX.synchronize do
|
659
647
|
@hub_sessions.delete(key)
|
660
648
|
end
|
@@ -674,6 +662,10 @@ module HubSsoLib
|
|
674
662
|
# SESSIONS IN THE HASH and must therefore lock on mutex for the duration.
|
675
663
|
#
|
676
664
|
def destroy_sessions_by_user_id(user_id)
|
665
|
+
unless @hub_be_quiet
|
666
|
+
puts "Session factory: Deleting all session records for user ID #{user_id.inspect}"
|
667
|
+
end
|
668
|
+
|
677
669
|
HUB_MUTEX.synchronize do
|
678
670
|
@hub_sessions.reject! do | key, session |
|
679
671
|
session&.session_user&.user_id == user_id
|
@@ -685,6 +677,30 @@ module HubSsoLib
|
|
685
677
|
raise
|
686
678
|
end
|
687
679
|
|
680
|
+
# WARNING: Comparatively slow.
|
681
|
+
#
|
682
|
+
# Call only if you MUST update details of a session user inside all Hub
|
683
|
+
# sessions. Pass the user ID and HubSsoLib::User details that are to be
|
684
|
+
# stored for all sessions owned by that user ID.
|
685
|
+
#
|
686
|
+
def update_sessions_by_user_id(user_id, user)
|
687
|
+
unless @hub_be_quiet
|
688
|
+
puts "Session factory: Updating all session records for user ID #{user_id.inspect}"
|
689
|
+
end
|
690
|
+
|
691
|
+
HUB_MUTEX.synchronize do
|
692
|
+
@hub_sessions.each do | key, session |
|
693
|
+
if session&.session_user&.user_id == user_id
|
694
|
+
session.session_user = user
|
695
|
+
end
|
696
|
+
end
|
697
|
+
end
|
698
|
+
|
699
|
+
rescue => e
|
700
|
+
Sentry.capture_exception(e) if defined?(Sentry) && Sentry.respond_to?(:capture_exception)
|
701
|
+
raise
|
702
|
+
end
|
703
|
+
|
688
704
|
# WARNING: Slow.
|
689
705
|
#
|
690
706
|
# This is a housekeeping task which checks sessions against Hub expiry and,
|
@@ -964,34 +980,97 @@ module HubSsoLib
|
|
964
980
|
end
|
965
981
|
end
|
966
982
|
|
967
|
-
#
|
968
|
-
#
|
969
|
-
#
|
970
|
-
#
|
983
|
+
# Return a URL that leads to a Hub "log in" page if the user is not logged
|
984
|
+
# in currently, else an "account" page for logged-in users.
|
985
|
+
#
|
986
|
+
# +universal+:: Use +true+ if concerned that a "Back" browser button action
|
987
|
+
# might cause a page to appear that's got a cached link which
|
988
|
+
# may no longer reflect the current state. This jumps to Hub
|
989
|
+
# and redirects to the "log in" or "account" destinations
|
990
|
+
# depending on current state. If using this, bear in mind
|
991
|
+
# that the link text must be ambiguous, because the eventual
|
992
|
+
# destination isn't known.
|
993
|
+
#
|
994
|
+
# It's often better to just use #hubssolib_account_link to
|
995
|
+
# create markup for this in a navigation area.
|
996
|
+
#
|
997
|
+
# The default is +false+, which means that a bespoke link
|
998
|
+
# for the exact current instantaneous log in state is
|
999
|
+
# generated; the +logged_in+ parameter applies (see below).
|
1000
|
+
#
|
1001
|
+
# +logged_in+:: If +universal+ is +false+, then this parameter defaults to
|
1002
|
+
# the current user logged-in state, but can be overridden
|
1003
|
+
# with +true+ (act as if someone is logged in) or +false+
|
1004
|
+
# (act as if someone is not logged in).
|
1005
|
+
#
|
1006
|
+
# +return_to+:: Overrides the use of <tt>request.original_url</tt> to give
|
1007
|
+
# an alternative return-after-logging-in URL. Will be of no
|
1008
|
+
# use for users already logged in. This is rarely used, but
|
1009
|
+
# might be helpful if you (say) want them to return to the
|
1010
|
+
# current page, but with a specific fragment added ("#foo").
|
1011
|
+
# Specify as a String, Symbol or URI, at your preference.
|
1012
|
+
#
|
1013
|
+
# Note that the universal links, or a not-logged-in state link will include
|
1014
|
+
# a query string which takes the value of <tt>request.original_url</tt> or,
|
1015
|
+
# if not defined, tries <tt>request.referrer</tt> (else is absent). This is
|
1016
|
+
# a URL used for the redirection after successful login. The logged-in
|
1017
|
+
# state link does not require this addition so omits it for brevity.
|
1018
|
+
#
|
1019
|
+
def hubssolib_returnable_account_url(
|
1020
|
+
universal: false,
|
1021
|
+
logged_in: self.hubssolib_logged_in?,
|
1022
|
+
return_to: nil
|
1023
|
+
)
|
1024
|
+
account_url = if universal
|
1025
|
+
"#{HUB_PATH_PREFIX}/account/login_conditional"
|
1026
|
+
else
|
1027
|
+
"#{HUB_PATH_PREFIX}/#{'account/login' unless logged_in}"
|
1028
|
+
end
|
1029
|
+
|
1030
|
+
# Attach a return-to URL always for the universal case which needs to
|
1031
|
+
# work regardless of login state; else we only need it when logged out,
|
1032
|
+
# so that we can return to the originating location after logging in.
|
1033
|
+
# There's no functional difference - just a simpler URL that omits what
|
1034
|
+
# would otherwise be an unused query string parameter.
|
1035
|
+
#
|
1036
|
+
if universal or not logged_in
|
1037
|
+
if return_to.nil?
|
1038
|
+
request_obj = self.try(:request)
|
1039
|
+
return_to = request_obj.try(:original_url) || request_obj.try(:referrer)
|
1040
|
+
end
|
1041
|
+
|
1042
|
+
if return_to.present?
|
1043
|
+
account_url << "?return_to_url=#{CGI.escape(return_to.to_s)}"
|
1044
|
+
end
|
1045
|
+
end
|
1046
|
+
|
1047
|
+
return account_url
|
1048
|
+
end
|
1049
|
+
|
1050
|
+
# Returns markup for a link that leads to Hub's login or logout link, using
|
1051
|
+
# pure HTML + CSS for styling. A universal "conditional login" link is used
|
1052
|
+
# since page data may be old due to e.g. a "back" button being used, after
|
1053
|
+
# the user either logged in or out elsewhere. This possibility is also why
|
1054
|
+
# JavaScript is used, updating the button styling the correct login state
|
1055
|
+
# if needed. This requires the "pageshow" event to be supported. NOSCRIPT
|
1056
|
+
# browsers use the a no-cache image-based fallback, which is much less
|
1057
|
+
# efficient, but works.
|
971
1058
|
#
|
972
|
-
#
|
973
|
-
#
|
974
|
-
#
|
975
|
-
# no-cache image fallback, which is much less efficient, but works.
|
1059
|
+
# Although the JavaScript-powered option could use the non-conditional link
|
1060
|
+
# for log in/out and swap those, it's simpler just to use generate the same
|
1061
|
+
# link for all states - script-capable or otherwise, logged in or out,
|
976
1062
|
#
|
977
1063
|
def hubssolib_account_link
|
978
|
-
|
979
|
-
|
1064
|
+
logged_in_url = self.hubssolib_returnable_account_url(universal: false, logged_in: true)
|
1065
|
+
logged_out_url = self.hubssolib_returnable_account_url(universal: false, logged_in: false)
|
1066
|
+
universal_url = self.hubssolib_returnable_account_url(universal: true)
|
1067
|
+
|
980
1068
|
noscript_img_src = "#{HUB_PATH_PREFIX}/account/login_indication.png"
|
981
1069
|
noscript_img_tag = helpers.image_tag(noscript_img_src, size: '90x22', border: '0', alt: 'Log in or out')
|
982
1070
|
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
if return_to_url.present?
|
987
|
-
return_query = URI.encode_www_form({ return_to_url: return_to_url.to_s })
|
988
|
-
ui_href << "?#{return_query}"
|
989
|
-
end
|
990
|
-
end
|
991
|
-
|
992
|
-
logged_in_link = helpers.link_to('Account', ui_href, id: 'hubssolib_logged_in_link')
|
993
|
-
logged_out_link = helpers.link_to('Log in', ui_href, id: 'hubssolib_logged_out_link')
|
994
|
-
noscript_link = helpers.link_to(noscript_img_tag, ui_href, id: 'hubssolib_login_noscript')
|
1071
|
+
logged_in_link = helpers.link_to('Account', logged_in_url, id: 'hubssolib_logged_in_link')
|
1072
|
+
logged_out_link = helpers.link_to('Log in', logged_out_url, id: 'hubssolib_logged_out_link')
|
1073
|
+
noscript_link = helpers.link_to(noscript_img_tag, universal_url, id: 'hubssolib_login_noscript')
|
995
1074
|
|
996
1075
|
# Yes, it's ugly, but yes, it works and it's a lot better for the server
|
997
1076
|
# to avoid the repeated image fetches. It probably works out as overall
|
@@ -1092,6 +1171,13 @@ module HubSsoLib
|
|
1092
1171
|
HubSsoLib::Trust.get_trust_object().review_action(**args)
|
1093
1172
|
end
|
1094
1173
|
|
1174
|
+
# The equivalent of #hubssolib_review_action, but for retrieving details of
|
1175
|
+
# an action when Hub invokes your callback via POST request.
|
1176
|
+
#
|
1177
|
+
def hubssolib_retrieve_action(**args)
|
1178
|
+
HubSsoLib::Trust.get_trust_object().retrieve_action(**args)
|
1179
|
+
end
|
1180
|
+
|
1095
1181
|
# Public read-only accessor methods for common user activities:
|
1096
1182
|
# return the current user's roles as a Roles object, or nil if
|
1097
1183
|
# there's no user.
|
@@ -1210,6 +1296,18 @@ module HubSsoLib
|
|
1210
1296
|
hubssolib_factory().destroy_sessions_by_user_id(hub_user_id) unless hub_user_id.nil?
|
1211
1297
|
end
|
1212
1298
|
|
1299
|
+
# WARNING: Comparatively slow.
|
1300
|
+
#
|
1301
|
+
# If a Hub user record changes, make sure their session records reflect
|
1302
|
+
# the updated demographics according to the HubSsoLib::User provided.
|
1303
|
+
#
|
1304
|
+
# For information about performance limitations, see
|
1305
|
+
# HubSsoLib::SessionFactory#destroy_sessions_by_user_id.
|
1306
|
+
#
|
1307
|
+
def hubssolib_update_user_sessions(hub_user_id, hub_user)
|
1308
|
+
hubssolib_factory().update_sessions_by_user_id(hub_user_id, hub_user) unless hub_user_id.nil?
|
1309
|
+
end
|
1310
|
+
|
1213
1311
|
# If an application needs to know about changes of a user e-mail address
|
1214
1312
|
# or display name (e.g. because of sync to a local relational store of
|
1215
1313
|
# users related to other application-managed resources, with therefore a
|
@@ -1320,7 +1418,6 @@ module HubSsoLib
|
|
1320
1418
|
cookies.delete(HUB_LOGIN_INDICATOR_COOKIE, domain: :all, path: '/')
|
1321
1419
|
|
1322
1420
|
if login_is_required
|
1323
|
-
hubssolib_store_location()
|
1324
1421
|
return hubssolib_must_login()
|
1325
1422
|
else
|
1326
1423
|
return true
|
@@ -1347,14 +1444,10 @@ module HubSsoLib
|
|
1347
1444
|
# if OK, else indicate that access is denied.
|
1348
1445
|
|
1349
1446
|
if (hubssolib_session_expired?)
|
1350
|
-
hubssolib_store_location()
|
1351
1447
|
hubssolib_log_out()
|
1352
1448
|
hubssolib_set_flash(:attention, 'Sorry, your session timed out; you need to log in again to continue.')
|
1353
1449
|
|
1354
|
-
|
1355
|
-
# ...except for the Hub, rather than the current application (whatever
|
1356
|
-
# it may be).
|
1357
|
-
redirect_to HUB_PATH_PREFIX + '/account/login'
|
1450
|
+
redirect_to hubssolib_returnable_account_url(logged_in: false)
|
1358
1451
|
else
|
1359
1452
|
hubssolib_set_last_used(Time.now.utc)
|
1360
1453
|
return hubssolib_authorized? ? true : hubssolib_access_denied()
|
@@ -1403,28 +1496,17 @@ module HubSsoLib
|
|
1403
1496
|
end
|
1404
1497
|
end
|
1405
1498
|
|
1406
|
-
#
|
1407
|
-
# optional supplied specific URI.
|
1408
|
-
#
|
1409
|
-
# We can return to this location by calling #redirect_back_or_default.
|
1499
|
+
# Deprecated. Don't use this. See #hubssolib_returnable_account_url.
|
1410
1500
|
#
|
1411
1501
|
def hubssolib_store_location(uri_str = request.url)
|
1412
|
-
|
1413
|
-
uri_str = hubssolib_promote_uri_to_ssl(uri_str, request.host) unless request.ssl?
|
1414
|
-
hubssolib_set_return_to(uri_str)
|
1415
|
-
else
|
1416
|
-
hubssolib_set_return_to(nil)
|
1417
|
-
end
|
1502
|
+
Rails.logger.warn('hubssolib_store_location: DEPRECATED (no-op)') rescue nil
|
1418
1503
|
end
|
1419
1504
|
|
1420
|
-
#
|
1421
|
-
# to the passed default.
|
1505
|
+
# Deprecated. Don't use this. See #hubssolib_returnable_account_url.
|
1422
1506
|
#
|
1423
1507
|
def hubssolib_redirect_back_or_default(default)
|
1424
|
-
|
1425
|
-
|
1426
|
-
|
1427
|
-
redirect_to(url || default)
|
1508
|
+
Rails.logger.warn('hubssolib_redirect_back_or_default: DEPRECATED (always redirects to default)') rescue nil
|
1509
|
+
redirect_to(default)
|
1428
1510
|
end
|
1429
1511
|
|
1430
1512
|
# Take a URI and pass an optional host parameter. Decomposes the URI,
|
@@ -1433,9 +1515,10 @@ module HubSsoLib
|
|
1433
1515
|
# as a flat string.
|
1434
1516
|
#
|
1435
1517
|
def hubssolib_promote_uri_to_ssl(uri_str, host = nil)
|
1436
|
-
uri
|
1437
|
-
uri.host
|
1518
|
+
uri = URI.parse(uri_str)
|
1519
|
+
uri.host = host if host
|
1438
1520
|
uri.scheme = hub_bypass_ssl? ? 'http' : 'https'
|
1521
|
+
|
1439
1522
|
return uri.to_s
|
1440
1523
|
end
|
1441
1524
|
|
@@ -1447,8 +1530,7 @@ module HubSsoLib
|
|
1447
1530
|
if request.ssl? || hub_bypass_ssl?
|
1448
1531
|
return true
|
1449
1532
|
else
|
1450
|
-
|
1451
|
-
redirect_to( hubssolib_promote_uri_to_ssl( request.request_uri, request.host ) )
|
1533
|
+
redirect_to(hubssolib_promote_uri_to_ssl(request.original_url))
|
1452
1534
|
return false
|
1453
1535
|
end
|
1454
1536
|
end
|
@@ -1458,21 +1540,32 @@ module HubSsoLib
|
|
1458
1540
|
# dropped. However, we also want this to work without being logged in, so
|
1459
1541
|
# in that case it uses the normal flash as a backup when *writing*.
|
1460
1542
|
#
|
1543
|
+
# This method returns the Hub flash if logged in, else +nil+.
|
1544
|
+
#
|
1461
1545
|
def hubssolib_get_flash
|
1462
1546
|
session = self.hubssolib_get_session()
|
1463
|
-
session&.session_flash
|
1547
|
+
session&.session_flash
|
1464
1548
|
end
|
1465
1549
|
|
1550
|
+
# Set Flash information under the given symbol with the given text message,
|
1551
|
+
# using the Hub cross-application flash store if logged in, else the
|
1552
|
+
# this-application local session flash store otherwise.
|
1553
|
+
#
|
1466
1554
|
def hubssolib_set_flash(symbol, message)
|
1467
1555
|
session = self.hubssolib_get_session()
|
1468
|
-
|
1469
|
-
f
|
1556
|
+
|
1557
|
+
f = hubssolib_get_flash()
|
1558
|
+
f ||= self.flash if self.respond_to?(:flash)
|
1559
|
+
f ||= {}
|
1470
1560
|
|
1471
1561
|
f[symbol] = message
|
1472
1562
|
|
1473
1563
|
session.session_flash = f unless session.nil?
|
1474
1564
|
end
|
1475
1565
|
|
1566
|
+
# Clears the *hub* flash for logged-in users, but not the local application
|
1567
|
+
# session flash.
|
1568
|
+
#
|
1476
1569
|
def hubssolib_clear_flash
|
1477
1570
|
session = self.hubssolib_get_session()
|
1478
1571
|
session.session_flash = {} unless session.nil?
|
@@ -1488,6 +1581,10 @@ module HubSsoLib
|
|
1488
1581
|
# values. This allows both the Hub and standard flashes to have values
|
1489
1582
|
# inside them under the same key. All keys are strings.
|
1490
1583
|
#
|
1584
|
+
# You may well prefer to use #hubssolib_flash_markup to obtain something
|
1585
|
+
# that can be written straight into a view, unless it doesn't meet your
|
1586
|
+
# markup requirements.
|
1587
|
+
#
|
1491
1588
|
def hubssolib_flash_data
|
1492
1589
|
|
1493
1590
|
# These known key values are used to guarantee an order in the output
|
@@ -1503,14 +1600,14 @@ module HubSsoLib
|
|
1503
1600
|
# Get an array of keys for the Hub flash with the ordered key items
|
1504
1601
|
# first and store data from that flash; same again for standard.
|
1505
1602
|
|
1506
|
-
hash = hubssolib_get_flash()
|
1603
|
+
hash = hubssolib_get_flash() || {}
|
1507
1604
|
keys = ordered_keys | hash.keys
|
1508
1605
|
|
1509
1606
|
keys.each do | key |
|
1510
1607
|
compiled_data['hub'][key] = hash[key] if hash.key?(key)
|
1511
1608
|
end
|
1512
1609
|
|
1513
|
-
if
|
1610
|
+
if self.respond_to?( :flash )
|
1514
1611
|
hash = flash.to_h()
|
1515
1612
|
keys = ordered_keys | hash.keys
|
1516
1613
|
|
@@ -1520,11 +1617,60 @@ module HubSsoLib
|
|
1520
1617
|
end
|
1521
1618
|
|
1522
1619
|
hubssolib_clear_flash()
|
1523
|
-
flash.
|
1620
|
+
flash.clear()
|
1524
1621
|
|
1525
1622
|
return compiled_data
|
1526
1623
|
end
|
1527
1624
|
|
1625
|
+
# A companion to #hubssolib_flash_data which returns standardised Flash
|
1626
|
+
# markup for your view. THIS MUST ONLY BE USED IN A VIEW / HELPER, or at
|
1627
|
+
# least somewhere that ActionView::Helpers::TagHelper#tag is available.
|
1628
|
+
#
|
1629
|
+
# * An outer DIV with class "flash" wraps the content.
|
1630
|
+
#
|
1631
|
+
# * Within that, +H2+ tags wrap each message in the flash data. These
|
1632
|
+
# tags also have class "flash", along with an additional tag which is
|
1633
|
+
# equal to the key under which the message was found - so if adding a
|
1634
|
+
# flash message under, say, <tt>:alert</tt>, the rendered result would
|
1635
|
+
# be <tt><h2 class="flash alert">...</h2></tt>.
|
1636
|
+
#
|
1637
|
+
# * As a special case, a key with the suffix <tt>_html_safe</tt> is taken
|
1638
|
+
# to contain HTML-safe strings and potential markup, so you could do
|
1639
|
+
# things like add emphasis, other classes or styles to the data written
|
1640
|
+
# inside the +H2+ tag. Be very careful to make sure any non-markup data
|
1641
|
+
# is properly escaped first. The key-related class in the arising +H2+
|
1642
|
+
# tag _excludes_ the suffix, so e.g. <tt>:notice_html_safe</tt> will
|
1643
|
+
# lead to class +notice+.
|
1644
|
+
#
|
1645
|
+
# Hub session-sourced and Rails local app session-sourced flash data is
|
1646
|
+
# treated the same, with Hub-sourced data listed first. The other is
|
1647
|
+
# otherwise undefined (it's rare for there to be more than one thing in
|
1648
|
+
# the flash at any given time, though).
|
1649
|
+
#
|
1650
|
+
def hubssolib_flash_markup
|
1651
|
+
data = hubssolib_flash_data()
|
1652
|
+
proc = Proc.new do | key, value |
|
1653
|
+
key = key.to_s
|
1654
|
+
|
1655
|
+
if key.end_with?( '_html_safe' )
|
1656
|
+
value = value.html_safe()
|
1657
|
+
key = key.chomp( '_html_safe' )
|
1658
|
+
end
|
1659
|
+
|
1660
|
+
helpers.tag.h2(value, class: "flash #{ key }")
|
1661
|
+
end
|
1662
|
+
|
1663
|
+
return helpers.tag.div(class: 'flash') do
|
1664
|
+
data['hub'].each do | key, value |
|
1665
|
+
helpers.concat(proc.call(key, value))
|
1666
|
+
end
|
1667
|
+
|
1668
|
+
data['standard'].each do | key, value |
|
1669
|
+
helpers.concat(proc.call(key, value))
|
1670
|
+
end
|
1671
|
+
end
|
1672
|
+
end
|
1673
|
+
|
1528
1674
|
# Retrieve the message of an exception stored as an object in the given
|
1529
1675
|
# string.
|
1530
1676
|
#
|
@@ -1541,8 +1687,10 @@ module HubSsoLib
|
|
1541
1687
|
|
1542
1688
|
:hubssolib_current_user,
|
1543
1689
|
:hubssolib_unique_name,
|
1690
|
+
:hubssolib_returnable_account_url,
|
1544
1691
|
:hubssolib_account_link,
|
1545
1692
|
:hubssolib_flash_data,
|
1693
|
+
:hubssolib_flash_markup,
|
1546
1694
|
|
1547
1695
|
:hubssolib_logged_in?,
|
1548
1696
|
:hubssolib_authorized?,
|
@@ -1696,7 +1844,7 @@ module HubSsoLib
|
|
1696
1844
|
#
|
1697
1845
|
if hubssolib_ensure_https
|
1698
1846
|
hubssolib_set_flash(:alert, 'You must log in before you can continue.')
|
1699
|
-
redirect_to
|
1847
|
+
redirect_to hubssolib_returnable_account_url(logged_in: false)
|
1700
1848
|
end
|
1701
1849
|
|
1702
1850
|
return false
|
@@ -1788,16 +1936,6 @@ module HubSsoLib
|
|
1788
1936
|
session = self.hubssolib_get_session()
|
1789
1937
|
session.session_last_used = time unless session.nil?
|
1790
1938
|
end
|
1791
|
-
|
1792
|
-
def hubssolib_get_return_to
|
1793
|
-
self.hubssolib_get_session()&.session_return_to
|
1794
|
-
end
|
1795
|
-
|
1796
|
-
def hubssolib_set_return_to(uri)
|
1797
|
-
session = self.hubssolib_get_session()
|
1798
|
-
session.session_return_to = uri unless session.nil?
|
1799
|
-
end
|
1800
|
-
|
1801
1939
|
end # Core module
|
1802
1940
|
end # HubSsoLib module
|
1803
1941
|
|
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.
|
4
|
+
version: 3.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Hodgkinson and others
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-
|
10
|
+
date: 2025-04-04 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: drb
|
@@ -51,6 +51,20 @@ dependencies:
|
|
51
51
|
- - "~>"
|
52
52
|
- !ruby/object:Gem::Version
|
53
53
|
version: '1.1'
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: rails
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '8.0'
|
61
|
+
type: :development
|
62
|
+
prerelease: false
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '8.0'
|
54
68
|
- !ruby/object:Gem::Dependency
|
55
69
|
name: simplecov
|
56
70
|
requirement: !ruby/object:Gem::Requirement
|