Class: Clickwrap::Submission
- Inherits:
-
Object
- Object
- Clickwrap::Submission
- Defined in:
- lib/clickwrap/submission.rb
Overview
What came back from the browser: a signed presentation token and the answers to the statements that token declared.
Nothing else. A submission cannot carry a policy key, a document version, a validity date, a retention rule, a subject, an IP address, a user-agent, or a geolocation, because every one of those is a decision the server makes and a form field is not a safe place to keep one. Unknown keys are rejected rather than ignored, so an attempt to smuggle one in fails loudly instead of silently doing nothing and looking like it worked.
Constant Summary collapse
- ENVELOPE_KEY =
:clickwrap_submission- ENVELOPE_KEYS =
%w[presentation_token answers].freeze
- REFUSED_KEYS =
Names a client must never be able to set. They exist as a check rather than a filter: a request containing one is a request worth failing.
%w[ policy policy_key policy_revision revision document document_version version valid_from valid_until expires_at retention retain_until subject subject_id actor actor_id tenant ip_address remote_ip browser_user_agent user_agent ip_geolocation geolocation latitude longitude resolver recorded_at server_observed_ip_address capture_channel authentication_method ].freeze
- MAX_ANSWER_LENGTH =
The longest an answer can be: generous for any declared choice name, far too short for smuggled prose or a payload.
120
Instance Attribute Summary collapse
-
#answers ⇒ Object
readonly
Returns the value of attribute answers.
-
#presentation_token ⇒ Object
readonly
Returns the value of attribute presentation_token.
Class Method Summary collapse
- .affirmative?(value) ⇒ Boolean
-
.from_params(params, key: ENVELOPE_KEY) ⇒ Object
Reads the generated envelope out of controller params.
- .missing_envelope_message(key) ⇒ Object
Instance Method Summary collapse
- #answer_for(statement_key) ⇒ Object
- #answered?(statement_key) ⇒ Boolean
-
#initialize(presentation_token:, answers: {}) ⇒ Submission
constructor
A new instance of Submission.
-
#manifest ⇒ Object
Deliberately not memoized: a Submission is frozen the moment it is built, so an instance variable written on first use would raise.
- #to_h ⇒ Object
Constructor Details
#initialize(presentation_token:, answers: {}) ⇒ Submission
Returns a new instance of Submission.
33 34 35 36 37 |
# File 'lib/clickwrap/submission.rb', line 33 def initialize(presentation_token:, answers: {}) @presentation_token = presentation_token @answers = normalize_answers(answers) freeze end |
Instance Attribute Details
#answers ⇒ Object (readonly)
Returns the value of attribute answers.
31 32 33 |
# File 'lib/clickwrap/submission.rb', line 31 def answers @answers end |
#presentation_token ⇒ Object (readonly)
Returns the value of attribute presentation_token.
31 32 33 |
# File 'lib/clickwrap/submission.rb', line 31 def presentation_token @presentation_token end |
Class Method Details
.affirmative?(value) ⇒ Boolean
112 113 114 115 116 |
# File 'lib/clickwrap/submission.rb', line 112 def self.affirmative?(value) return false if value.nil? !%w[0 false off no].include?(value.to_s.downcase) && value.to_s != "" end |
.from_params(params, key: ENVELOPE_KEY) ⇒ Object
Reads the generated envelope out of controller params.
41 42 43 44 45 46 47 48 49 50 |
# File 'lib/clickwrap/submission.rb', line 41 def from_params(params, key: ENVELOPE_KEY) envelope = extract_envelope(params, key) raise SubmissionInvalid, (key) if envelope.nil? new( presentation_token: envelope["presentation_token"] || envelope[:presentation_token], answers: envelope["answers"] || envelope[:answers] || {} ) end |
.missing_envelope_message(key) ⇒ Object
52 53 54 55 |
# File 'lib/clickwrap/submission.rb', line 52 def (key) "The request contains no #{key} parameter. The form helper renders it; a custom form " \ "must include the signed presentation token from Clickwrap.present." end |
Instance Method Details
#answer_for(statement_key) ⇒ Object
106 |
# File 'lib/clickwrap/submission.rb', line 106 def answer_for(statement_key) = answers[statement_key.to_s] |
#answered?(statement_key) ⇒ Boolean
108 109 110 |
# File 'lib/clickwrap/submission.rb', line 108 def answered?(statement_key) self.class.affirmative?(answer_for(statement_key)) end |
#manifest ⇒ Object
Deliberately not memoized: a Submission is frozen the moment it is built, so an instance variable written on first use would raise. Verifying the token again costs one signature check, which is a small price for an object that cannot be tampered with after construction.
102 103 104 |
# File 'lib/clickwrap/submission.rb', line 102 def manifest PresentationManifest.from_token(presentation_token) end |
#to_h ⇒ Object
118 119 120 |
# File 'lib/clickwrap/submission.rb', line 118 def to_h { "presentation_token" => presentation_token, "answers" => answers } end |