Class: Hitch::DeviceActivation
- Inherits:
-
Object
- Object
- Hitch::DeviceActivation
- Includes:
- UriValidation
- Defined in:
- app/models/hitch/device_activation.rb
Overview
What the /activate confirmation screen may honestly say about the client behind a pending device grant.
The device flow delivers nothing to a redirect_uri, so the consent screen's verified signal — the host the authorization code is actually sent to — does not survive the trip. What replaces it is a vouching rule: a device grant is approvable only for a client somebody real vouches for, and only the voucher's word is displayed. A CIMD client is branded by its client_id's own URL host, earned by serving the document there. A confidential client is branded by the name the operator chose when they registered it at a console. A client that only ever vouched for itself through open registration — even one DCR issued a secret — is the §5.4 phishing shape: the mint endpoint refuses it, and this object independently refuses to verify it, so the guarantee holds whichever door a grant came through.
CIMD resolution happens here, with the signed-in approver as the rate-limit actor — never at the mint endpoint, which has no actor.
Instance Attribute Summary collapse
-
#grant ⇒ Object
readonly
Returns the value of attribute grant.
Instance Method Summary collapse
- #audit_client_name ⇒ Object
- #display_client_name ⇒ Object
-
#initialize(grant, principal:) ⇒ DeviceActivation
constructor
A new instance of DeviceActivation.
-
#localhost_only_client? ⇒ Boolean
The consent screen's own-computer warning, carried over: a client whose every declared redirect is loopback http runs on the user's machine, not at the host it displays as.
-
#operator_registered? ⇒ Boolean
A confidential client the operator registered at a console; its display name is the operator's word, and the view says whose word it is.
- #scopes ⇒ Object
-
#unverified? ⇒ Boolean
The live voucher must still exist and must agree with the immutable authentication posture recorded at mint.
Constructor Details
#initialize(grant, principal:) ⇒ DeviceActivation
Returns a new instance of DeviceActivation.
27 28 29 30 |
# File 'app/models/hitch/device_activation.rb', line 27 def initialize(grant, principal:) @grant = grant @principal = principal end |
Instance Attribute Details
#grant ⇒ Object (readonly)
Returns the value of attribute grant.
32 33 34 |
# File 'app/models/hitch/device_activation.rb', line 32 def grant @grant end |
Instance Method Details
#audit_client_name ⇒ Object
64 65 66 |
# File 'app/models/hitch/device_activation.rb', line 64 def audit_client_name document&.client_name || client&.client_name || "Unknown" end |
#display_client_name ⇒ Object
55 56 57 58 59 60 61 62 |
# File 'app/models/hitch/device_activation.rb', line 55 def display_client_name return client.client_name if operator_registered? # hostname, not host: URI#host keeps IPv6 brackets, which would # defeat a client_names entry keyed on the bare address. host = URI.parse(grant.client_id).hostname Hitch.configuration.client_label(host) || host end |
#localhost_only_client? ⇒ Boolean
The consent screen's own-computer warning, carried over: a client whose every declared redirect is loopback http runs on the user's machine, not at the host it displays as.
71 72 73 74 |
# File 'app/models/hitch/device_activation.rb', line 71 def localhost_only_client? declared = document&.redirect_uris declared.present? && declared.all? { |uri| loopback_http_uri?(uri) } end |
#operator_registered? ⇒ Boolean
A confidential client the operator registered at a console; its display name is the operator's word, and the view says whose word it is.
50 51 52 53 |
# File 'app/models/hitch/device_activation.rb', line 50 def operator_registered? grant.token_endpoint_auth_method == "client_secret_basic" && client&.operator_registered_confidential_client? end |
#scopes ⇒ Object
76 77 78 |
# File 'app/models/hitch/device_activation.rb', line 76 def scopes @scopes ||= grant.scopes.to_s.split(/\s+/) end |
#unverified? ⇒ Boolean
The live voucher must still exist and must agree with the immutable authentication posture recorded at mint. That refuses both directions of a registration race: a public/CIMD grant cannot borrow an operator registration, and a confidential grant cannot fall back to CIMD after its operator registration disappears.
39 40 41 42 43 44 45 |
# File 'app/models/hitch/device_activation.rb', line 39 def unverified? case grant.token_endpoint_auth_method when "client_secret_basic" then !operator_registered? when "none" then document.nil? else true end end |