masks 0.12.1 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,7 +11,7 @@ module Masks
11
11
  end
12
12
 
13
13
  if respond_to?(:rescue_from) && method_defined?(:render)
14
- rescue_from Masks::Rails::Cache::Unavailable, with: :masks_cache_unavailable
14
+ rescue_from Masks::Client::Unavailable, with: :masks_cache_unavailable
15
15
  end
16
16
  end
17
17
 
@@ -84,10 +84,10 @@ module Masks
84
84
  Masks::Client::Claims::ORGANIZATIONS
85
85
  ].freeze
86
86
 
87
- def masks_identity_from(tokens)
87
+ def masks_identity_from(tokens, nonce: nil, max_age: nil)
88
88
  return nil if tokens.id_token.nil?
89
89
 
90
- masks_session.identity(tokens)
90
+ masks_session.identity(tokens, nonce: nonce, max_age: max_age)
91
91
  end
92
92
 
93
93
  def masks_forget
@@ -163,7 +163,7 @@ module Masks
163
163
 
164
164
  renewal = begin
165
165
  masks_cache.renew(masks_config.issuer_for(request).to_s, spent) { masks_renewal(spent) }
166
- rescue Masks::Rails::Cache::Unavailable
166
+ rescue Masks::Client::Unavailable
167
167
  Masks::Rails::Renewal.unreachable
168
168
  end
169
169
 
@@ -194,12 +194,15 @@ module Masks
194
194
  held.merge(profile.slice(*IDENTITY))
195
195
  end
196
196
 
197
- def masks_login_url(return_to: nil, organization: nil, privilege: nil)
197
+ # Where to send someone to sign in. +max_age+ asks masks for a sign-in no
198
+ # older than that many seconds; an older one is refused at the callback.
199
+ def masks_login_url(return_to: nil, organization: nil, privilege: nil, max_age: nil)
198
200
  path = Masks::Rails::Engine.routes.url_helpers.start_path
199
201
  query = {
200
202
  "return_to" => masks_local_path(return_to),
201
203
  "organization" => Masks::Client::Session.organization_key(organization),
202
- "privilege" => Array(privilege).join(" ").presence
204
+ "privilege" => Array(privilege).join(" ").presence,
205
+ "max_age" => (max_age.to_i if max_age.to_i.positive?)
203
206
  }.compact
204
207
 
205
208
  query.empty? ? path : "#{path}?#{URI.encode_www_form(query)}"
@@ -237,7 +240,7 @@ module Masks
237
240
  Masks::Rails::Renewal.renewed(refreshed, masks_refreshed_identity(refreshed))
238
241
  rescue Masks::Client::Unregistered
239
242
  Masks::Rails::Renewal.unregistered
240
- rescue Masks::Client::Rejected => e
243
+ rescue Masks::Client::Refused => e
241
244
  e.status.to_i >= 500 || e.status.to_i == 429 ? Masks::Rails::Renewal.unreachable : Masks::Rails::Renewal.refused
242
245
  rescue Masks::Client::Error
243
246
  Masks::Rails::Renewal.unreachable
@@ -271,7 +274,7 @@ module Masks
271
274
 
272
275
  if masks_asked_already?(session.delete(STEPPED_UP), missing)
273
276
  raise Masks::Client::Forbidden.new(
274
- "insufficient_scope", "this account does not hold the #{missing.join(' and ')} privilege",
277
+ *Masks::Client.failure("no_privilege", missing.join(" and ")),
275
278
  scope: missing.flat_map { |name| masks_config.privilege(name).scopes }.join(" ")
276
279
  )
277
280
  end
@@ -326,7 +329,7 @@ module Masks
326
329
  response.headers["Retry-After"] = "5"
327
330
 
328
331
  if masks_wants_json?
329
- render json: { "error" => "temporarily_unavailable", "error_description" => error.message },
332
+ render json: { "error" => "temporarily_unavailable", "error_description" => error.description },
330
333
  status: :service_unavailable
331
334
  else
332
335
  render plain: "Signing in is unavailable right now. Try again in a moment.", status: :service_unavailable
@@ -1,8 +1,6 @@
1
1
  module Masks
2
2
  module Rails
3
3
  class Cache
4
- class Unavailable < Masks::Client::Error; end
5
-
6
4
  CLAIM = 30
7
5
  RESULT = 60
8
6
  WAIT = 0.05
@@ -41,7 +39,7 @@ module Masks
41
39
 
42
40
  kept = begin
43
41
  write(self.class.key("departed", issuer, kind, value), self.class.now, expires_in: DEPARTURE)
44
- rescue Unavailable
42
+ rescue Masks::Client::Unavailable
45
43
  false
46
44
  end
47
45
 
@@ -49,7 +47,7 @@ module Masks
49
47
 
50
48
  forgotten { delete(self.class.key("logout", issuer, logout.jti)) }
51
49
 
52
- raise Unavailable, "the cache did not keep that logout"
50
+ raise Masks::Client::Unavailable, "the cache did not keep that logout"
53
51
  end
54
52
 
55
53
  def departed?(issuer, identity, since:)
@@ -87,7 +85,7 @@ module Masks
87
85
  return true if write(key, 1, unless_exist: true, expires_in: expires_in)
88
86
  return false unless read(key).nil?
89
87
 
90
- raise Unavailable, "the cache neither kept that key nor holds it, so it is not answering"
88
+ raise Masks::Client::Unavailable, "the cache neither kept that key nor holds it, so it is not answering"
91
89
  end
92
90
 
93
91
  def read(key)
@@ -104,15 +102,15 @@ module Masks
104
102
 
105
103
  def reached
106
104
  yield
107
- rescue Unavailable
105
+ rescue Masks::Client::Unavailable
108
106
  raise
109
107
  rescue StandardError => e
110
- raise Unavailable, "the cache could not be reached (#{e.class})"
108
+ raise Masks::Client::Unavailable, Masks::Client.saying("store_unreachable")
111
109
  end
112
110
 
113
111
  def forgotten
114
112
  yield
115
- rescue Unavailable
113
+ rescue Masks::Client::Unavailable
116
114
  nil
117
115
  end
118
116
 
@@ -1,7 +1,11 @@
1
1
  module Masks
2
2
  module Rails
3
3
  class Configuration
4
- class Unconfigured < Masks::Client::Error; end
4
+ class Unconfigured < Masks::Client::Error
5
+ def initialize(description)
6
+ super("not_configured", description)
7
+ end
8
+ end
5
9
 
6
10
  Privilege = Struct.new(:name, :scopes, :roles, :organization, keyword_init: true)
7
11
  PRIVILEGE_KEYS = %w[scope role organization].freeze
@@ -6,7 +6,7 @@ module Masks
6
6
  include Masks::Rails::Privileged
7
7
 
8
8
  included do
9
- rescue_from Masks::Client::ReplayUnavailable, with: :masks_unavailable if respond_to?(:rescue_from)
9
+ rescue_from Masks::Client::Unavailable, with: :masks_unavailable if respond_to?(:rescue_from)
10
10
  end
11
11
 
12
12
  def masks_resource
@@ -25,7 +25,9 @@ module Masks
25
25
  def masks_authenticate(scope: nil, role: nil, organization: nil)
26
26
  masks_resource.authenticate(request.authorization, scope: scope, role: role, organization: organization,
27
27
  **masks_proof)
28
- rescue Masks::Client::Unauthenticated
28
+ rescue Masks::Client::InvalidToken => e
29
+ raise unless e.missing?
30
+
29
31
  nil
30
32
  end
31
33
 
@@ -34,15 +36,15 @@ module Masks
34
36
  end
35
37
 
36
38
  def masks_challenge(error)
37
- error = Masks::Client::Unauthorized.new(error.to_s) unless error.is_a?(Masks::Client::Challenge)
39
+ error = Masks::Client::InvalidToken.new(error.to_s) unless error.is_a?(Masks::Client::Error)
38
40
 
39
41
  response.headers["WWW-Authenticate"] = masks_resource.challenge(error)
40
42
  response.headers["Cache-Control"] = "no-store"
41
43
 
42
44
  render json: {
43
- "error" => error.code || "invalid_token",
45
+ "error" => error.code,
44
46
  "error_description" => error.description
45
- }, status: error.status
47
+ }, status: error.status || 401
46
48
  end
47
49
 
48
50
  def masks_unavailable
@@ -72,7 +74,7 @@ module Masks
72
74
 
73
75
  @masks_token_claims = claims
74
76
  true
75
- rescue Masks::Client::Challenge => e
77
+ rescue Masks::Client::InvalidToken, Masks::Client::Forbidden => e
76
78
  masks_challenge(e)
77
79
  false
78
80
  end
data/lib/masks/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Masks
2
- VERSION = "0.12.1".freeze
2
+ VERSION = "0.13.0".freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: masks
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.1
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - the masks authors
@@ -55,8 +55,10 @@ files:
55
55
  - lib/masks/client/embedded.rb
56
56
  - lib/masks/client/enrollment.rb
57
57
  - lib/masks/client/errors.rb
58
+ - lib/masks/client/failures.rb
58
59
  - lib/masks/client/handshake.rb
59
60
  - lib/masks/client/http.rb
61
+ - lib/masks/client/id_token.rb
60
62
  - lib/masks/client/introspection.rb
61
63
  - lib/masks/client/issuer.rb
62
64
  - lib/masks/client/key.rb