Class: Clickwrap::RequestEvidencePolicy

Inherits:
Object
  • Object
show all
Defined in:
lib/clickwrap/request_evidence_policy.rb

Overview

What one policy is allowed to record about the HTTP request that carried a capture.

Everything here is off unless a policy or the initializer names it. That is not squeamishness about useful data: it is that high-quality evidence is purpose-specific. An IP address is personal data, and keeping it on your own infrastructure does not remove the duty to have a reason for it, protect it, and stop keeping it eventually. So each field is enabled by name, and the policy that enables it is the server's, never the browser's.

Naming a field is the whole requirement. Every recorded category still leaves here carrying a purpose and a disposal posture, because a snapshot read years from now has to answer both questions — but since 0.3.0 those answers have honest gem-supplied defaults instead of being the entry fee. A host who writes their own keeps their own words, and the privacy inventory reports which of the two is looking back at you.

None of these fields is identity or physical location. An IP address is a network observation. IP geolocation is a provider's estimate about that address. The raw User-Agent header is whatever the client chose to send.

Defined Under Namespace

Classes: Setting

Constant Summary collapse

FIELD_CATEGORIES =
%i[ip_address browser_user_agent ip_geolocation].freeze
NOT_RECORDED =
Setting.new(record: false).freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(policy_key:, retention_class_key: nil, ip_address: nil, browser_user_agent: nil, ip_geolocation: nil, ip_geolocation_fields: {}, ip_geolocation_resolver_name: nil, trusted_proxy_configuration_digest: nil, review_configuration_on: nil) ⇒ RequestEvidencePolicy

Returns a new instance of RequestEvidencePolicy.



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/clickwrap/request_evidence_policy.rb', line 64

def initialize(policy_key:, retention_class_key: nil, ip_address: nil,
               browser_user_agent: nil, ip_geolocation: nil,
               ip_geolocation_fields: {}, ip_geolocation_resolver_name: nil,
               trusted_proxy_configuration_digest: nil, review_configuration_on: nil)
  @policy_key = policy_key
  @retention_class_key = retention_class_key&.to_s
  @purpose_sources = {}
  @ip_address = normalized_setting(:ip_address, ip_address || NOT_RECORDED)
  @browser_user_agent = normalized_setting(:browser_user_agent, browser_user_agent || NOT_RECORDED)
  @ip_geolocation = normalized_setting(:ip_geolocation, ip_geolocation || NOT_RECORDED)
  @purpose_sources.freeze
  @ip_geolocation_fields = normalize_geolocation_fields(ip_geolocation_fields)
  @ip_geolocation_resolver_name = ip_geolocation_resolver_name&.to_sym
  @trusted_proxy_configuration_digest = trusted_proxy_configuration_digest&.to_s
  @review_configuration_on = review_configuration_on

  validate!
  freeze
end

Instance Attribute Details

#browser_user_agentObject (readonly)

Returns the value of attribute browser_user_agent.



59
60
61
# File 'lib/clickwrap/request_evidence_policy.rb', line 59

def browser_user_agent
  @browser_user_agent
end

#ip_addressObject (readonly)

Returns the value of attribute ip_address.



59
60
61
# File 'lib/clickwrap/request_evidence_policy.rb', line 59

def ip_address
  @ip_address
end

#ip_geolocationObject (readonly)

Returns the value of attribute ip_geolocation.



59
60
61
# File 'lib/clickwrap/request_evidence_policy.rb', line 59

def ip_geolocation
  @ip_geolocation
end

#ip_geolocation_fieldsObject (readonly)

Returns the value of attribute ip_geolocation_fields.



59
60
61
# File 'lib/clickwrap/request_evidence_policy.rb', line 59

def ip_geolocation_fields
  @ip_geolocation_fields
end

#ip_geolocation_resolver_nameObject (readonly)

Returns the value of attribute ip_geolocation_resolver_name.



59
60
61
# File 'lib/clickwrap/request_evidence_policy.rb', line 59

def ip_geolocation_resolver_name
  @ip_geolocation_resolver_name
end

#policy_keyObject (readonly)

Returns the value of attribute policy_key.



59
60
61
# File 'lib/clickwrap/request_evidence_policy.rb', line 59

def policy_key
  @policy_key
end

#retention_class_keyObject (readonly)

Returns the value of attribute retention_class_key.



59
60
61
# File 'lib/clickwrap/request_evidence_policy.rb', line 59

def retention_class_key
  @retention_class_key
end

#review_configuration_onObject (readonly)

Returns the value of attribute review_configuration_on.



59
60
61
# File 'lib/clickwrap/request_evidence_policy.rb', line 59

def review_configuration_on
  @review_configuration_on
end

#trusted_proxy_configuration_digestObject (readonly)

Returns the value of attribute trusted_proxy_configuration_digest.



59
60
61
# File 'lib/clickwrap/request_evidence_policy.rb', line 59

def trusted_proxy_configuration_digest
  @trusted_proxy_configuration_digest
end

Instance Method Details

#authorized_fields_manifestObject

The exact field allowlist stored beside any recorded request evidence, so a reader years later can tell what the server was authorized to keep — not merely what happens to be present.



119
120
121
122
123
124
125
# File 'lib/clickwrap/request_evidence_policy.rb', line 119

def authorized_fields_manifest
  {
    "ip_address" => records_ip_address?,
    "browser_user_agent" => records_browser_user_agent?,
    "ip_geolocation" => ip_geolocation_fields.dup
  }
end

#enabled_ip_geolocation_fieldsObject



92
93
94
# File 'lib/clickwrap/request_evidence_policy.rb', line 92

def enabled_ip_geolocation_fields
  ip_geolocation_fields.select { |_, enabled| enabled }.keys
end

#purpose_source_for(category) ⇒ Object

Who wrote the purpose stored for this category: "host" when the policy or the initializer supplied one, "gem_default" when Clickwrap filled in its own. Deliberately kept off to_snapshot: the snapshot is a released evidence format, and the answer is derivable from the configuration a reader already has.



103
104
105
# File 'lib/clickwrap/request_evidence_policy.rb', line 103

def purpose_source_for(category)
  @purpose_sources[category.to_s]
end

#records_anything?Boolean

Returns:

  • (Boolean)


96
# File 'lib/clickwrap/request_evidence_policy.rb', line 96

def records_anything? = records_ip_address? || records_browser_user_agent? || records_ip_geolocation?

#records_browser_user_agent?Boolean

Returns:

  • (Boolean)


85
# File 'lib/clickwrap/request_evidence_policy.rb', line 85

def records_browser_user_agent? = browser_user_agent.record?

#records_ip_address?Boolean

Returns:

  • (Boolean)


84
# File 'lib/clickwrap/request_evidence_policy.rb', line 84

def records_ip_address? = ip_address.record?

#records_ip_geolocation?Boolean

Returns:

  • (Boolean)


86
# File 'lib/clickwrap/request_evidence_policy.rb', line 86

def records_ip_geolocation? = ip_geolocation.record?

#records_ip_geolocation_field?(field) ⇒ Boolean

Returns:

  • (Boolean)


88
89
90
# File 'lib/clickwrap/request_evidence_policy.rb', line 88

def records_ip_geolocation_field?(field)
  ip_geolocation_fields.fetch(field.to_s, false)
end

#setting_for(category) ⇒ Object



107
108
109
110
111
112
113
114
# File 'lib/clickwrap/request_evidence_policy.rb', line 107

def setting_for(category)
  case category.to_sym
  when :ip_address then ip_address
  when :browser_user_agent then browser_user_agent
  when :ip_geolocation then ip_geolocation
  else raise ArgumentError, "Unknown request-evidence category #{category.inspect}"
  end
end

#to_snapshotObject



127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/clickwrap/request_evidence_policy.rb', line 127

def to_snapshot
  {
    "ip_address" => ip_address.to_snapshot,
    "browser_user_agent" => browser_user_agent.to_snapshot,
    "ip_geolocation" => ip_geolocation.to_snapshot.merge(
      "fields" => ip_geolocation_fields,
      "resolver" => ip_geolocation_resolver_name&.to_s
    ).compact,
    "trusted_proxy_configuration_digest" => trusted_proxy_configuration_digest,
    "review_configuration_on" => review_configuration_on&.to_s
  }.compact
end