Class: MailerToGo::SPF::Plan
- Inherits:
-
Struct
- Object
- Struct
- MailerToGo::SPF::Plan
- Defined in:
- lib/mailertogo/spf/plan.rb
Overview
What to tell a domain owner to publish, given what is already at that name.
action:
:publish — nothing SPF-shaped is published at this name: hand them
the standalone record. Also the fallback when DNS did not
answer (resolved? == false), because guessing is worse.
:merge — one record is already there and does not authorize the
sender: they must REPLACE it with merged_record.
:deduplicate — two or more v=spf1 records are already published (the
RFC 7208 §3.2 violation): replace ALL of them with
merged_record.
:satisfied — a single record already reaches the sender. Nothing to say.
over_lookup_limit is true only when the merged record was definitively measured past RFC 7208 §4.6.4's cap — never on an inconclusive DNS answer.
Instance Attribute Summary collapse
-
#action ⇒ Object
Returns the value of attribute action.
-
#all_qualifier ⇒ Object
Returns the value of attribute all_qualifier.
-
#existing_records ⇒ Object
Returns the value of attribute existing_records.
-
#include_name ⇒ Object
Returns the value of attribute include_name.
-
#lookup_limit ⇒ Object
Returns the value of attribute lookup_limit.
-
#lookups ⇒ Object
Returns the value of attribute lookups.
-
#merged_record ⇒ Object
Returns the value of attribute merged_record.
-
#name ⇒ Object
Returns the value of attribute name.
-
#notes ⇒ Object
Returns the value of attribute notes.
-
#over_lookup_limit ⇒ Object
Returns the value of attribute over_lookup_limit.
-
#record ⇒ Object
Returns the value of attribute record.
-
#resolved ⇒ Object
Returns the value of attribute resolved.
Class Method Summary collapse
-
.none(name: nil, record: nil) ⇒ Object
The "no instruction beyond the standalone record" plan, so no caller has to nil-check before asking a question.
Instance Method Summary collapse
- #deduplicate? ⇒ Boolean
-
#duplicated? ⇒ Boolean
Already in the RFC-violating two-record state right now.
- #merge? ⇒ Boolean
-
#offered_record ⇒ Object
The line to actually put in front of them.
- #over_limit? ⇒ Boolean
- #publish? ⇒ Boolean
-
#replacement? ⇒ Boolean
Are we asking them to REPLACE an existing record rather than add one? The difference matters enormously in a UI: "add this TXT record" next to an existing SPF record is exactly the instruction that produces the two-record permerror in the first place.
-
#replaces?(name:, value:) ⇒ Boolean
Does this row carry the merged replacement instead of its own value? Only the SPF row at the name we resolved, and only when a merged line is actually on offer (never when it is withheld for the lookup cap).
- #resolved? ⇒ Boolean
- #satisfied? ⇒ Boolean
- #severity ⇒ Object
- #value_for(name:, value:) ⇒ Object
-
#warning? ⇒ Boolean
Is this state something to ALERT them about, or just an instruction? Already-duplicated and over-the-cap are defects they are living with today; a plain merge is just telling them how to add the sender correctly the first time.
Instance Attribute Details
#action ⇒ Object
Returns the value of attribute action
23 24 25 |
# File 'lib/mailertogo/spf/plan.rb', line 23 def action @action end |
#all_qualifier ⇒ Object
Returns the value of attribute all_qualifier
23 24 25 |
# File 'lib/mailertogo/spf/plan.rb', line 23 def all_qualifier @all_qualifier end |
#existing_records ⇒ Object
Returns the value of attribute existing_records
23 24 25 |
# File 'lib/mailertogo/spf/plan.rb', line 23 def existing_records @existing_records end |
#include_name ⇒ Object
Returns the value of attribute include_name
23 24 25 |
# File 'lib/mailertogo/spf/plan.rb', line 23 def include_name @include_name end |
#lookup_limit ⇒ Object
Returns the value of attribute lookup_limit
23 24 25 |
# File 'lib/mailertogo/spf/plan.rb', line 23 def lookup_limit @lookup_limit end |
#lookups ⇒ Object
Returns the value of attribute lookups
23 24 25 |
# File 'lib/mailertogo/spf/plan.rb', line 23 def lookups @lookups end |
#merged_record ⇒ Object
Returns the value of attribute merged_record
23 24 25 |
# File 'lib/mailertogo/spf/plan.rb', line 23 def merged_record @merged_record end |
#name ⇒ Object
Returns the value of attribute name
23 24 25 |
# File 'lib/mailertogo/spf/plan.rb', line 23 def name @name end |
#notes ⇒ Object
Returns the value of attribute notes
23 24 25 |
# File 'lib/mailertogo/spf/plan.rb', line 23 def notes @notes end |
#over_lookup_limit ⇒ Object
Returns the value of attribute over_lookup_limit
23 24 25 |
# File 'lib/mailertogo/spf/plan.rb', line 23 def over_lookup_limit @over_lookup_limit end |
#record ⇒ Object
Returns the value of attribute record
23 24 25 |
# File 'lib/mailertogo/spf/plan.rb', line 23 def record @record end |
#resolved ⇒ Object
Returns the value of attribute resolved
23 24 25 |
# File 'lib/mailertogo/spf/plan.rb', line 23 def resolved @resolved end |
Class Method Details
.none(name: nil, record: nil) ⇒ Object
The "no instruction beyond the standalone record" plan, so no caller has to nil-check before asking a question. It answers everything the way a real :publish plan does: nothing to replace, nothing to warn about.
85 86 87 88 89 |
# File 'lib/mailertogo/spf/plan.rb', line 85 def self.none(name: nil, record: nil) new(action: :publish, name: name && Record.normalize_name(name), record: record, existing_records: [], notes: [], resolved: false, lookup_limit: Authorization::MAX_DNS_LOOKUPS, over_lookup_limit: false) end |
Instance Method Details
#deduplicate? ⇒ Boolean
28 |
# File 'lib/mailertogo/spf/plan.rb', line 28 def deduplicate? = action == :deduplicate |
#duplicated? ⇒ Boolean
Already in the RFC-violating two-record state right now.
38 |
# File 'lib/mailertogo/spf/plan.rb', line 38 def duplicated? = deduplicate? |
#merge? ⇒ Boolean
27 |
# File 'lib/mailertogo/spf/plan.rb', line 27 def merge? = action == :merge |
#offered_record ⇒ Object
The line to actually put in front of them. Withheld when merging would blow the lookup budget: a record we know permerrors is worse than the standalone instruction plus an explanation of what has to go first.
47 48 49 50 51 |
# File 'lib/mailertogo/spf/plan.rb', line 47 def offered_record return nil unless replacement? over_limit? ? nil : merged_record end |
#over_limit? ⇒ Boolean
40 |
# File 'lib/mailertogo/spf/plan.rb', line 40 def over_limit? = over_lookup_limit == true |
#publish? ⇒ Boolean
26 |
# File 'lib/mailertogo/spf/plan.rb', line 26 def publish? = action == :publish |
#replacement? ⇒ Boolean
Are we asking them to REPLACE an existing record rather than add one? The difference matters enormously in a UI: "add this TXT record" next to an existing SPF record is exactly the instruction that produces the two-record permerror in the first place.
35 |
# File 'lib/mailertogo/spf/plan.rb', line 35 def replacement? = merge? || deduplicate? |
#replaces?(name:, value:) ⇒ Boolean
Does this row carry the merged replacement instead of its own value? Only the SPF row at the name we resolved, and only when a merged line is actually on offer (never when it is withheld for the lookup cap).
70 71 72 73 74 75 76 |
# File 'lib/mailertogo/spf/plan.rb', line 70 def replaces?(name:, value:) offered = offered_record return false if offered.nil? || offered.empty? return false unless value.to_s.start_with?("v=spf1") Record.normalize_name(name) == self.name end |
#resolved? ⇒ Boolean
42 |
# File 'lib/mailertogo/spf/plan.rb', line 42 def resolved? = resolved == true |
#satisfied? ⇒ Boolean
29 |
# File 'lib/mailertogo/spf/plan.rb', line 29 def satisfied? = action == :satisfied |
#severity ⇒ Object
59 |
# File 'lib/mailertogo/spf/plan.rb', line 59 def severity = warning? ? :warning : :info |
#value_for(name:, value:) ⇒ Object
78 79 80 |
# File 'lib/mailertogo/spf/plan.rb', line 78 def value_for(name:, value:) replaces?(name: name, value: value) ? offered_record : value end |
#warning? ⇒ Boolean
Is this state something to ALERT them about, or just an instruction? Already-duplicated and over-the-cap are defects they are living with today; a plain merge is just telling them how to add the sender correctly the first time. A fact about the plan, not about the view — two surfaces must not have to agree on it independently.
58 |
# File 'lib/mailertogo/spf/plan.rb', line 58 def warning? = duplicated? || over_limit? |