Sovite.Policy.Action (sovite v0.6.0)

Copy Markdown View Source

Policy server actions: the value of the action attribute of a reply, as in a Postfix access(5) table.

parse/1 turns an action into a term and encode/1 turns a term back into an action. Keywords are case-insensitive and separated from their argument by spaces or tabs; surrounding whitespace is ignored.

ActionTermMeaning
OK:okAccept.
all-numerical, such as 1730000000:okAccept (access(5); used by pop-before-smtp).
DUNNO:dunnoNo decision: go on with the next restriction.
REJECT [text]{:reject, text}Reject with the default reject code.
DEFER [text]{:defer, text}Reject with a temporary error.
DEFER_IF_REJECT [text]{:defer_if_reject, text}Defer if a later restriction rejects.
DEFER_IF_PERMIT [text]{:defer_if_permit, text}Defer if a later restriction accepts.
4NN [x.y.z] [text], 5NN [x.y.z] [text]{:reply, code, enhanced, text}Reject with this reply.
HOLD [text]{:hold, text}Accept, but put the message on hold.
DISCARD [text]{:discard, text}Accept, then discard the message.
WARN [text]{:warn, text}Log a warning, no decision.
INFO [text]{:info, text}Log a note, no decision.
PREPEND name: value{:prepend, header}Add a header field to the message.
REDIRECT user@domain{:redirect, address}Send the message to this address instead.
BCC user@domain{:bcc, address}Send a copy to this address.
FILTER transport:destination{:filter, destination}Deliver through this content filter.

An optional text is nil when absent. It may start with an RFC 3463 enhanced status code (REJECT 5.7.1 Go away), which is left in the text. Text after OK and DUNNO is ignored.

For 4NN and 5NN replies, code is from 400 to 599 and enhanced an enhanced status code of the same class ("5.7.1" for 550), or nil. Unlike Postfix, which accepts a bare all-numerical 450 or 550 as OK, a bare reject code is a reply without text.

Restriction names (permit, reject_unauth_destination, ...) are not supported. Anything else is {:error, :invalid_action}.

Summary

Types

t()

A parsed action, see the module docs.

An optional text, nil when absent.

Functions

Encodes an action term as action text, the reverse of parse/1. Carriage returns and newlines in texts are replaced by spaces.

Parses an action, see the module docs.

Types

t()

@type t() ::
  :ok
  | :dunno
  | {:reject, text()}
  | {:defer, text()}
  | {:defer_if_reject, text()}
  | {:defer_if_permit, text()}
  | {:reply, 400..599, enhanced :: String.t() | nil, text()}
  | {:hold, text()}
  | {:discard, text()}
  | {:warn, text()}
  | {:info, text()}
  | {:prepend, header :: String.t()}
  | {:redirect, address :: String.t()}
  | {:bcc, address :: String.t()}
  | {:filter, destination :: String.t()}

A parsed action, see the module docs.

text()

@type text() :: String.t() | nil

An optional text, nil when absent.

Functions

encode(action)

@spec encode(t()) :: String.t()

Encodes an action term as action text, the reverse of parse/1. Carriage returns and newlines in texts are replaced by spaces.

Raises ArgumentError for a term that is not an action: an unknown term, a reply code outside 400..599, an enhanced status code of another class, or a PREPEND, REDIRECT, BCC, or FILTER argument that parse/1 would refuse.

iex> Sovite.Policy.Action.encode({:reply, 450, "4.7.1", "Try later"})
"450 4.7.1 Try later"

iex> Sovite.Policy.Action.encode({:reject, nil})
"REJECT"

parse(action)

@spec parse(String.t()) :: {:ok, t()} | {:error, :invalid_action}

Parses an action, see the module docs.

iex> Sovite.Policy.Action.parse("defer_if_permit Greylisted")
{:ok, {:defer_if_permit, "Greylisted"}}

iex> Sovite.Policy.Action.parse("550 5.7.23 SPF fail")
{:ok, {:reply, 550, "5.7.23", "SPF fail"}}

iex> Sovite.Policy.Action.parse("PREPEND Received-SPF: pass")
{:ok, {:prepend, "Received-SPF: pass"}}

iex> Sovite.Policy.Action.parse("REDIRECT")
{:error, :invalid_action}