Class: MailerToGo::SPF::Result
- Inherits:
-
Struct
- Object
- Struct
- MailerToGo::SPF::Result
- Defined in:
- lib/mailertogo/spf/result.rb
Overview
The answer to "does this domain's published SPF authorise me?", shaped so callers ask it questions rather than pattern-match a hash.
status — :pass | :pinned | :fail | :permerror | :unknown
:pass — the sender is reachable from the record, directly or
through its include chain: durable authorisation.
:pinned — no include chain to the sender, but the record hardcodes
the sender's current sending addresses. Mail passes SPF
*today* and breaks silently the moment an address moves,
so this is deliberately NOT :pass. See #pinned?.
:fail — the chain resolved fine; the sender simply is not in it.
:permerror — the record is broken (duplicate records, or past the
§4.6.4 lookup cap). Receivers reject it, so nothing passes.
:unknown — DNS did not answer. Verdict withheld, NOT a failure.
The four-valued status exists so a resolver hiccup can never be mistaken for "this domain removed my record". Anything that gates a customer on SPF has to be able to tell those apart.
reason narrows :permerror (:duplicate_records | :lookup_limit) and :pinned (:pinned_full | :pinned_partial).
all_qualifier (:pass | :fail | :softfail | :neutral | nil) is what the
record tells receivers to do with mail it does NOT authorise — the
qualifier on its terminal all (RFC 7208 §5.1). It is deliberately a
FIELD rather than a fifth status: the yes/no decision ("is my include
published?") is identical either way, but a ~all domain's unauthorised
mail is merely marked while a -all domain's is rejected outright, and
the customer's remedy is far more urgent in the second case. Callers that
write to humans need to say which one they published.
partial is true when part of the chain did not resolve, which makes
lookups a FLOOR rather than the real cost. Harmless for the verdict — a
match is a match — but it matters to anyone pricing a record against the
§4.6.4 budget, who must not report "this fits" from a count it could not
finish.
Instance Attribute Summary collapse
-
#all_qualifier ⇒ Object
Returns the value of attribute all_qualifier.
-
#detail ⇒ Object
Returns the value of attribute detail.
-
#lookups ⇒ Object
Returns the value of attribute lookups.
-
#matched ⇒ Object
Returns the value of attribute matched.
-
#partial ⇒ Object
Returns the value of attribute partial.
-
#reason ⇒ Object
Returns the value of attribute reason.
-
#status ⇒ Object
Returns the value of attribute status.
Instance Method Summary collapse
-
#defect ⇒ Object
Which defect to tell the customer about, or nil when the record is clean: :ip_pinned | :lookup_limit | :duplicate_records.
- #failed? ⇒ Boolean
- #partial? ⇒ Boolean
- #pass? ⇒ Boolean
- #permerror? ⇒ Boolean
-
#permerror_with_sender_published? ⇒ Boolean
The record IS broken for receivers, but the sender's include is sitting in it.
- #pinned? ⇒ Boolean
-
#softfail? ⇒ Boolean
Unauthorised, but under a
~all: receivers mark the mail rather than rejecting it, so the domain is in a materially better position than a-all:fail. - #unknown? ⇒ Boolean
Instance Attribute Details
#all_qualifier ⇒ Object
Returns the value of attribute all_qualifier
42 43 44 |
# File 'lib/mailertogo/spf/result.rb', line 42 def all_qualifier @all_qualifier end |
#detail ⇒ Object
Returns the value of attribute detail
42 43 44 |
# File 'lib/mailertogo/spf/result.rb', line 42 def detail @detail end |
#lookups ⇒ Object
Returns the value of attribute lookups
42 43 44 |
# File 'lib/mailertogo/spf/result.rb', line 42 def lookups @lookups end |
#matched ⇒ Object
Returns the value of attribute matched
42 43 44 |
# File 'lib/mailertogo/spf/result.rb', line 42 def matched @matched end |
#partial ⇒ Object
Returns the value of attribute partial
42 43 44 |
# File 'lib/mailertogo/spf/result.rb', line 42 def partial @partial end |
#reason ⇒ Object
Returns the value of attribute reason
42 43 44 |
# File 'lib/mailertogo/spf/result.rb', line 42 def reason @reason end |
#status ⇒ Object
Returns the value of attribute status
42 43 44 |
# File 'lib/mailertogo/spf/result.rb', line 42 def status @status end |
Instance Method Details
#defect ⇒ Object
Which defect to tell the customer about, or nil when the record is clean: :ip_pinned | :lookup_limit | :duplicate_records.
64 65 66 67 68 69 |
# File 'lib/mailertogo/spf/result.rb', line 64 def defect case status when :pinned then :ip_pinned when :permerror then reason == :lookup_limit ? :lookup_limit : :duplicate_records end end |
#failed? ⇒ Boolean
48 |
# File 'lib/mailertogo/spf/result.rb', line 48 def failed? = %i[fail permerror].include?(status) |
#partial? ⇒ Boolean
49 |
# File 'lib/mailertogo/spf/result.rb', line 49 def partial? = partial == true |
#pass? ⇒ Boolean
44 |
# File 'lib/mailertogo/spf/result.rb', line 44 def pass? = status == :pass |
#permerror? ⇒ Boolean
46 |
# File 'lib/mailertogo/spf/result.rb', line 46 def permerror? = status == :permerror |
#permerror_with_sender_published? ⇒ Boolean
The record IS broken for receivers, but the sender's include is sitting in it. Gating callers use this to avoid treating "the customer's SPF has an unrelated RFC problem" as "the customer removed my record" — the remedy is completely different, and un-verifying them is wrong.
60 |
# File 'lib/mailertogo/spf/result.rb', line 60 def permerror_with_sender_published? = permerror? && !matched.to_s.empty? |
#pinned? ⇒ Boolean
45 |
# File 'lib/mailertogo/spf/result.rb', line 45 def pinned? = status == :pinned |
#softfail? ⇒ Boolean
Unauthorised, but under a ~all: receivers mark the mail rather than
rejecting it, so the domain is in a materially better position than a
-all :fail. Same defect, different urgency.
54 |
# File 'lib/mailertogo/spf/result.rb', line 54 def softfail? = status == :fail && all_qualifier == :softfail |
#unknown? ⇒ Boolean
47 |
# File 'lib/mailertogo/spf/result.rb', line 47 def unknown? = status == :unknown |