authrocket 2.4.1 → 3.0.0

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
2
  SHA256:
3
- metadata.gz: 8806b7bb2d33bd8f45cdc90f2b3dddac5e1aab15956b54dd6eb5ae435b636287
4
- data.tar.gz: 60a546549c2ec30ecfdaee1c9a391bfb0d747909346e78eb5a1ff274f2b9dbc4
3
+ metadata.gz: 138d4247bae61aa6ac0c171621a438d8b6d47db7de2a2cc9b7ad61ea7df0784d
4
+ data.tar.gz: c83fe483dbdaf4d0e0152972c42e76b17ec5133114cae0b1081c082b74883cee
5
5
  SHA512:
6
- metadata.gz: edb91edfa64deceb771134a84ad3b63719cd7e5a363e9485150d4361cac8162912da86adf9f3a93eb9214901c923f21df19a8c356a8c7085ca47c76f018c484a
7
- data.tar.gz: 22031370adff34599aaf30d78a4d075fd023aea255e1c3bb41d014fcc4fee2a157284bcf691ca1fdceed2cdaba844fa9707b980cf290b842059245da9621cef7
6
+ metadata.gz: 89f83a485b4c382eba642e16d9617bd0107833ee79abe6379fb3126a939f3515becda60182fc886a7976e739f1b45d6a60918ad82dc91cd6960fb8cebb306063
7
+ data.tar.gz: d1b32f8ac525755fa7cfed8e06846c6aa6d58e124ba775ecde423901fcc7157db09f65553e27b670f2ab7ec596621d2c033ecbaab2e7da104369955cea2895a2
@@ -1,6 +1,22 @@
1
- #### 2.4.1
1
+ #### 3.0.0
2
2
 
3
- - Require ncore 2.2.2+
3
+ - NOTE: This version includes breaking changes.
4
+ It is only compatible with AuthRocket 2. Use gem version '~> 2.0' with AuthRocket 1.
5
+ - Refactor Rails integration
6
+ - Update resources for AuthRocket 2
7
+ - Add: ClientApp, Connection, Domain, Invitation, NamedPermission, Oauth2Session, ResourceLink, Token
8
+ - Remove: LoginPolicy, UserToken,
9
+ - Rename: AppHook -> Hook
10
+ - Update most others
11
+ - Support LR JWKS - retrieve RS256 key when key not pre-configured
12
+ - Update auth/credentials
13
+ - Rename ENV AUTHROCKET_JWT_SECRET -> AUTHROCKET_JWT_KEY
14
+ - Rename ENV AUTHROCKET_LOGIN_URL -> LOGINROCKET_URL
15
+ - Rename AuthRocket::API.credentials :jwt_secret -> :jwt_key
16
+ - Update ncore to v3
17
+ - `#errors` is now always an ActiveModel::Errors instance
18
+ - <exception>#errors is now an ActiveModel::Errors for all applicable exceptions
19
+ - Require Ruby >= 2.3
4
20
 
5
21
  #### 2.4.0
6
22
 
data/README.md CHANGED
@@ -8,7 +8,7 @@ This gem works with both Rails and plain Ruby. It will auto-detect Rails and ena
8
8
 
9
9
  ## Usage - Rails
10
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.
11
+ AuthRocket includes a streamlined Rails integration that automatically handles logins and logouts. For a new app, we highly recommend this.
12
12
 
13
13
  Note: The streamlined integration requires Rails 4.2+.
14
14
 
@@ -16,47 +16,55 @@ To your Gemfile, add:
16
16
 
17
17
  gem 'authrocket', require: 'authrocket/rails'
18
18
 
19
- Then ensure the following environment variables are set:
19
+ Then ensure the following environment variable is set:
20
20
 
21
- AUTHROCKET_LOGIN_URL = https://sample.e1.loginrocket.com/
22
- AUTHROCKET_JWT_SECRET = jsk_SAMPLE
21
+ LOGINROCKET_URL = https://sample.e2.loginrocket.com/
22
+
23
+ If you've changed the default JWT key type to HS256, you'll also need this variable:
24
+
25
+ AUTHROCKET_JWT_KEY = jsk_SAMPLE
23
26
 
24
27
  If you plan to access the AuthRocket API as well, you'll need these variables too:
25
28
 
26
- AUTHROCKET_API_KEY = ko_SAMPLE
27
- AUTHROCKET_URL = https://api-e1.authrocket.com/v1
28
- AUTHROCKET_REALM = rl_SAMPLE # optional
29
+ AUTHROCKET_API_KEY = ks_SAMPLE
30
+ AUTHROCKET_URL = https://api-e2.authrocket.com/v2
31
+ AUTHROCKET_REALM = rl_SAMPLE # optional
29
32
 
30
33
  Finally, add a `before_action` command to any/all controllers or actions that should require a login.
31
34
 
32
35
  For example, to protect your entire app:
33
36
 
34
37
  class ApplicationController < ActionController::Base
35
- before_action :require_valid_token
38
+ before_action :require_login
36
39
  end
37
40
 
38
41
  Selectively exempt certain actions or controllers using the standard `skip_before_action` method:
39
42
 
40
- class ContactUsController < ActionController::Base
41
- skip_before_action :require_valid_token, only: [:new, :create]
43
+ class ContactUsController < ApplicationController
44
+ skip_before_action :require_login, only: [:new, :create]
42
45
  end
43
46
 
44
- Helpers are provided to create login, signup, and logout links:
47
+ Helpers are provided to create login, signup, and logout links, as well as for users to manage their profile:
45
48
 
46
49
  <%= link_to 'Login', ar_login_url %>
47
50
  <%= link_to 'Signup', ar_signup_url %>
48
51
  <%= link_to 'Logout', logout_path %>
52
+ <%= link_to 'Manage Profile', ar_profile_url %>
49
53
 
50
- Both the current session and user are available to your controllers and views:
54
+ Both the current Session and User are available to your controllers and views:
51
55
 
52
56
  current_session # => AuthRocket::Session
53
57
  current_user # => AuthRocket::User
54
58
 
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).
59
+ The current Membership and Org (account) are accessible through those helpers as well.
60
+
61
+ current_membership
62
+ current_org
56
63
 
57
- current_user.memberships
58
- current_user.memberships.first.org
59
- current_user.orgs
64
+ If a user is a member of more than one org (account), `current_membership` and `current_org` will be reflect the currently selected account. Additional helpers are available to provide appropriate links to your users:
65
+
66
+ <%= link_to 'Manage current account', ar_account_url %>
67
+ <%= link_to 'Switch accounts', ar_accounts_url %>
60
68
 
61
69
  See below for customization details.
62
70
 
@@ -73,14 +81,13 @@ In your Gemfile, add:
73
81
  Then set the following environment variables:
74
82
 
75
83
  # 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
84
+ AUTHROCKET_API_KEY = ks_SAMPLE
85
+ AUTHROCKET_URL = https://api-e2.authrocket.com/v2 # must match your account's provisioned cluster
86
+ AUTHROCKET_REALM = rl_SAMPLE # optional
79
87
  #
80
88
  # If using JWT-verification of AuthRocket's login tokens:
81
- AUTHROCKET_JWT_SECRET = jsk_SAMPLE
89
+ AUTHROCKET_JWT_KEY = SAMPLE
82
90
 
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
91
 
85
92
 
86
93
 
@@ -88,30 +95,30 @@ If you're using either Hosted LoginRocket or authrocket.js to manage logins, see
88
95
 
89
96
  By default, AuthRocket automatically loads credentials from environment variables. This is optimal for any 12-factor deployment. Supported variables are:
90
97
 
91
- `AUTHROCKET_API_KEY = ko_SAMPLE`
98
+ `AUTHROCKET_API_KEY = ks_SAMPLE`
92
99
  Your AuthRocket API key. Required to use the API (but not if only performing JWT verification of login tokens).
93
100
 
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'.
101
+ `AUTHROCKET_JWT_KEY = SAMPLE`
102
+ Used to perform JWT signing verification of login tokens. Not required if validating all tokens using the API instead. Also not required if LOGINROCKET_URL is set and RS256 keys are being used, as public keys will be auto-retrieved. This is a realm-specific value, so like `AUTHROCKET_REALM`, set it on a per-use basis if using multiple realms.
99
103
 
100
104
  `AUTHROCKET_REALM = rl_SAMPLE`
101
105
  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
106
 
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.
107
+ `AUTHROCKET_URL = https://api-e2.authrocket.com/v2`
108
+ The URL of the AuthRocket API server. This may vary depending on which cluster your service is provisioned on.
109
+
110
+ `LOGINROCKET_URL = https://sample.e2.loginrocket.com/`
111
+ The LoginRocket URL for your Connected App. Used by the streamlined Rails integration (for redirects) and for auto-retrieval of RS256 JWT keys (if AUTHROCKET_JWT_KEY is not set). 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'.
105
112
 
106
113
 
107
114
  It's also possible to configure AuthRocket using a Rails initializer (or other initialization code).
108
115
 
109
116
  AuthRocket::Api.credentials = {
110
- api_key: 'ko_SAMPLE',
111
- jwt_secret: 'jsk_SAMPLE',
112
- loginrocket_url: 'https://sample.e1.loginrocket.com/',
117
+ api_key: 'ks_SAMPLE',
118
+ jwt_key: 'SAMPLE',
119
+ loginrocket_url: 'https://sample.e2.loginrocket.com/',
113
120
  realm: 'rl_SAMPLE',
114
- url: 'https://api-e1.authrocket.com/v1'
121
+ url: 'https://api-e2.authrocket.com/v2'
115
122
  }
116
123
 
117
124
 
@@ -121,53 +128,56 @@ It's also possible to configure AuthRocket using a Rails initializer (or other i
121
128
  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.
122
129
 
123
130
 
124
- #### The default post-login path
131
+ #### Logins
132
+
133
+ The Rails integration handles logins on any path by detecting the presence of `?token=...`. It will process the login and then immediately redirect back to the same path without `?token=`; this helps prevent browsers and bookmarks from accidentally saving or caching the login token.
134
+
135
+ Likewise, the built-in handler for `before_action :require_login` will automatically redirect to LoginRocket when the user is not currently logged in. `?redirect_uri=<current_path>` will be automatically included so that the user returns to the same place post-login. You can override this behavior by replacing `before_login`.
125
136
 
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).
137
+ # For example, to force the user to always return to "/manage":
138
+ def require_login
139
+ unless current_session
140
+ redirect_to ar_login_url(redirect_uri: "/manage")
141
+ end
142
+ end
127
143
 
128
- This default path may be changed using an initializer.
144
+ AuthRocket will verify the domain + path to redirect to. You can configure this at Realm -> Settings -> Connected Apps -> (edit) -> Login URLs. The first URL listed will be the default, so it should generally be the default "just logged in" path.
129
145
 
130
- Create/edit `config/initializers/authrocket.rb` and add:
146
+ Paths are validated as "equal or more specific". That is, if Login URLs contains "https://my.app/manage", then any path starting with "/manage" will be allowed, but "/other" will not be allowed. If you want to allow any path at your domain, add "https://my.app/" (since "/" will match any path).
131
147
 
132
- ```ruby
133
- AuthRocket::Api.default_login_path = '/manage'
134
- ```
135
148
 
149
+ #### Logouts
136
150
 
137
- #### /login and /logout routes
151
+ ##### The default post-logout path
138
152
 
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:
153
+ Upon logout, the user will be returned to the root path ("/").
154
+
155
+ This default path may be changed using an initializer. Create/edit `config/initializers/authrocket.rb` and add:
156
+
157
+ AuthRocket::Api.post_logout_path = '/other'
158
+
159
+
160
+ ##### /logout route
161
+
162
+ The default route for logout is `/logout`. To overrideis, add an initializer for AuthRocket (eg: `config/initializers/authrocket.rb`) and add:
140
163
 
141
164
  AuthRocket::Api.use_default_routes = false
142
165
 
143
166
  Then add your own routes to `config/routes.rb`:
144
167
 
145
- get 'mylogin' => 'logins#login'
146
168
  get 'mylogout' => 'logins#logout'
147
169
 
148
170
 
149
- #### The login controller
171
+ ##### The logout action
150
172
 
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.
173
+ AuthRocket's default login controller automatically sets a logout message using `flash`.
152
174
 
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:
175
+ You may customize this, or other logout behavior, by creating your own LoginsController and inherit from AuthRocket's controller:
154
176
 
155
177
  class LoginsController < AuthRocket::ArController
156
- def login
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
163
- end
164
- # else if login failed, a redirect to LoginRocket happens automatically
165
- end
166
-
167
178
  def logout
168
179
  super
169
- # Change the path and/or the message.
170
- redirect_to root_path, notice: 'You have been logged out.'
180
+ flash[:notice] = 'You have been logged out.'
171
181
  end
172
182
  end
173
183
 
@@ -185,7 +195,7 @@ If you're not using the streamlined Rails integration, you'll need to verify the
185
195
  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:
186
196
 
187
197
  def current_user
188
- @_current_user ||= AuthRocket::Session.from_token(session[:ar_token]).try(:user)
198
+ @_current_user ||= AuthRocket::Session.from_token(session[:ar_token])&.user
189
199
  end
190
200
 
191
201
  `from_token` returns `nil` if the token is missing, expired, or otherwise invalid.
@@ -196,10 +206,10 @@ AuthRocket's login tokens use the JWT standard and are cryptographically signed.
196
206
  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
207
 
198
208
  def current_user
199
- @_current_user ||= AuthRocket::Session.retrieve(session[:ar_token]).try(:user)
209
+ @_current_user ||= AuthRocket::Session.retrieve(session[:ar_token])&.user
200
210
  end
201
211
 
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.
212
+ For better performance (and to avoid API rate limits), you will want to cache the results of the API call for 3-15 minutes.
203
213
 
204
214
 
205
215
  #### Initial login
@@ -1,44 +1,22 @@
1
1
  class AuthRocket::ArController < ::ApplicationController
2
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
3
+ before_action :require_login, only: []
4
+ # ensure :require_login is known so it can be skipped
5
+ skip_before_action :require_login
6
6
  # in case it's globally applied to ApplicationController
7
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
8
 
24
9
  def logout
25
- if current_session && current_session.id =~ /^kss_/ && AuthRocket::Api.credentials[:api_key]
26
- AuthRocket::Session.delete current_session.id
10
+ if AuthRocket::Api.post_logout_path
11
+ uri = Addressable::URI.parse full_url_for
12
+ uri.path = AuthRocket::Api.post_logout_path
13
+ redirect_to ar_logout_url(redirect_uri: uri.to_s)
14
+ else
15
+ redirect_to ar_logout_url
27
16
  end
28
- session[:ar_token] = nil
29
- # redirect in the child
30
- end
31
-
32
-
33
- private
17
+ # set flash message in the child
34
18
 
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
19
+ session[:ar_token] = nil
42
20
  end
43
21
 
44
22
  end
@@ -1,15 +1,8 @@
1
1
  class LoginsController < AuthRocket::ArController
2
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
3
  def logout
11
4
  super
12
- redirect_to '/', notice: 'You have been logged out.'
5
+ flash[:notice] = 'You have been logged out.'
13
6
  end
14
7
 
15
8
  end
@@ -18,10 +18,11 @@ Gem::Specification.new do |gem|
18
18
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
19
  gem.require_paths = ["lib"]
20
20
 
21
- gem.required_ruby_version = '>= 1.9'
21
+ gem.required_ruby_version = '>= 2.3'
22
22
 
23
- gem.add_dependency 'ncore', '>= 2.2.2', '< 3'
24
- gem.add_dependency 'jwt', '~> 1.5.0'
23
+ gem.add_dependency 'addressable', '~> 2.5'
24
+ gem.add_dependency 'ncore', '~> 3.0'
25
+ gem.add_dependency 'jwt', '~> 2.1'
25
26
 
26
27
  gem.add_development_dependency "bundler", "~> 1.3"
27
28
  gem.add_development_dependency "rake"
@@ -1,7 +1,6 @@
1
1
  Rails.application.routes.draw do
2
2
 
3
3
  if AuthRocket::Api.use_default_routes
4
- get 'login' => 'logins#login'
5
4
  get 'logout' => 'logins#logout'
6
5
  end
7
6
 
@@ -1,3 +1,4 @@
1
+ require 'addressable/uri'
1
2
  require 'ncore'
2
3
  require 'jwt'
3
4
 
@@ -5,7 +6,27 @@ require 'jwt'
5
6
  require "authrocket/api/#{f}"
6
7
  end
7
8
 
8
- %w(app_hook auth_provider credential event jwt_key login_policy membership notification org realm session user user_token).each do |f|
9
+ %w(
10
+ auth_provider
11
+ client_app
12
+ connection
13
+ credential
14
+ domain
15
+ event
16
+ hook
17
+ invitation
18
+ jwt_key
19
+ membership
20
+ named_permission
21
+ notification
22
+ oauth2_session
23
+ org
24
+ realm
25
+ resource_link
26
+ session
27
+ token
28
+ user
29
+ ).each do |f|
9
30
  require "authrocket/#{f}"
10
31
  end
11
32
 
@@ -14,19 +14,21 @@ 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'] || ENV['AUTHROCKET_JWT_SECRET']
17
+ elsif ENV['AUTHROCKET_API_KEY']
18
18
  self.credentials = {
19
19
  api_key: ENV['AUTHROCKET_API_KEY'],
20
- account: ENV['AUTHROCKET_ACCOUNT'],
21
20
  realm: ENV['AUTHROCKET_REALM'],
22
- jwt_secret: ENV['AUTHROCKET_JWT_SECRET']
21
+ service: ENV['AUTHROCKET_SERVICE'],
23
22
  }
24
23
  else
25
24
  self.credentials = {}
26
25
  end
27
26
 
28
- if ENV['AUTHROCKET_LOGIN_URL']
29
- self.credentials[:loginrocket_url] = ENV['AUTHROCKET_LOGIN_URL']
27
+ if ENV['AUTHROCKET_JWT_KEY']
28
+ self.credentials[:jwt_key] ||= ENV['AUTHROCKET_JWT_KEY']
29
+ end
30
+ if ENV['LOGINROCKET_URL']
31
+ self.credentials[:loginrocket_url] = ENV['LOGINROCKET_URL']
30
32
  end
31
33
 
32
34
  self.debug = false
@@ -34,29 +36,26 @@ module AuthRocket
34
36
  self.strict_attributes = true
35
37
 
36
38
 
39
+ self.i18n_scope = :authrocket
40
+
37
41
  self.instrument_key = 'request.authrocket'
38
42
 
39
43
  self.status_page = 'https://status.authrocket.com/'
40
44
 
41
- self.auth_header_prefix = 'X-Authrocket'
45
+ self.auth_header_prefix = 'Authrocket'
42
46
 
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}"}
47
+ self.credentials_error_message = %Q{Missing API credentials or URL. Set default credentials using "AuthRocket::Api.credentials = {api_key: YOUR_API_KEY, url: AR_API_URL}"}
44
48
 
45
49
 
46
50
  mattr_accessor :use_default_routes
47
51
  self.use_default_routes = true
48
52
 
49
- mattr_accessor :default_login_path
50
- self.default_login_path = '/'
53
+ mattr_accessor :post_logout_path
54
+ self.post_logout_path = '/'
51
55
  end
52
56
 
53
57
 
54
58
  class << self
55
- # makes AuthRocket::Realm.model_name.param_key do the right thing
56
- def use_relative_model_naming?
57
- true
58
- end
59
-
60
59
 
61
60
  private
62
61
 
@@ -69,13 +68,13 @@ module AuthRocket
69
68
  [url.password, url.user].each do |part|
70
69
  case part
71
70
  when /^jsk_/
72
- o[:jwt_secret] = part
73
- when /^k(ey|o)_/
71
+ o[:jwt_key] = part
72
+ when /^k(ey|s)_/
74
73
  o[:api_key] = part
75
- when /^org_/
76
- o[:account] = part
77
74
  when /^rl_/
78
75
  o[:realm] = part
76
+ when /^svc_/
77
+ o[:service] = part
79
78
  end
80
79
  end
81
80
  url.user = url.password = nil