authrocket 2.1.1 → 2.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +27 -0
- data/LICENSE +1 -1
- data/README.md +163 -62
- data/app/controllers/auth_rocket/ar_controller.rb +44 -0
- data/app/controllers/logins_controller.rb +15 -0
- data/authrocket.gemspec +1 -1
- data/config/routes.rb +8 -0
- data/lib/authrocket.rb +1 -1
- data/lib/authrocket/api/api_config.rb +15 -2
- data/lib/authrocket/api/client.rb +1 -1
- data/lib/authrocket/api/version.rb +1 -1
- data/lib/authrocket/app_hook.rb +1 -1
- data/lib/authrocket/credential.rb +10 -0
- data/lib/authrocket/jwt_key.rb +11 -0
- data/lib/authrocket/rails.rb +5 -0
- data/lib/authrocket/rails/controller_helper.rb +47 -0
- data/lib/authrocket/rails/engine.rb +13 -0
- data/lib/authrocket/realm.rb +3 -1
- data/lib/authrocket/session.rb +13 -1
- data/lib/authrocket/user.rb +11 -0
- metadata +20 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8806b7bb2d33bd8f45cdc90f2b3dddac5e1aab15956b54dd6eb5ae435b636287
|
4
|
+
data.tar.gz: 60a546549c2ec30ecfdaee1c9a391bfb0d747909346e78eb5a1ff274f2b9dbc4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: edb91edfa64deceb771134a84ad3b63719cd7e5a363e9485150d4361cac8162912da86adf9f3a93eb9214901c923f21df19a8c356a8c7085ca47c76f018c484a
|
7
|
+
data.tar.gz: 22031370adff34599aaf30d78a4d075fd023aea255e1c3bb41d014fcc4fee2a157284bcf691ca1fdceed2cdaba844fa9707b980cf290b842059245da9621cef7
|
data/CHANGELOG.md
CHANGED
@@ -1,16 +1,43 @@
|
|
1
|
+
#### 2.4.1
|
2
|
+
|
3
|
+
- Require ncore 2.2.2+
|
4
|
+
|
5
|
+
#### 2.4.0
|
6
|
+
|
7
|
+
- Add Rails Engine for expedited setup
|
8
|
+
|
9
|
+
#### 2.3.1
|
10
|
+
|
11
|
+
- Properly self-configure when only using :jwt_secret
|
12
|
+
|
13
|
+
#### 2.3.0
|
14
|
+
|
15
|
+
- Add support for TOTP MFA
|
16
|
+
|
17
|
+
#### 2.2.0
|
18
|
+
|
19
|
+
- Add Realm#jwt_algo
|
20
|
+
- Deprecate Realm#jwt_secret - replaced with Realm#jwt_key
|
21
|
+
- Add JwtKey resource
|
22
|
+
- Support RS256 signed tokens
|
23
|
+
|
1
24
|
#### 2.1.1
|
25
|
+
|
2
26
|
- Add Realm#jwt_fields
|
3
27
|
- Deprecate Realm#jwt_data - replaced by #jwt_fields
|
4
28
|
- Parse custom attributes from JWT when available
|
5
29
|
|
6
30
|
#### 2.1.0
|
31
|
+
|
7
32
|
- AuthProvider.authorize, #authorize_token can now return a UserToken
|
8
33
|
- Add UserToken#credential_type
|
9
34
|
|
10
35
|
#### 2.0.3
|
36
|
+
|
11
37
|
- Fix error handling for missing jwt_secret
|
12
38
|
|
13
39
|
#### 2.0.2
|
40
|
+
|
14
41
|
- Add Realm#resource_links
|
15
42
|
|
16
43
|
#### 2.0.1
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -5,124 +5,224 @@
|
|
5
5
|
This gem works with both Rails and plain Ruby. It will auto-detect Rails and enable Rails-specific features as appropriate.
|
6
6
|
|
7
7
|
|
8
|
-
## Usage
|
9
8
|
|
10
|
-
|
9
|
+
## Usage - Rails
|
11
10
|
|
11
|
+
AuthRocket includes a streamlined Rails integration that automatically provides login and logout actions, and all relevant handling. For a new app, we highly recommend this.
|
12
12
|
|
13
|
-
|
13
|
+
Note: The streamlined integration requires Rails 4.2+.
|
14
14
|
|
15
|
-
|
15
|
+
To your Gemfile, add:
|
16
|
+
|
17
|
+
gem 'authrocket', require: 'authrocket/rails'
|
18
|
+
|
19
|
+
Then ensure the following environment variables are set:
|
20
|
+
|
21
|
+
AUTHROCKET_LOGIN_URL = https://sample.e1.loginrocket.com/
|
22
|
+
AUTHROCKET_JWT_SECRET = jsk_SAMPLE
|
23
|
+
|
24
|
+
If you plan to access the AuthRocket API as well, you'll need these variables too:
|
16
25
|
|
17
26
|
AUTHROCKET_API_KEY = ko_SAMPLE
|
18
27
|
AUTHROCKET_URL = https://api-e1.authrocket.com/v1
|
19
28
|
AUTHROCKET_REALM = rl_SAMPLE # optional
|
20
|
-
|
29
|
+
|
30
|
+
Finally, add a `before_action` command to any/all controllers or actions that should require a login.
|
31
|
+
|
32
|
+
For example, to protect your entire app:
|
33
|
+
|
34
|
+
class ApplicationController < ActionController::Base
|
35
|
+
before_action :require_valid_token
|
36
|
+
end
|
37
|
+
|
38
|
+
Selectively exempt certain actions or controllers using the standard `skip_before_action` method:
|
39
|
+
|
40
|
+
class ContactUsController < ActionController::Base
|
41
|
+
skip_before_action :require_valid_token, only: [:new, :create]
|
42
|
+
end
|
43
|
+
|
44
|
+
Helpers are provided to create login, signup, and logout links:
|
45
|
+
|
46
|
+
<%= link_to 'Login', ar_login_url %>
|
47
|
+
<%= link_to 'Signup', ar_signup_url %>
|
48
|
+
<%= link_to 'Logout', logout_path %>
|
49
|
+
|
50
|
+
Both the current session and user are available to your controllers and views:
|
51
|
+
|
52
|
+
current_session # => AuthRocket::Session
|
53
|
+
current_user # => AuthRocket::User
|
54
|
+
|
55
|
+
Membership and Org data is accessible through those helpers as well. Be sure to tell AuthRocket to include Membership and/or Org data in the JWT (Realm -> Settings -> Sessions & JWT).
|
56
|
+
|
57
|
+
current_user.memberships
|
58
|
+
current_user.memberships.first.org
|
59
|
+
current_user.orgs
|
60
|
+
|
61
|
+
See below for customization details.
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
## Usage - everywhere else
|
66
|
+
|
67
|
+
If you aren't using Rails, or if the streamlined integration above is too opinionated, use the gem without the extra Rails integration.
|
68
|
+
|
69
|
+
In your Gemfile, add:
|
70
|
+
|
71
|
+
gem 'authrocket'
|
72
|
+
|
73
|
+
Then set the following environment variables:
|
74
|
+
|
75
|
+
# If accessing the AuthRocket API:
|
76
|
+
AUTHROCKET_API_KEY = ko_SAMPLE
|
77
|
+
AUTHROCKET_URL = https://api-e1.authrocket.com/v1 # must match your account's provisioned cluster
|
78
|
+
AUTHROCKET_REALM = rl_SAMPLE # optional
|
79
|
+
#
|
80
|
+
# If using JWT-verification of AuthRocket's login tokens:
|
81
|
+
AUTHROCKET_JWT_SECRET = jsk_SAMPLE
|
82
|
+
|
83
|
+
If you're using either Hosted LoginRocket or authrocket.js to manage logins, see Verifing login tokens below. If you plan to use the API to directly authenticate, see the [API docs](https://authrocket.com/docs/api).
|
84
|
+
|
85
|
+
|
21
86
|
|
22
|
-
|
87
|
+
## Configuration
|
23
88
|
|
24
|
-
|
89
|
+
By default, AuthRocket automatically loads credentials from environment variables. This is optimal for any 12-factor deployment. Supported variables are:
|
25
90
|
|
26
|
-
`
|
91
|
+
`AUTHROCKET_API_KEY = ko_SAMPLE`
|
92
|
+
Your AuthRocket API key. Required to use the API (but not if only performing JWT verification of login tokens).
|
27
93
|
|
28
|
-
|
94
|
+
`AUTHROCKET_JWT_SECRET = jsk_SAMPLE`
|
95
|
+
Used to perform JWT signing verification of login tokens. Not required if validating all tokens using the API instead. This is a realm-specific value, so like `AUTHROCKET_REALM`, set it on a per-use basis if using multiple realms.
|
96
|
+
|
97
|
+
`AUTHROCKET_LOGIN_URL = https://sample.e1.loginrocket.com/`
|
98
|
+
The LoginRocket URL for your Connected App. Only used by the streamlined Rails integration (for redirects), but still available to use otherwise. If your app uses multiple realms, you'll need to handle this on your own. If you're using a custom domain, this will be that domain and will not contain 'loginrocket.com'.
|
99
|
+
|
100
|
+
`AUTHROCKET_REALM = rl_SAMPLE`
|
101
|
+
Sets an application-wide default realm ID. If you're using a single realm, this is definitely easiest. Certain multi-tenant apps might using multiple realms. In this case, don't set this globally, but include it as part of the `:credentials` set for each API method.
|
102
|
+
|
103
|
+
`AUTHROCKET_URL = https://api-e1.authrocket.com/v1`
|
104
|
+
The URL of the AuthRocket API server. This may vary depending on which cluster your account is provisioned on.
|
105
|
+
|
106
|
+
|
107
|
+
It's also possible to configure AuthRocket using a Rails initializer (or other initialization code).
|
29
108
|
|
30
109
|
AuthRocket::Api.credentials = {
|
31
110
|
api_key: 'ko_SAMPLE',
|
32
|
-
|
111
|
+
jwt_secret: 'jsk_SAMPLE',
|
112
|
+
loginrocket_url: 'https://sample.e1.loginrocket.com/',
|
33
113
|
realm: 'rl_SAMPLE',
|
34
|
-
|
114
|
+
url: 'https://api-e1.authrocket.com/v1'
|
35
115
|
}
|
36
116
|
|
37
117
|
|
38
|
-
### Hosted Logins
|
39
118
|
|
40
|
-
|
119
|
+
## Customizing the Rails integration
|
41
120
|
|
42
|
-
|
121
|
+
The built-in Rails integration tries to handle as much for you as possible. However, there may be times when you wish to modify the default behavior.
|
43
122
|
|
44
|
-
Be sure to enable Hosted Logins (a separate step) and specify a Login Handler URL. For development purposes, we'll point the Login Handler URL to your local app. Assuming your Rails app is running on port 3000, you'd enter `http://localhost:3000/login`.
|
45
123
|
|
46
|
-
|
124
|
+
#### The default post-login path
|
47
125
|
|
48
|
-
|
126
|
+
After a user logs in (or signs up), they are returned to either the last page they tried to access (if known) or to `'/'` (the default path).
|
49
127
|
|
50
|
-
|
51
|
-
before_filter :require_user
|
52
|
-
# This protects *all* of your app. If that's not what
|
53
|
-
# you want, then just add this to the controllers
|
54
|
-
# that need to be protected.
|
128
|
+
This default path may be changed using an initializer.
|
55
129
|
|
56
|
-
|
130
|
+
Create/edit `config/initializers/authrocket.rb` and add:
|
57
131
|
|
58
|
-
|
59
|
-
|
60
|
-
|
132
|
+
```ruby
|
133
|
+
AuthRocket::Api.default_login_path = '/manage'
|
134
|
+
```
|
61
135
|
|
62
|
-
def require_user
|
63
|
-
unless current_user
|
64
|
-
redirect_to LOGIN_URL
|
65
|
-
end
|
66
|
-
end
|
67
136
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
137
|
+
#### /login and /logout routes
|
138
|
+
|
139
|
+
The default routes for login and logout are `/login` and `/logout`, respectively. To override them, add an initializer for AuthRocket (eg: `config/initializers/authrocket.rb`) and add:
|
140
|
+
|
141
|
+
AuthRocket::Api.use_default_routes = false
|
73
142
|
|
74
|
-
|
143
|
+
Then add your own routes to `config/routes.rb`:
|
75
144
|
|
76
|
-
|
145
|
+
get 'mylogin' => 'logins#login'
|
146
|
+
get 'mylogout' => 'logins#logout'
|
77
147
|
|
78
|
-
Then add login and logout methods:
|
79
148
|
|
80
|
-
|
81
|
-
skip_before_filter :require_user
|
149
|
+
#### The login controller
|
82
150
|
|
151
|
+
AuthRocket's default login controller automatically sets up the session (by storing the login token in `session[:ar_token]`) and makes a best effort at returning the user to where they were when the login request was triggered.
|
152
|
+
|
153
|
+
If you require more customization than provided by modifying the default post-login path, as outlined above, you may create your own LoginsController and inherit from AuthRocket's controller:
|
154
|
+
|
155
|
+
class LoginsController < AuthRocket::ArController
|
83
156
|
def login
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
157
|
+
super
|
158
|
+
if current_session
|
159
|
+
# @redir will be present if the user's previous URL was able to be
|
160
|
+
# saved. If not, then provide a fallback (eg: root_path,
|
161
|
+
# manager_path, etc).
|
162
|
+
redirect_to @redir || dashboard_path
|
90
163
|
end
|
91
|
-
|
164
|
+
# else if login failed, a redirect to LoginRocket happens automatically
|
92
165
|
end
|
93
166
|
|
94
167
|
def logout
|
95
|
-
|
168
|
+
super
|
169
|
+
# Change the path and/or the message.
|
96
170
|
redirect_to root_path, notice: 'You have been logged out.'
|
97
171
|
end
|
98
172
|
end
|
99
173
|
|
100
|
-
|
174
|
+
If you wish to replace all of the login logic, create a new, different controller that doesn't inherit from `AuthRocket::ArController` (and also override the routes, as per above). You may wish to look at `ArController` as a reference.
|
101
175
|
|
102
|
-
get '/login' => 'logins#login'
|
103
|
-
get '/logout' => 'logins#logout'
|
104
176
|
|
105
|
-
That's it. You're all done!
|
106
177
|
|
178
|
+
## Verifying login tokens
|
107
179
|
|
108
|
-
|
180
|
+
If you're not using the streamlined Rails integration, you'll need to verify the login tokens (unless you're using the API to authenticate directly).
|
109
181
|
|
110
|
-
For full details on the AuthRocket API, including examples for Ruby, see our [documentation](http://authrocket.com/docs).
|
111
182
|
|
183
|
+
#### JWT verification
|
112
184
|
|
113
|
-
|
185
|
+
AuthRocket's login tokens use the JWT standard and are cryptographically signed. Verifying the signature is extremely fast. Here's are a couple examples of using this:
|
114
186
|
|
115
|
-
|
187
|
+
def current_user
|
188
|
+
@_current_user ||= AuthRocket::Session.from_token(session[:ar_token]).try(:user)
|
189
|
+
end
|
116
190
|
|
117
|
-
|
191
|
+
`from_token` returns `nil` if the token is missing, expired, or otherwise invalid.
|
118
192
|
|
119
|
-
And then execute:
|
120
193
|
|
121
|
-
|
194
|
+
#### API verification
|
122
195
|
|
123
|
-
|
196
|
+
AuthRocket also supports Managed Sessions, which enables you to enforce logouts, even across apps (single sign-out!). In this instance, the session is regularly verified using the AuthRocket API.
|
197
|
+
|
198
|
+
def current_user
|
199
|
+
@_current_user ||= AuthRocket::Session.retrieve(session[:ar_token]).try(:user)
|
200
|
+
end
|
201
|
+
|
202
|
+
For better performance (and to avoid API rate limits), you may want to cache the results of the API call for 3-15 minutes.
|
203
|
+
|
204
|
+
|
205
|
+
#### Initial login
|
206
|
+
|
207
|
+
Each of the above are designed for ongoing use. The initial login isn't going to be much different though. Here's an example login action:
|
208
|
+
|
209
|
+
def login
|
210
|
+
if params[:token]
|
211
|
+
if AuthRocket::Session.from_token(params[:token])
|
212
|
+
session[:ar_token] = params[:token]
|
213
|
+
redirect_to '/'
|
214
|
+
return
|
215
|
+
end
|
216
|
+
end
|
217
|
+
redirect_to AuthRocket::Api.credentials[:loginrocket_url]
|
218
|
+
end
|
219
|
+
|
220
|
+
|
221
|
+
|
222
|
+
## Reference
|
223
|
+
|
224
|
+
For full details on the AuthRocket API, including examples for Ruby, see our [documentation](https://authrocket.com/docs).
|
124
225
|
|
125
|
-
$ gem install authrocket
|
126
226
|
|
127
227
|
|
128
228
|
## Contributing
|
@@ -134,6 +234,7 @@ Or install it yourself as:
|
|
134
234
|
5. Create new Pull Request
|
135
235
|
|
136
236
|
|
237
|
+
|
137
238
|
## License
|
138
239
|
|
139
240
|
MIT
|
@@ -0,0 +1,44 @@
|
|
1
|
+
class AuthRocket::ArController < ::ApplicationController
|
2
|
+
|
3
|
+
before_action :require_valid_token, only: []
|
4
|
+
# ensure :require_valid_token is known so it can be skipped
|
5
|
+
skip_before_action :require_valid_token
|
6
|
+
# in case it's globally applied to ApplicationController
|
7
|
+
|
8
|
+
def login
|
9
|
+
if params[:token]
|
10
|
+
if s = AuthRocket::Session.from_token(params[:token])
|
11
|
+
@_current_session = s
|
12
|
+
session[:ar_token] = params[:token]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
if current_session
|
16
|
+
@redir = sanitize_redir || session[:last_url]
|
17
|
+
session[:last_url] = nil
|
18
|
+
# redirect in the child
|
19
|
+
else
|
20
|
+
require_valid_token
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def logout
|
25
|
+
if current_session && current_session.id =~ /^kss_/ && AuthRocket::Api.credentials[:api_key]
|
26
|
+
AuthRocket::Session.delete current_session.id
|
27
|
+
end
|
28
|
+
session[:ar_token] = nil
|
29
|
+
# redirect in the child
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# sanitize by making it path-only
|
36
|
+
def sanitize_redir(redir=params[:redir])
|
37
|
+
return if redir.blank?
|
38
|
+
u = defined?(Addressable) ? Addressable::URI.parse(redir) : URI.parse(redir)
|
39
|
+
if u
|
40
|
+
[u.path, u.query].compact.join('?')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class LoginsController < AuthRocket::ArController
|
2
|
+
|
3
|
+
def login
|
4
|
+
super
|
5
|
+
if current_session
|
6
|
+
redirect_to @redir || AuthRocket::Api.default_login_path
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def logout
|
11
|
+
super
|
12
|
+
redirect_to '/', notice: 'You have been logged out.'
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
data/authrocket.gemspec
CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |gem|
|
|
20
20
|
|
21
21
|
gem.required_ruby_version = '>= 1.9'
|
22
22
|
|
23
|
-
gem.add_dependency 'ncore', '
|
23
|
+
gem.add_dependency 'ncore', '>= 2.2.2', '< 3'
|
24
24
|
gem.add_dependency 'jwt', '~> 1.5.0'
|
25
25
|
|
26
26
|
gem.add_development_dependency "bundler", "~> 1.3"
|
data/config/routes.rb
ADDED
data/lib/authrocket.rb
CHANGED
@@ -5,7 +5,7 @@ require 'jwt'
|
|
5
5
|
require "authrocket/api/#{f}"
|
6
6
|
end
|
7
7
|
|
8
|
-
%w(app_hook auth_provider credential event login_policy membership notification org realm session user user_token).each do |f|
|
8
|
+
%w(app_hook auth_provider credential event jwt_key login_policy membership notification org realm session user user_token).each do |f|
|
9
9
|
require "authrocket/#{f}"
|
10
10
|
end
|
11
11
|
|
@@ -14,13 +14,19 @@ module AuthRocket
|
|
14
14
|
|
15
15
|
if ENV['AUTHROCKET_URI']
|
16
16
|
self.credentials = parse_credentials ENV['AUTHROCKET_URI']
|
17
|
-
elsif ENV['AUTHROCKET_API_KEY']
|
17
|
+
elsif ENV['AUTHROCKET_API_KEY'] || ENV['AUTHROCKET_JWT_SECRET']
|
18
18
|
self.credentials = {
|
19
19
|
api_key: ENV['AUTHROCKET_API_KEY'],
|
20
20
|
account: ENV['AUTHROCKET_ACCOUNT'],
|
21
21
|
realm: ENV['AUTHROCKET_REALM'],
|
22
22
|
jwt_secret: ENV['AUTHROCKET_JWT_SECRET']
|
23
23
|
}
|
24
|
+
else
|
25
|
+
self.credentials = {}
|
26
|
+
end
|
27
|
+
|
28
|
+
if ENV['AUTHROCKET_LOGIN_URL']
|
29
|
+
self.credentials[:loginrocket_url] = ENV['AUTHROCKET_LOGIN_URL']
|
24
30
|
end
|
25
31
|
|
26
32
|
self.debug = false
|
@@ -30,11 +36,18 @@ module AuthRocket
|
|
30
36
|
|
31
37
|
self.instrument_key = 'request.authrocket'
|
32
38
|
|
33
|
-
self.status_page = '
|
39
|
+
self.status_page = 'https://status.authrocket.com/'
|
34
40
|
|
35
41
|
self.auth_header_prefix = 'X-Authrocket'
|
36
42
|
|
37
43
|
self.credentials_error_message = %Q{Missing API credentials or URL. Set default credentials using "AuthRocket::Api.credentials = {api_key: YOUR_API_KEY, url: AR_REGION_URL}"}
|
44
|
+
|
45
|
+
|
46
|
+
mattr_accessor :use_default_routes
|
47
|
+
self.use_default_routes = true
|
48
|
+
|
49
|
+
mattr_accessor :default_login_path
|
50
|
+
self.default_login_path = '/'
|
38
51
|
end
|
39
52
|
|
40
53
|
|
data/lib/authrocket/app_hook.rb
CHANGED
@@ -18,7 +18,7 @@ module AuthRocket
|
|
18
18
|
realm.created realm.updated realm.deleted
|
19
19
|
user.created user.updated user.deleted
|
20
20
|
user.email.verification_requested user.email.verified
|
21
|
-
user.login.succeeded user.login.failed
|
21
|
+
user.login.succeeded user.login.failed user.login.initiated
|
22
22
|
user.password_token.created user.password_token.consumed user.password_token.failed
|
23
23
|
).sort
|
24
24
|
end
|
@@ -8,7 +8,17 @@ module AuthRocket
|
|
8
8
|
attr :credential_type
|
9
9
|
attr :api_key
|
10
10
|
attr :password, :password_confirmation
|
11
|
+
attr :name, :otp_secret, :provisioning_uri, :state
|
11
12
|
attr :access_token, :provider_user_id, :token_expires_at
|
12
13
|
|
14
|
+
|
15
|
+
# code - required
|
16
|
+
def verify(code, attribs={})
|
17
|
+
params = parse_request_params(attribs.merge(code: code), json_root: json_root).merge credentials: api_creds
|
18
|
+
parsed, _ = request(:post, url+'/verify', params)
|
19
|
+
load(parsed)
|
20
|
+
errors.empty? ? self : false
|
21
|
+
end
|
22
|
+
|
13
23
|
end
|
14
24
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module AuthRocket::ControllerHelper
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
if respond_to?(:helper_method)
|
6
|
+
helper_method :current_session
|
7
|
+
helper_method :current_user
|
8
|
+
helper_method :ar_login_url
|
9
|
+
helper_method :ar_signup_url
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
def require_valid_token
|
15
|
+
unless current_session
|
16
|
+
session[:last_url] = request.get? ? url_for(params.to_unsafe_h.except(:domain, :host, :port, :prototcol, :subdomain, :token)) : url_for
|
17
|
+
redirect_to ar_login_url + "?redir=#{ERB::Util.url_encode(session[:last_url])}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def current_session
|
23
|
+
@_current_session ||= AuthRocket::Session.from_token(session[:ar_token])
|
24
|
+
end
|
25
|
+
|
26
|
+
def current_user
|
27
|
+
current_session.try(:user)
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
def ar_login_url
|
32
|
+
@_login_url = loginrocket_url('login')
|
33
|
+
end
|
34
|
+
|
35
|
+
def ar_signup_url
|
36
|
+
@_signup_url = loginrocket_url('signup')
|
37
|
+
end
|
38
|
+
|
39
|
+
def loginrocket_url(path=nil)
|
40
|
+
raise "Missing env AUTHROCKET_LOGIN_URL or credentials[:loginrocket_url]" if AuthRocket::Api.credentials[:loginrocket_url].blank?
|
41
|
+
s = AuthRocket::Api.credentials[:loginrocket_url].dup
|
42
|
+
s.concat('/') unless s.ends_with?('/')
|
43
|
+
s.concat(path) if path
|
44
|
+
s.freeze
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
data/lib/authrocket/realm.rb
CHANGED
@@ -5,6 +5,7 @@ module AuthRocket
|
|
5
5
|
has_many :app_hooks
|
6
6
|
has_many :auth_providers
|
7
7
|
has_many :events
|
8
|
+
has_many :jwt_keys
|
8
9
|
has_many :login_policies
|
9
10
|
has_many :orgs
|
10
11
|
has_many :users
|
@@ -12,7 +13,8 @@ module AuthRocket
|
|
12
13
|
attr :api_key_minutes, :api_key_policy, :api_key_prefix, :custom, :name
|
13
14
|
attr :jwt_fields, :require_unique_emails, :resource_links, :session_minutes
|
14
15
|
attr :session_type, :state, :username_validation_human
|
15
|
-
attr :
|
16
|
+
attr :jwt_key # readonly
|
17
|
+
attr :jwt_secret # readonly, deprecated
|
16
18
|
attr :jwt_data # deprecated
|
17
19
|
|
18
20
|
|
data/lib/authrocket/session.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'jwt'
|
3
|
+
|
1
4
|
module AuthRocket
|
2
5
|
class Session < Resource
|
3
6
|
crud :all, :find, :create, :delete
|
@@ -13,12 +16,21 @@ module AuthRocket
|
|
13
16
|
|
14
17
|
|
15
18
|
# options - :within - (in seconds) Maximum time since the token was originally issued
|
19
|
+
# - credentials: {jwt_secret: StringOrKey} - used to verify the token
|
20
|
+
# - :algo - one of HS256, RS256 (default: auto-detect based on :jwt_secret)
|
16
21
|
def self.from_token(token, options={})
|
17
22
|
secret = (options[:credentials]||credentials||{})[:jwt_secret]
|
18
23
|
raise Error, "missing :jwt_secret (or AUTHROCKET_JWT_SECRET)" unless secret
|
19
24
|
return unless token
|
20
25
|
|
21
|
-
|
26
|
+
algo = options[:algo]
|
27
|
+
if secret.is_a?(String) && secret.length > 256
|
28
|
+
secret = OpenSSL::PKey.read secret
|
29
|
+
end
|
30
|
+
algo ||= 'RS256' if secret.is_a?(OpenSSL::PKey::RSA)
|
31
|
+
algo ||= 'HS256'
|
32
|
+
|
33
|
+
jwt, _ = JWT.decode token, secret, true, algorithm: algo
|
22
34
|
|
23
35
|
if within = options.delete(:within)
|
24
36
|
return if jwt['iat'] < Time.now.to_i - within
|
data/lib/authrocket/user.rb
CHANGED
@@ -51,6 +51,17 @@ module AuthRocket
|
|
51
51
|
new(parsed, creds)
|
52
52
|
end
|
53
53
|
|
54
|
+
# params - {username: '...', token: 'kli_...', code: '000000'}
|
55
|
+
def authenticate_code(params)
|
56
|
+
params = parse_request_params(params, json_root: json_root)
|
57
|
+
username = params[json_root].delete(:username) || '--'
|
58
|
+
parsed, creds = request(:post, "#{url}/#{CGI.escape username}/authenticate_code", params)
|
59
|
+
if parsed[:errors].any?
|
60
|
+
raise ValidationError, parsed[:errors]
|
61
|
+
end
|
62
|
+
new(parsed, creds)
|
63
|
+
end
|
64
|
+
|
54
65
|
def generate_password_token(username, params={})
|
55
66
|
params = parse_request_params(params)
|
56
67
|
parsed, creds = request(:post, "#{url}/#{CGI.escape username}/generate_password_token", params)
|
metadata
CHANGED
@@ -1,29 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: authrocket
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- AuthRocket Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ncore
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.2.2
|
20
|
+
- - "<"
|
18
21
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
22
|
+
version: '3'
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
|
-
- - "
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 2.2.2
|
30
|
+
- - "<"
|
25
31
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
32
|
+
version: '3'
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: jwt
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -79,7 +85,10 @@ files:
|
|
79
85
|
- LICENSE
|
80
86
|
- README.md
|
81
87
|
- Rakefile
|
88
|
+
- app/controllers/auth_rocket/ar_controller.rb
|
89
|
+
- app/controllers/logins_controller.rb
|
82
90
|
- authrocket.gemspec
|
91
|
+
- config/routes.rb
|
83
92
|
- lib/authrocket.rb
|
84
93
|
- lib/authrocket/api/api_config.rb
|
85
94
|
- lib/authrocket/api/client.rb
|
@@ -90,10 +99,14 @@ files:
|
|
90
99
|
- lib/authrocket/auth_provider.rb
|
91
100
|
- lib/authrocket/credential.rb
|
92
101
|
- lib/authrocket/event.rb
|
102
|
+
- lib/authrocket/jwt_key.rb
|
93
103
|
- lib/authrocket/login_policy.rb
|
94
104
|
- lib/authrocket/membership.rb
|
95
105
|
- lib/authrocket/notification.rb
|
96
106
|
- lib/authrocket/org.rb
|
107
|
+
- lib/authrocket/rails.rb
|
108
|
+
- lib/authrocket/rails/controller_helper.rb
|
109
|
+
- lib/authrocket/rails/engine.rb
|
97
110
|
- lib/authrocket/realm.rb
|
98
111
|
- lib/authrocket/session.rb
|
99
112
|
- lib/authrocket/user.rb
|
@@ -117,8 +130,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
117
130
|
- !ruby/object:Gem::Version
|
118
131
|
version: '0'
|
119
132
|
requirements: []
|
120
|
-
|
121
|
-
rubygems_version: 2.4.8
|
133
|
+
rubygems_version: 3.0.8
|
122
134
|
signing_key:
|
123
135
|
specification_version: 4
|
124
136
|
summary: AuthRocket client for Ruby
|