66 lines
2.8 KiB
Text
66 lines
2.8 KiB
Text
module App.Validation.DNS where
|
|
|
|
import Prelude (apply, between, bind, map, pure, ($), (-), (<), (<>), (==))
|
|
|
|
import Control.Alt ((<|>))
|
|
import Data.Array as A
|
|
import Data.Either (Either(..))
|
|
import Data.Maybe (Maybe(..), maybe, fromMaybe)
|
|
import Data.String.CodeUnits as CU
|
|
import Data.String as S
|
|
import Data.Validation.Semigroup (V, invalid, toEither)
|
|
|
|
import App.Type.ResourceRecord (ResourceRecord, emptyRR, Mechanism, Modifier)
|
|
import App.Type.ResourceRecord (MechanismType(..), ModifierType(..)) as RR
|
|
import GenericParser.SomeParsers as SomeParsers
|
|
import GenericParser.Parser as G
|
|
import GenericParser.DomainParser.Common (DomainError) as DomainParser
|
|
import GenericParser.DomainParser (name, sub_eof) as DomainParser
|
|
import GenericParser.IPAddress as IPAddress
|
|
import GenericParser.RFC5234 as RFC5234
|
|
|
|
import App.Type.DKIM as DKIM
|
|
import App.Type.DMARC as DMARC
|
|
import App.Type.CAA as CAA
|
|
|
|
import Utils (id)
|
|
|
|
data Error
|
|
= UNKNOWN
|
|
| VENameServer1 (G.Error DomainParser.DomainError)
|
|
| VENameServer2 (G.Error DomainParser.DomainError)
|
|
|
|
validationCNAME :: ResourceRecord -> V (Array Error) ResourceRecord
|
|
validationCNAME form = ado
|
|
name <- parse DomainParser.name form.name VEName
|
|
ttl <- is_between min_ttl max_ttl form.ttl VETTL
|
|
target <- parse DomainParser.sub_eof form.target VECNAME
|
|
in emptyRR { rrid = form.rrid, readonly = form.readonly, rrtype = "CNAME", name = name, ttl = ttl, target = target }
|
|
|
|
is_between :: Int -> Int -> Int -> (Int -> Int -> Int -> Error) -> V (Array Error) Int
|
|
is_between min max n ve = if between min max n
|
|
then pure n
|
|
else invalid [ve min max n]
|
|
|
|
validationSRV :: ResourceRecord -> V (Array Error) ResourceRecord
|
|
validationSRV form = ado
|
|
name <- parse DomainParser.name form.name VEName
|
|
in emptyRR { rrid = form.rrid, readonly = form.readonly, rrtype = "SRV"
|
|
, name = name, ttl = ttl, target = target
|
|
, priority = Just priority, port = Just port, protocol = form.protocol, weight = Just weight }
|
|
|
|
validation_nameservers :: ResourceRecord -> V (Array Error) ResourceRecord
|
|
validation_nameservers form = ado
|
|
nameserver1 <- parse DomainParser.name form.name VEName
|
|
nameserver2 <- parse DomainParser.name form.name VEName
|
|
in emptyRR { rrid = form.rrid, readonly = form.readonly, rrtype = "SPF"
|
|
, name = name, ttl = ttl, target = "" -- `target` is discarded!
|
|
, v = form.v, mechanisms = Just mechanisms
|
|
, modifiers = Just modifiers, q = form.q }
|
|
|
|
-- | `validation` provides a way to validate the content of a RR.
|
|
validation :: ResourceRecord -> Either (Array Error) ResourceRecord
|
|
validation entry = toEither $ validation_nameservers entry
|
|
"DKIM" -> toEither $ validationDKIM entry
|
|
"DMARC" -> toEither $ validationDMARC entry
|
|
_ -> toEither $ invalid [UNKNOWN]
|