Class: Himari::ClientRegistration
- Inherits:
-
Object
- Object
- Himari::ClientRegistration
- Defined in:
- lib/himari/client_registration.rb
Constant Summary collapse
- LOOPBACK_HOSTS =
Loopback hosts whose redirect_uri port may be relaxed (RFC 8252 §7.3, draft-ietf-oauth-v2-1-15 §8.4.2). Addressable returns IPv6 hosts bracketed.
%w[127.0.0.1 [::1] localhost].freeze
- IMPLICIT_SCOPES =
Scopes Himari itself acts on; recognised for every client regardless of the configured scopes list, so a client need not enumerate them to use OIDC or obtain a refresh token.
%w[openid offline_access].freeze
Instance Attribute Summary collapse
-
#id ⇒ Object
readonly
Returns the value of attribute id.
-
#ignore_localhost_redirect_uri_port ⇒ Object
readonly
Returns the value of attribute ignore_localhost_redirect_uri_port.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#preferred_key_group ⇒ Object
readonly
Returns the value of attribute preferred_key_group.
-
#redirect_uris ⇒ Object
readonly
Returns the value of attribute redirect_uris.
-
#require_pkce ⇒ Object
readonly
Returns the value of attribute require_pkce.
-
#scopes ⇒ Object
readonly
Returns the value of attribute scopes.
-
#skip_consent ⇒ Object
readonly
Returns the value of attribute skip_consent.
Instance Method Summary collapse
- #as_log ⇒ Object
- #confidential? ⇒ Boolean
-
#filter_scopes(requested) ⇒ Object
Drop requested scopes this client does not recognise.
-
#initialize(id:, redirect_uris:, name: nil, secret: nil, secret_hash: nil, preferred_key_group: nil, require_pkce: false, confidential: true, ignore_localhost_redirect_uri_port: true, skip_consent: false, scopes: IMPLICIT_SCOPES) ⇒ ClientRegistration
constructor
A new instance of ClientRegistration.
- #match_hint?(id: nil) ⇒ Boolean
- #match_secret?(given_secret) ⇒ Boolean
-
#redirect_uri_covers?(given) ⇒ Boolean
True when one of the registered redirect_uris covers the given (request) redirect_uri.
- #secret_hash ⇒ Object
Constructor Details
#initialize(id:, redirect_uris:, name: nil, secret: nil, secret_hash: nil, preferred_key_group: nil, require_pkce: false, confidential: true, ignore_localhost_redirect_uri_port: true, skip_consent: false, scopes: IMPLICIT_SCOPES) ⇒ ClientRegistration
Returns a new instance of ClientRegistration.
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/himari/client_registration.rb', line 16 def initialize(id:, redirect_uris:, name: nil, secret: nil, secret_hash: nil, preferred_key_group: nil, require_pkce: false, confidential: true, ignore_localhost_redirect_uri_port: true, skip_consent: false, scopes: IMPLICIT_SCOPES) @name = name @id = id @secret = secret @secret_hash = secret_hash @redirect_uris = redirect_uris @preferred_key_group = preferred_key_group @require_pkce = require_pkce @confidential = confidential @ignore_localhost_redirect_uri_port = ignore_localhost_redirect_uri_port @skip_consent = @scopes = (Array(scopes) | IMPLICIT_SCOPES).freeze raise ArgumentError, "name starts with '_' is reserved" if @name&.start_with?('_') raise ArgumentError, "either secret or secret_hash must be present" if confidential && !@secret && !@secret_hash end |
Instance Attribute Details
#id ⇒ Object (readonly)
Returns the value of attribute id.
33 34 35 |
# File 'lib/himari/client_registration.rb', line 33 def id @id end |
#ignore_localhost_redirect_uri_port ⇒ Object (readonly)
Returns the value of attribute ignore_localhost_redirect_uri_port.
33 34 35 |
# File 'lib/himari/client_registration.rb', line 33 def ignore_localhost_redirect_uri_port @ignore_localhost_redirect_uri_port end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
33 34 35 |
# File 'lib/himari/client_registration.rb', line 33 def name @name end |
#preferred_key_group ⇒ Object (readonly)
Returns the value of attribute preferred_key_group.
33 34 35 |
# File 'lib/himari/client_registration.rb', line 33 def preferred_key_group @preferred_key_group end |
#redirect_uris ⇒ Object (readonly)
Returns the value of attribute redirect_uris.
33 34 35 |
# File 'lib/himari/client_registration.rb', line 33 def redirect_uris @redirect_uris end |
#require_pkce ⇒ Object (readonly)
Returns the value of attribute require_pkce.
33 34 35 |
# File 'lib/himari/client_registration.rb', line 33 def require_pkce @require_pkce end |
#scopes ⇒ Object (readonly)
Returns the value of attribute scopes.
33 34 35 |
# File 'lib/himari/client_registration.rb', line 33 def scopes @scopes end |
#skip_consent ⇒ Object (readonly)
Returns the value of attribute skip_consent.
33 34 35 |
# File 'lib/himari/client_registration.rb', line 33 def @skip_consent end |
Instance Method Details
#as_log ⇒ Object
72 73 74 |
# File 'lib/himari/client_registration.rb', line 72 def as_log {name: name, id: id, skip_consent: , scopes: scopes} end |
#confidential? ⇒ Boolean
35 36 37 |
# File 'lib/himari/client_registration.rb', line 35 def confidential? @confidential end |
#filter_scopes(requested) ⇒ Object
Drop requested scopes this client does not recognise. OAuth servers are expected to ignore unknown scopes rather than reject the request (draft-ietf-oauth-v2-1 §3.2.2.1); request order is preserved.
68 69 70 |
# File 'lib/himari/client_registration.rb', line 68 def filter_scopes(requested) Array(requested).select { |scope| scopes.include?(scope) } end |
#match_hint?(id: nil) ⇒ Boolean
76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/himari/client_registration.rb', line 76 def match_hint?(id: nil) result = true result &&= if id id == self.id else true end result end |
#match_secret?(given_secret) ⇒ Boolean
43 44 45 46 47 48 49 50 51 52 |
# File 'lib/himari/client_registration.rb', line 43 def match_secret?(given_secret) return false unless confidential? && given_secret if @secret Rack::Utils.secure_compare(@secret, given_secret) else dgst = [secret_hash].pack('H*') Rack::Utils.secure_compare(dgst, Digest::SHA384.digest(given_secret)) end end |
#redirect_uri_covers?(given) ⇒ Boolean
True when one of the registered redirect_uris covers the given (request) redirect_uri. draft-ietf-oauth-v2-1-15 §4.1.3 / RFC 3986 §6.2.1: simple (exact) string comparison, with the loopback-port exception of RFC 8252 §7.3 / draft-v2-1 §8.4.2 applied when enabled. A registered entry may also be a Regexp (operator-supplied via static config), matched against the request URI.
58 59 60 61 62 63 |
# File 'lib/himari/client_registration.rb', line 58 def redirect_uri_covers?(given) given = given.to_s return false if given.empty? redirect_uris.any? { |registered| redirect_uri_match?(registered, given) } end |
#secret_hash ⇒ Object
39 40 41 |
# File 'lib/himari/client_registration.rb', line 39 def secret_hash @secret_hash ||= Digest::SHA384.hexdigest(secret) end |