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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 25c9714d9a8a39ba10d25bce51b378d643bb2a86
4
- data.tar.gz: f6590ea8aed5079f41ddfe62d17c0095188efffb
2
+ SHA256:
3
+ metadata.gz: 8806b7bb2d33bd8f45cdc90f2b3dddac5e1aab15956b54dd6eb5ae435b636287
4
+ data.tar.gz: 60a546549c2ec30ecfdaee1c9a391bfb0d747909346e78eb5a1ff274f2b9dbc4
5
5
  SHA512:
6
- metadata.gz: ca3ea43ae527d665af2ffd02ade85e8dac33d895a9d879fa425f13a6b6d0399819c06ea99368189601d7fd80155393d32ddf730788142be2d1b3ab6afe6a4783
7
- data.tar.gz: 00183ddbe8d5b9d65da316118da31618dfa57892aa993ba7930470495d08a4d03d66a4b5219bc2807068667072ab67940c9bee667e90a3a6ac591ad0b818a1ba
6
+ metadata.gz: edb91edfa64deceb771134a84ad3b63719cd7e5a363e9485150d4361cac8162912da86adf9f3a93eb9214901c923f21df19a8c356a8c7085ca47c76f018c484a
7
+ data.tar.gz: 22031370adff34599aaf30d78a4d075fd023aea255e1c3bb41d014fcc4fee2a157284bcf691ca1fdceed2cdaba844fa9707b980cf290b842059245da9621cef7
@@ -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
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014-2017 Notioneer, Inc.
1
+ Copyright (c) 2014-2020 Notioneer, Inc.
2
2
 
3
3
  MIT License
4
4
 
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
- For installation, add `gem 'authrocket'` to your Gemfile. More details are below.
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
- ### Configuration
13
+ Note: The streamlined integration requires Rails 4.2+.
14
14
 
15
- By default, AuthRocket automatically loads your credentials from environment variables. For such hosting environments, including Heroku, just configure these:
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
- AUTHROCKET_JWT_SECRET = jsk_SAMPLE # optional
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
- `AUTHROCKET_URL` must be updated based on what cluster your account is provisioned on.
87
+ ## Configuration
23
88
 
24
- `AUTHROCKET_REALM` is optional. If you're using a single Realm, it's easiest to add it here as an application-wide default. If you're using multiple Realms with your app, we recommend leaving it out here and setting it as you go.
89
+ By default, AuthRocket automatically loads credentials from environment variables. This is optimal for any 12-factor deployment. Supported variables are:
25
90
 
26
- `AUTHROCKET_JWT_SECRET` is optional. It only should be included if you've also specified a single realm via AUTHROCKET_REALM *and* you're using hosted logins or authrocket.js. The tokens returned by both are JWT-compatible and can be verified in-app using a matching secret.
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
- It's possible to configure AuthRocket using a Rails initializer (or other initializaiton code) too.
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
- url: 'https://api-e1.authrocket.com/v1',
111
+ jwt_secret: 'jsk_SAMPLE',
112
+ loginrocket_url: 'https://sample.e1.loginrocket.com/',
33
113
  realm: 'rl_SAMPLE',
34
- jwt_secret: 'jsk_SAMPLE'
114
+ url: 'https://api-e1.authrocket.com/v1'
35
115
  }
36
116
 
37
117
 
38
- ### Hosted Logins
39
118
 
40
- AuthRocket has a few options to handle logins. One option is to let AuthRocket handle the login process completely, which is what's shown here. Your app only needs to verify the final login token. This example is specific to Rails, but adapt accordingly for Sinatra or any other framework.
119
+ ## Customizing the Rails integration
41
120
 
42
- To get started, login to AuthRocket and add a Login Policy (under Logins/Signups) for your chosen Realm (create your first Realm if you haven't already).
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
- After enabling Hosted Logins, take note of the LoginRocket URL. You'll need this below.
124
+ #### The default post-login path
47
125
 
48
- Let's add a couple methods to your Application Controller, substituting the correct value for `LOGIN_URL`:
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
- class ApplicationController < ActionController::Base
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
- private
130
+ Create/edit `config/initializers/authrocket.rb` and add:
57
131
 
58
- LOGIN_URL = 'https://sample.e1.loginrocket.com/'
59
- # This should be your app's own LoginRocket URL, as
60
- # shown in the Login Policy details.
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
- helper_method :current_user
69
- def current_user
70
- @_current_user ||= AuthRocket::Session.from_token(session[:ar_token]).try(:user)
71
- end
72
- end
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
- Create a Login or Session controller if you don't have one already:
143
+ Then add your own routes to `config/routes.rb`:
75
144
 
76
- rails g controller logins
145
+ get 'mylogin' => 'logins#login'
146
+ get 'mylogout' => 'logins#logout'
77
147
 
78
- Then add login and logout methods:
79
148
 
80
- class LoginsController < ApplicationController
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
- if params[:token]
85
- if AuthRocket::Session.from_token(params[:token])
86
- session[:ar_token] = params[:token]
87
- redirect_to root_path
88
- return
89
- end
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
- require_user
164
+ # else if login failed, a redirect to LoginRocket happens automatically
92
165
  end
93
166
 
94
167
  def logout
95
- session[:ar_token] = nil
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
- Finally, update `config/routes.rb`:
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
- ### Other Methods
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
- ## Installation
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
- Add this line to your application's Gemfile:
187
+ def current_user
188
+ @_current_user ||= AuthRocket::Session.from_token(session[:ar_token]).try(:user)
189
+ end
116
190
 
117
- gem 'authrocket'
191
+ `from_token` returns `nil` if the token is missing, expired, or otherwise invalid.
118
192
 
119
- And then execute:
120
193
 
121
- $ bundle
194
+ #### API verification
122
195
 
123
- Or install it yourself as:
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
@@ -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', '~> 2.0'
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"
@@ -0,0 +1,8 @@
1
+ Rails.application.routes.draw do
2
+
3
+ if AuthRocket::Api.use_default_routes
4
+ get 'login' => 'logins#login'
5
+ get 'logout' => 'logins#logout'
6
+ end
7
+
8
+ end
@@ -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 = 'http://status.notioneer.com/'
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
 
@@ -5,7 +5,7 @@ module AuthRocket
5
5
  module ClassMethods
6
6
 
7
7
  def parse_credentials(creds)
8
- creds.with_indifferent_access.except :jwt_secret
8
+ creds.with_indifferent_access.except :loginrocket_url, :jwt_secret
9
9
  end
10
10
 
11
11
  end
@@ -1,3 +1,3 @@
1
1
  module AuthRocket
2
- VERSION = '2.1.1'
2
+ VERSION = '2.4.1'
3
3
  end
@@ -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,11 @@
1
+ module AuthRocket
2
+ class JwtKey < Resource
3
+ crud :all, :find, :create, :delete
4
+
5
+ belongs_to :realm
6
+
7
+ attr :algo, :key, :use
8
+ attr :expired # readonly
9
+
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ require_relative '../authrocket'
2
+
3
+ %w(engine).each do |f|
4
+ require_relative "rails/#{f}"
5
+ 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
@@ -0,0 +1,13 @@
1
+ module AuthRocket
2
+ class Engine < ::Rails::Engine
3
+
4
+ initializer "authrocket.helpers" do
5
+ require_relative 'controller_helper'
6
+
7
+ ActiveSupport.on_load(:action_controller) do
8
+ include AuthRocket::ControllerHelper
9
+ end
10
+ end
11
+
12
+ end
13
+ end
@@ -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 :jwt_secret # readonly
16
+ attr :jwt_key # readonly
17
+ attr :jwt_secret # readonly, deprecated
16
18
  attr :jwt_data # deprecated
17
19
 
18
20
 
@@ -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
- jwt, _ = JWT.decode token, secret, true, algorithm: 'HS256'
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
@@ -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.1.1
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: 2017-01-07 00:00:00.000000000 Z
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: '2.0'
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: '2.0'
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
- rubyforge_project:
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