PhoenixKit.API.Keys.CIDR (phoenix_kit v2.63.0)

Copy Markdown View Source

The IP allow-list of an API key: a list of CIDR blocks stored as text.

An entry is address/prefix_length or a bare address (a single host). The text is split on /, the address is parsed with :inet.parse_strict_address/1 and the prefix length must fit the address family (0-32 for IPv4, 0-128 for IPv6). A client address is allowed when it falls inside any block of its own family; an IPv4-mapped IPv6 client (::ffff:203.0.113.7) counts as IPv4.

parse_strict_address/1 is :inet.parse_address/1 without its shorthand forms ("10.1" would be read as 10.0.0.1), so only addresses written out in full are accepted.

Summary

Functions

Whether client_ip (text) falls inside any block of entries (CIDR text).

Whether address is inside block. Different families never match.

Validates an entry and returns it in canonical text form.

Normalises a list of entries.

Types

block()

@type block() :: {:inet.ip_address(), non_neg_integer()}

Functions

allowed?(entries, client_ip)

@spec allowed?([String.t()], String.t() | nil) :: boolean()

Whether client_ip (text) falls inside any block of entries (CIDR text).

contains?(arg, address)

@spec contains?(block(), :inet.ip_address()) :: boolean()

Whether address is inside block. Different families never match.

normalize(text)

@spec normalize(term()) :: {:ok, String.t()} | :error

Validates an entry and returns it in canonical text form.

iex> PhoenixKit.API.Keys.CIDR.normalize("203.0.113.7")
{:ok, "203.0.113.7/32"}

iex> PhoenixKit.API.Keys.CIDR.normalize("2001:DB8::/32")
{:ok, "2001:db8::/32"}

iex> PhoenixKit.API.Keys.CIDR.normalize("10.0.0.0/33")
:error

normalize_all(entries)

@spec normalize_all([term()]) :: {:ok, [String.t()]} | {:error, [term()]}

Normalises a list of entries.

Returns {:ok, normalised} or {:error, invalid_entries} naming every entry that did not parse.