hubssolib 0.2.9 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +8 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +41 -0
- data/README.md +329 -0
- data/VERSION +1 -1
- data/hubssolib.gemspec +31 -0
- data/lib/hub_sso_lib.rb +215 -439
- metadata +80 -50
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9309369683fa647e559c4a87d5569e215d25f472b2acdb6869b538807a42ecf2
|
4
|
+
data.tar.gz: 6b4ffb49a16835ceac8436c6ebd5d9270fe9ea1af2d9c1de07616e2b38f5cd5e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8b4d75adcceea21ca4b95b49410a20667b7a1088e7f0bcf63e267699a779ba8e1ececcf2a5d5894274f7f12fe47eb4694bc948df912d625c86aece3dfc6551a7
|
7
|
+
data.tar.gz: 7c6aea5a1261203b6c74872620cbb7195e53cb9b545df6dea252bb0c4dce7c25260891d0ee7ceca8b1a85da29fb8669a7fb8346202f972d3263e199efd1df26c
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
## Version 1 -> Version 2.0.0, 19-Apr-2020
|
2
|
+
|
3
|
+
The public interface to applications is generally unchanged, but the cookie storage mechanism has been improved and is not compatible with v1 of Hub. You will need to use the newer Hub application, server and gem, but hopefully will find you don't need to change anything with your integrated applications.
|
4
|
+
|
5
|
+
* The Hub random data file is no longer necessary.
|
6
|
+
* The (internal) `HubSsoLib::Crypto` class has been completely deleted in favour of `SecureRandom.uuid` key rotation, HTTPS and insisting that the Hub server only ever runs on Unix domain sockets.
|
7
|
+
* The (internal) `hubssolib_get_secure_cookie_data`, `hubssolib_set_secure_cookie_data`, `hubssolib_get_user_data` and `hubssolib_set_user_data` methods are no longer needed and have been removed.
|
8
|
+
* The (internal) Hub server factory `get_session` factory method is renamed to `get_hub_session_proxy` (since that's what it actually does) and `enumerate_sessions` is renamed `enumerate_hub_sessions` as part of a wider rename that removed potential ambiguity in the application controller namespace between local variables called `session` and the Rails `session`.
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
hubssolib (2.0.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: http://rubygems.org/
|
8
|
+
specs:
|
9
|
+
diff-lcs (1.5.0)
|
10
|
+
docile (1.4.0)
|
11
|
+
rspec (3.11.0)
|
12
|
+
rspec-core (~> 3.11.0)
|
13
|
+
rspec-expectations (~> 3.11.0)
|
14
|
+
rspec-mocks (~> 3.11.0)
|
15
|
+
rspec-core (3.11.0)
|
16
|
+
rspec-support (~> 3.11.0)
|
17
|
+
rspec-expectations (3.11.0)
|
18
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
19
|
+
rspec-support (~> 3.11.0)
|
20
|
+
rspec-mocks (3.11.1)
|
21
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
22
|
+
rspec-support (~> 3.11.0)
|
23
|
+
rspec-support (3.11.0)
|
24
|
+
simplecov (0.21.2)
|
25
|
+
docile (~> 1.1)
|
26
|
+
simplecov-html (~> 0.11)
|
27
|
+
simplecov_json_formatter (~> 0.1)
|
28
|
+
simplecov-html (0.12.3)
|
29
|
+
simplecov_json_formatter (0.1.4)
|
30
|
+
|
31
|
+
PLATFORMS
|
32
|
+
ruby
|
33
|
+
|
34
|
+
DEPENDENCIES
|
35
|
+
hubssolib!
|
36
|
+
rspec (~> 3.8)
|
37
|
+
rspec-mocks (~> 3.8)
|
38
|
+
simplecov (~> 0.16)
|
39
|
+
|
40
|
+
BUNDLED WITH
|
41
|
+
2.3.17
|
data/README.md
ADDED
@@ -0,0 +1,329 @@
|
|
1
|
+
# Hub single sign-on
|
2
|
+
|
3
|
+
Hub is a Ruby On Rails application with accompanying library gem which manages user accounts for a web site. Its main use is for sites that run more than one Rails application within a single domain. Through integration with the Hub library gem, applications share Hub user details so that a user only has to create one account and log in or out of one place. Without Hub, users have to create and manage individual accounts for individual applications. Hub is therefore a single sign-on mechanism.
|
4
|
+
|
5
|
+
Applications require modifications to use Hub. Applications that already have the concept of users and accounts must be modified with some care, because the application's own account mechanism must be replaced or overlaid with the single sign-on alternative. Applications that have no account mechanism are much simpler to modify. You may wish to add Hub support to such applications so that users must create accounts to perform certain actions, such as posting to a forum or blog that might otherwise be completely open to the public — and therefore completely open to spam.
|
6
|
+
|
7
|
+
Hub has three main components. The Hub application handles users creating accounts, logging in and out and managing their account settings, through an ActiveRecord database connection and the library gem. User information stored securely in the database while the gem is used to record details when a user logs in or discard those details when a user logs out. The gem does this by sending objects to or reading objects from the third component, a small distributed Ruby server. Running on Unix domain sockets, the server allows all Hub-integrated Rails applications to share information on a logged in user without needing secondary ActiveRecord connections to the Hub database or any detailed knowledge of Hub's user account model. Everything is hidden by the Hub library gem API.
|
8
|
+
|
9
|
+
The Hub core is very distantly based on the [Acts as Authenticated](https://web.archive.org/web/20061126081805/http://technoweenie.stikipad.com/plugins/show/Acts+as+Authenticated) shell.
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
### Downloading
|
14
|
+
|
15
|
+
Presently, only a version of Hub with views styled for the RISC OS Open web site is available. In future I hope to add a more generic and more easily customised version.
|
16
|
+
|
17
|
+
The latest version of the Hub application is available at:
|
18
|
+
|
19
|
+
[https://github.com/pond/hub](https://github.com/pond/hub)
|
20
|
+
|
21
|
+
The latest version of the Hub gem source code is available at:
|
22
|
+
|
23
|
+
[https://github.com/pond/hubssolib](https://github.com/pond/hubssolib)
|
24
|
+
|
25
|
+
### The Hub library gem
|
26
|
+
|
27
|
+
First of all, download and unpack the Hub gem sources. Change into the source directory (usually, `rails/gems/hubssolib`) and build with:
|
28
|
+
|
29
|
+
```sh
|
30
|
+
gem build hubssolib.gemspec
|
31
|
+
```
|
32
|
+
|
33
|
+
Install the Hub gem using the `gem` command in the usual fashion. For example, for version 1.0.0 of the library, issue the following command:
|
34
|
+
|
35
|
+
```sh
|
36
|
+
gem install hubssolib-1.0.0.gem
|
37
|
+
```
|
38
|
+
|
39
|
+
If you run multiple gem repositories you can instruct `gem` to install into a specific location using the `--install-dir` command line switch:
|
40
|
+
|
41
|
+
```sh
|
42
|
+
gem install hubssolib-1.0.0.gem --install-dir=/home/username/gems
|
43
|
+
```
|
44
|
+
|
45
|
+
Include in a project by adding this to your `Gemfile`:
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
gem 'hubssolib', '~> 1.0.0', :require => 'hub_sso_lib'
|
49
|
+
```
|
50
|
+
|
51
|
+
### The DRb server
|
52
|
+
|
53
|
+
The Hub DRb server consists of a small wrapper Ruby script which does most of its work using the Hub gem. To run the server, you need to first specify a DRb connection URI in the `HUB_CONNECTION_URI` environment variable. Usually, this is a Unix domain socket and so lives in a location of your choice in the local filesystem. Run the server by running `ruby` on the `hub_sso_server.rb` file in the Hub archive. For example:
|
54
|
+
|
55
|
+
```sh
|
56
|
+
HUB_CONNECTION_URI="drbunix:/home/username/sockets/.hub_drb"
|
57
|
+
export HUB_CONNECTION_URI
|
58
|
+
ruby /home/username/hub/hub_sso_server.rb &
|
59
|
+
```
|
60
|
+
|
61
|
+
The default is to use a file `.hub_drb` in the root of the current user's home directory. If you specify a custom URI, note that it _MUST_ start with `drbunix:`; the hub server must not be run on an IP port for security reasons.
|
62
|
+
|
63
|
+
### The Hub application
|
64
|
+
|
65
|
+
Finally you can install the Hub application using whatever mechanism you prefer to application installation. See ample documentation elsewhere on the Web for information on installing Ruby On Rails applications — Hub itself contains the default rails README file with quite a lot of information in it.
|
66
|
+
|
67
|
+
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.
|
68
|
+
|
69
|
+
* `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.
|
70
|
+
* `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'`.
|
71
|
+
* `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`.
|
72
|
+
|
73
|
+
Usually, these are set up in a Web server configuration file as part of launching an FCGI process to host the Hub application.
|
74
|
+
|
75
|
+
Don't forget to set up the application's `database.yml` file in the usual fashion. use `rake db:migrate` to build the empty database structure.
|
76
|
+
|
77
|
+
## Cookies and domains
|
78
|
+
|
79
|
+
For Hub to work, your domains must _all match_. If one application on local development is fetched by `http://127.0.0.1` while another is on `http://locahost` or on something like `http://lvh.me`, an independent Hub session cookie will be generated by each application so things won't work; while Hub might think you're logged in, the integrating application will not.
|
80
|
+
|
81
|
+
A simple rule is to always use e.g. `http://127.0.0.1:3000` for the Hub application and `http://127.0.0.1:<other-port>` for other applications. So, for Hub, use:
|
82
|
+
|
83
|
+
```
|
84
|
+
bundle exec rails s -b 127.0.0.1 --port 3000
|
85
|
+
```
|
86
|
+
|
87
|
+
...and then launch integrating applications with:
|
88
|
+
|
89
|
+
```
|
90
|
+
HUB_PATH_PREFIX="http://127.0.0.1:3000" be rails s -b 127.0.0.1 --port <other-port>
|
91
|
+
```
|
92
|
+
|
93
|
+
...and fetch `http://127.0.0.1:<other-port>` in your web browser.
|
94
|
+
|
95
|
+
## Testing the installation
|
96
|
+
|
97
|
+
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.
|
98
|
+
|
99
|
+
As the first user of the Hub application, you test your installation by simply going through the sign-up process. The first account is automatically constructed with administrator privileges. If you are successfully able to visit the signup page, create your account, validate the signup using the confirmation e-mail message and subsequently log in or out of the new account, then Hub is correctly installed `:-)`
|
100
|
+
|
101
|
+
## Administrative use of the Hub application
|
102
|
+
|
103
|
+
Administrative account users are presented with extra options in the Hub control panel when they log on. You can list currently logged on users, list all users and modify account settings for any user, including deleting their accounts. Accounts have a list of _roles_ associated with them. Roles define whether or not a user has administrative privileges, webmaster privileges and so-on. When you integrate Hub with another application, you define exactly what these roles are because (as described below) you must assign lists of roles required to access protected controller actions.
|
104
|
+
|
105
|
+
Accounts can be assigned more than one role. Whether or not you ever want to do this will depend entirely on how you set up the roles required to access various controller actions as you integrate Hub with whichever applications you wish to work under the single sign-on mechanism.
|
106
|
+
|
107
|
+
## Integrating with applications
|
108
|
+
|
109
|
+
For full integration with Hub, particularly when it comes to showing or hiding things in application views, you need to know some of the Hub programmer interface. This API is described in detail later. First, we need to consider basic application integration issues, mostly revolving around modifying the application controllers. For more information on the interfaces used by the examples show, consult the detailed API documentation further down.
|
110
|
+
|
111
|
+
### Applications without an existing user model
|
112
|
+
|
113
|
+
Applications with no concept of user log-in are easy to integrate with Hub. Applications with only the concept of logging in for administrative purposes are similarly easy, provided your administrators do not mind having to log in using the application's own administrative mechanisms (so you basically treat the application as if it has no existing user model).
|
114
|
+
|
115
|
+
To integrate, add the Hub filters into `application.rb` just inside the definition of the `ApplicationController` class:
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
# Hub single sign-on support.
|
119
|
+
|
120
|
+
require 'hub_sso_lib'
|
121
|
+
include HubSsoLib::Core
|
122
|
+
before_action :hubssolib_beforehand
|
123
|
+
after_action :hubssolib_afterwards</pre>
|
124
|
+
```
|
125
|
+
|
126
|
+
Within any controller which has actions which you wish to protect with Hub login, define a variable `@@hubssolib_permissions` and provide an accessor method for it. I'll deal with the accessor method first; for a controller called `FooController`, add the following to `foo_controller.rb`:
|
127
|
+
|
128
|
+
```ruby
|
129
|
+
def FooController.hubssolib_permissions
|
130
|
+
@@hubssolib_permissions
|
131
|
+
end
|
132
|
+
```
|
133
|
+
|
134
|
+
More details are provided [below](#permissions) but, in brief, to define the permissions variable you create an instance of `HubSsoLib::Permissions`. The constructor is passed a hash. The hash keys are symbolized names of the controller actions you want to protect. The hash values are an array of privileges required to access the action, from a choice of one or more of `:admin`, `:webmaster`, `:privileged` and `:normal`. These relate to the roles you can assign to accounts as Hub administrator. For example:
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
@@hubssolib_permissions = HubSsoLib::Permissions.new({
|
138
|
+
:show => [ :admin, :webmaster, :privileged, :normal ],
|
139
|
+
:edit => [ :admin, :webmaster ]
|
140
|
+
})
|
141
|
+
```
|
142
|
+
|
143
|
+
In this example, any user can access the controller's `show` action but only users with an administrator or webmaster role associated with their account can access the `edit` action.
|
144
|
+
|
145
|
+
A user's role(s) must match at least one of the privileges in the array for a given action — so even if your account has an administrator role (and _only_ an administrator role), it won't be able to access a protected action unless `:admin` is included in the array given within the hash to the `HubSsoLib::Permissions` constructor. For example:
|
146
|
+
|
147
|
+
```ruby
|
148
|
+
@@hubssolib_permissions = HubSsoLib::Permissions.new({
|
149
|
+
:weblist => [ :webmaster, :privileged ]
|
150
|
+
})
|
151
|
+
```
|
152
|
+
|
153
|
+
Here, only accounts with the webmaster or privileged role associated can access the `weblist` action. If an account has only normal and/or administrative roles, it won't be allowed through.
|
154
|
+
|
155
|
+
### Applications with an existing user model
|
156
|
+
|
157
|
+
If you want to integrate Hub with an application which already has the concept of user accounts, logging in and logging out, there are two main approaches.
|
158
|
+
|
159
|
+
* Remove the existing mechanism and replace with Hub (see above). Removal may be through actually deleting code, models and filters related to that mechanism or simply removing or blocking access to the parts of the application that deal with the users and dropping in Hub equivalents over a minimum amount of code, reducing overall changes to the application but leaving a less clean result.
|
160
|
+
* Use a `before_action` in the application controller to run special code which you write, which maps a logged in Hub user to an existing application user. If the visitor is logged into Hub and no corresponding local application user account exists, one is created automatically based on the Hub account credentials.
|
161
|
+
|
162
|
+
Neither approach is problem-free and both require quite a lot of effort and testing. Automated testing is very hard because the modified application's behaviour depends upon logging in or out of Hub, which is running elsewhere. Unfortunately Rails doesn't offer a universally supported single sign-on mechanism so applications all use different approaches to user management; this means that there is no magic bullet to integration with Hub. You have to learn and understand the structure of the application being integrated and be prepared to make changes that are potentially quite extensive.
|
163
|
+
|
164
|
+
## Hub library API
|
165
|
+
|
166
|
+
The Hub component interfaces that should be used by application authors when integrating with the Hub single sign-on mechanism are described below. If you want a complete list of all public interfaces, consult the file `hub_sso_lib.rb` inside the Hub gem. All functions and classes therein are fully commented to describe the purpose of each class, along with the purpose, input parameters and return values of class methods and instance methods.
|
167
|
+
|
168
|
+
### Roles
|
169
|
+
|
170
|
+
Every Hub user account has assigned to it one or more _Roles_. For day to day use, roles are managed using the Hub application front-end. Role names are defined as symbols. Defined names are:
|
171
|
+
|
172
|
+
* `:admin` — Administrators.
|
173
|
+
* `:webmaster` — The site Webmaster.
|
174
|
+
* `:privileged` — Normal users with privileges for certain actions.
|
175
|
+
* `:normal` — Normal users. This role is assigned to new accounts by default.
|
176
|
+
|
177
|
+
When setting access permissions for actions in controllers (see next section), you specify the permissions in terms of the role names above. This means that you really define the true meaning of each of the four roles by their use within controllers. It isn't necessary to use all four roles or, if you want to add more, you can extend the `ROLES` constant in the `HubSsoLib::Roles` class inside `hub_sso_lib.rb` in the Hub gem.
|
178
|
+
|
179
|
+
### Permissions
|
180
|
+
|
181
|
+
Hub protects against access to actions in controller by using a `before_action` which checks to see if the controller defines a permissions structure. Permissions are defined as a hash, using action names as keys. The values define a role or roles permitted to access that action. Hub is based around the idea of a loose, permissive access mechanism. Actions omitted from the permissions hash _**are permitted**_ for general public access by default. Conversely, if an action is included but a particular role is not associated with it, that role is denied access. You can therefore allow a normal user to access an action which an administrator cannot use, by simply including the normal role but omitting the administrator role for that action.
|
182
|
+
|
183
|
+
Permitted roles are expressed as single symbols or their equivalent strings, or an array containing many symbols or equivalent strings. Most often, an array of symbols is used. To create a permissions object, instantiate `HubSsoLib::Permissions`. For example:
|
184
|
+
|
185
|
+
```ruby
|
186
|
+
@@hubssolib_permissions = HubSsoLib::Permissions.new({
|
187
|
+
:show => [ :admin, :webmaster, :privileged, :normal ],
|
188
|
+
:edit => [ :admin, :webmaster ]
|
189
|
+
})
|
190
|
+
```
|
191
|
+
|
192
|
+
Here, all roles are allowed to access the `show` action while only the `admin` and `webmaster` roles can access the `edit` action. Any other actions are unprotected, so even users who are not logged into to Hub can access them, along with any logged in Hub user regardless of the roles associated with their account.
|
193
|
+
|
194
|
+
The above line of code typically appears at the start of the class definition for the controller to which you are restricting access.
|
195
|
+
|
196
|
+
```ruby
|
197
|
+
class AccountController < ApplicationController
|
198
|
+
|
199
|
+
@@hubssolib_permissions = HubSsoLib::Permissions.new({
|
200
|
+
# ...permissions here...
|
201
|
+
})
|
202
|
+
|
203
|
+
# ...existing class contents here...
|
204
|
+
end
|
205
|
+
```
|
206
|
+
|
207
|
+
Having created the permissions object, you need to expose variable `@@hubssolib_permissions` to Hub in a way that it understands. To do this, create an instance method called `hubssolib_permissions` that just returns the variable:
|
208
|
+
|
209
|
+
```ruby
|
210
|
+
def AccountController.hubssolib_permissions
|
211
|
+
@@hubssolib_permissions
|
212
|
+
end
|
213
|
+
```
|
214
|
+
|
215
|
+
So the full preamble in this example is:
|
216
|
+
|
217
|
+
```ruby
|
218
|
+
class AccountController < ApplicationController
|
219
|
+
|
220
|
+
@@hubssolib_permissions = HubSsoLib::Permissions.new({
|
221
|
+
...permissions here...
|
222
|
+
})
|
223
|
+
|
224
|
+
def AccountController.hubssolib_permissions
|
225
|
+
@@hubssolib_permissions
|
226
|
+
end
|
227
|
+
|
228
|
+
...existing class contents here...
|
229
|
+
end
|
230
|
+
```
|
231
|
+
|
232
|
+
While you can ask a specific Permissions object whether or not an action is permitted for a given role or roles using the `permitted?` method ([see later](#permitted)), a more general purpose interface to achieve the same thing is provided in the `Core` module (see below). Use of the `Core` interface is strongly recommended.
|
233
|
+
|
234
|
+
### Core
|
235
|
+
|
236
|
+
The Hub `Core` module is usually included in `application.rb` as follows, just inside the `ApplicationController` class definition:
|
237
|
+
|
238
|
+
```ruby
|
239
|
+
# Hub single sign-on support.
|
240
|
+
|
241
|
+
require 'hub_sso_lib'
|
242
|
+
include HubSsoLib::Core
|
243
|
+
before_action :hubssolib_beforehand
|
244
|
+
after_action :hubssolib_afterwards
|
245
|
+
```
|
246
|
+
|
247
|
+
All internal methods have the `hubssolib_` prefix in an effort to avoid namespace collision with anything else in the including application.
|
248
|
+
|
249
|
+
#### The "before" action: `hubssolib_beforehand`
|
250
|
+
|
251
|
+
Before any action in a Hub integrated application, `hubssolib_beforehand` must be invoked. To achieve this, ensure that `application.rb` includes the method as a `before_action`, as listed above:
|
252
|
+
|
253
|
+
```ruby
|
254
|
+
before_action :hubssolib_beforehand
|
255
|
+
```
|
256
|
+
|
257
|
+
The filter is the core of the Hub protection mechanism, making sure that no action can run unless the user is logged in (unless the action is completely protected) and their account is associated with at least one of the roles required to access the action.
|
258
|
+
|
259
|
+
#### The "after" action: `hubssolib_afterwards`
|
260
|
+
|
261
|
+
After any action in a Hub integrated application, `hubssolib_afterward` must be invoked. To achieve this, ensure that `application.rb` includes the method as a `after_action`, as listed above:
|
262
|
+
|
263
|
+
```ruby
|
264
|
+
after_action :hubssolib_afterwards
|
265
|
+
```
|
266
|
+
|
267
|
+
At the time of writing the filter does nothing, but is included to allow for future expansion and avoid API changes that might force application integrators to modify their code.
|
268
|
+
|
269
|
+
#### Finding out about the current user
|
270
|
+
|
271
|
+
Most Hub integration methods are geared around making it easy to find out about a currently logged in user.
|
272
|
+
|
273
|
+
##### Is the user logged in?
|
274
|
+
|
275
|
+
Method `hubssolib_logged_in?` returns `true` if there is a Hub user presently logged in, else `false`.
|
276
|
+
|
277
|
+
##### What is the user's name?
|
278
|
+
|
279
|
+
Method `hubssolib_get_user_name` returns the display name of the currently logged in user as a string or `nil` if there is nobody logged in right now.
|
280
|
+
|
281
|
+
##### Does the user have a unique identifier?
|
282
|
+
|
283
|
+
Method `hubssolib_get_user_id` returns the Hub database ID of the currently logged in user or `nil` if there is nobody logged in right now. This numerical ID is unique but not human-readable; sometimes it is desirable to generate unique _display_ names. For example, perhaps you are integrating with an application that has its own account scheme based on unique user names shown in views (e.g. a forum) and want to create application accounts transparently to map to Hub accounts on the fly. For such purposes, call `hubssolib_unique_name`. The method returns a unique string containing the Hub user display name followed by the user ID in brackets or `nil` if nobody is logged in.
|
284
|
+
|
285
|
+
##### What is the user's e-mail address?
|
286
|
+
|
287
|
+
Method `hubssolib_get_user_address` returns the e-mail address specified by the currently logged in user when they signed up to Hub or `nil` if nobody is logged in right now. Since account confirmation in the Hub application is conducted by e-mail, the address ought to be valid unless the user created a temporary account purely for the purpose of signing up (there is no way to tell if this is the case). The e-mail address should only be used for sending solicited messages and never be displayed in views, since such addresses can be harvested for spam and as a result displaying an e-mail address without prior permission can make some account holders quite angry.
|
288
|
+
|
289
|
+
#### Checking for user permissions
|
290
|
+
|
291
|
+
Although controller actions are protected automatically by Hub, you may wish to hide things from certain users, such as links to actions they cannot perform or information that should only be seen by users with a different role set.
|
292
|
+
|
293
|
+
##### Can the user access a particular action?
|
294
|
+
|
295
|
+
Method `hubssolib_authorized?` takes two parameters:
|
296
|
+
|
297
|
+
1. The first is an action name, specified as a string or symbol. If calling from view or helper code you need to specify this every time, but if calling from a Controller you can omit it and the current action's name (the value of `action_name`) is used instead.
|
298
|
+
2. The second parameter is the name of the controller class, in which the action you're checking resides. If calling from that controller then again, you can omit this parameter; the class' own name (the value of `self.class`) is used instead. Otherwise, give the name; the `ClassName.hubssolib_permissions` method is used to discover the current set of permissions for the action.
|
299
|
+
|
300
|
+
By looking at the set of permissions for the controller class you specified in the second parameter for the action you specified in the first parameter, the method determines the list of permitted roles. If the currently logged in user's account has at least one of the roles associated with it, the method returns `true` to indicate that access is allowed. Otherwise, or if there is no user currently logged in, the method returns `false`.
|
301
|
+
|
302
|
+
##### Is the user's account privileged?
|
303
|
+
|
304
|
+
Although the use of roles in the lists of permissions written for controllers actually defines what each role means in practice, it's usually best to consider normal users as the least privileged and everyone else as having a more privileged access status. Sometimes you just want normal users to only access a limited amount of information or actions while anybody else, with any more privileged roles associated with their account, can do more interesting (but potentially dangerous!) things. Primarily for use in views, the `hubssolib_privileged?` method returns `true` if the currently logged in user account has any roles _other_ than just `:normal`, else `false` for `:normal` roles only, or if there is no user logged in right now.
|
305
|
+
|
306
|
+
To obtain an array of the current user's roles, call `hubssolib_get_user_roles`. This returns a `HubSsoLib:Roles` object which implements the following public methods:
|
307
|
+
|
308
|
+
* `get_role_symbols` — returns an array of _all_ valid role symbols (e.g. `:admin` and `:normal`.
|
309
|
+
* `get_display_name` — when passed a role symbol, returns a human-readable role name in English. If you are using an internationalised application, you'd probably just look up the key in some part of your messages file with `I18n.t` instead.
|
310
|
+
* `get_display_names` — returns an array of human-readable role names for _all_ valid roles (see `get_display_name` above).
|
311
|
+
* `include?` — when passed a role symbol, returns `true` if this Roles object includes that symbol, else `false`.
|
312
|
+
* `includes?` — aliased to `include?`.
|
313
|
+
* `validate` — integrity check — if this returns `false`, somehow an unrecognised role symbol got injected into the database for the Hub user for which this Roles object was generated, so it includes an unrecognised role. This is really a debugging function and shouldn't ever happen, but if you want to be paranoid, you could always check that any Roles object returned by Hub returns `true` when this method is called, indicating that it is valid.
|
314
|
+
|
315
|
+
As described above when talking about [`HubSsoLib::Permissions` earlier](#permissions), Hub defines roles `:normal`, `:privileged`, `:webmaster` and `:admin`. The significance attached to these depends entirely on your chosen use of them in access permissions to parts of your site.
|
316
|
+
|
317
|
+
##### Permissions for arbitrary user accounts
|
318
|
+
|
319
|
+
Although applications are normally concerned with the abilities of the _currently logged in_ user, leading to simple Hub accessor methods such as `hubssolib_authorized?`, sometimes you may need more control. For example, you may want to check action permissions of an arbitrary user as part of some administrative interface.
|
320
|
+
|
321
|
+
The `HubSsoLib::Permissions` instance you define in your controllers ([see earlier](#permissions)) is key to this. You can create an instance as discussed earlier — usually just calling your controller's own `hubssolib_permissions` class method when considering action permissions for the controller of interest is simplest. This has member method `permitted?` on this to find out if an action is allowed. Pass a Roles object in the first parameter and an action, expressed as a symbol (e.g. `:create`, `:edit`) in the second parameter. The method returns `true` if the permissions object allows the given action under the given Roles, else `false`.
|
322
|
+
|
323
|
+
In the example of "permissions for arbitrary user" you may well not have ready access to an initialised Roles object for that user, so you will probably have to build one. Use `Roles.new(...)` to create a new Roles object, passing it `true` to assign a single initial role of `:admin` or `false` to assign a single initial role of `:normal`. You can use the instance methods `add` and `delete` to add or delete roles to the object, specified as role symbols. Use `clear` to empty the object of all roles.
|
324
|
+
|
325
|
+
### Visual feedback
|
326
|
+
|
327
|
+
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.
|
328
|
+
|
329
|
+
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").
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
2.0.0 (19-Apr-2020)
|
data/hubssolib.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rake'
|
2
|
+
|
3
|
+
spec = Gem::Specification.new do |s|
|
4
|
+
s.platform = Gem::Platform::RUBY
|
5
|
+
s.name = 'hubssolib'
|
6
|
+
|
7
|
+
s.version = '2.0.0'
|
8
|
+
s.author = 'Andrew Hodgkinson and others'
|
9
|
+
s.email = 'ahodgkin@rowing.org.uk'
|
10
|
+
s.homepage = 'http://hub.pond.org.uk/'
|
11
|
+
s.date = File.ctime('VERSION')
|
12
|
+
s.summary = 'Cross-application single sign-on support library.'
|
13
|
+
s.license = 'MIT'
|
14
|
+
|
15
|
+
s.description = <<-EOF
|
16
|
+
The Hub SSO Library supports single sign-on across multiple Rails
|
17
|
+
applications on the same host. The Hub application provides account
|
18
|
+
management facilities (sign up, log in, etc.). The library provides
|
19
|
+
read-only access to data set up by the application. Using the library,
|
20
|
+
external applications can see whether or not someone is logged in via
|
21
|
+
Hub and see what their assigned roles are. Each application determines
|
22
|
+
its own mappings between roles and permissions.
|
23
|
+
EOF
|
24
|
+
|
25
|
+
s.files = FileList['lib/**/*.rb', '[A-Z]*'].to_a
|
26
|
+
s.required_ruby_version = '>= 2.5.9' # Not tested on earlier versions
|
27
|
+
|
28
|
+
s.add_development_dependency 'simplecov', '~> 0.16'
|
29
|
+
s.add_development_dependency 'rspec', '~> 3.8'
|
30
|
+
s.add_development_dependency 'rspec-mocks', '~> 3.8'
|
31
|
+
end
|