Compare commits

...

3 Commits

3 changed files with 36 additions and 22 deletions

View File

@ -26,11 +26,25 @@
-- | handle messages in the different pages. -- | handle messages in the different pages.
-- | Pages could handle semantic operations directly instead. -- | Pages could handle semantic operations directly instead.
-- | -- |
-- | TODO: -- | Tested features:
-- | Allow users to provide a validation code (received by email). -- | - registration, mail validation, login, disconnection
-- | - domain registration
-- | - zone display, RR creation, update and removal
-- | -- |
-- | TODO: -- | Validation:
-- | Verify that a user can register, update its password, login. -- | - registration page: login, password, mail
-- | - login and password recovery page: TODO
-- | - mail verification: TODO
-- | - domain list: domain (`label`) is insufficient.
-- |
-- | TODO: when reading a RR `name`, always make it an FQDN by adding `<user-domain>.netlib.re.".
-- |
-- | TODO: remove the FQDN when showing RR names.
-- |
-- | TODO: authd administrative page
-- |
-- | Untested features:
-- | - mail recovery, password change
module App.Container where module App.Container where
import Prelude (Unit, bind, discard, unit, ($), (=<<), (<>), show, pure) import Prelude (Unit, bind, discard, unit, ($), (=<<), (<>), show, pure)

View File

@ -1,6 +1,6 @@
module App.Validation.DNS where module App.Validation.DNS where
import Prelude (apply, between, bind, map, pure, ($), (-), (<)) import Prelude (apply, between, bind, map, pure, ($), (-), (<), (<<<))
import Control.Alt ((<|>)) import Control.Alt ((<|>))
import Data.Array as A import Data.Array as A
@ -13,7 +13,7 @@ import App.ResourceRecord (ResourceRecord)
import GenericParser.SomeParsers as SomeParsers import GenericParser.SomeParsers as SomeParsers
import GenericParser.Parser as G import GenericParser.Parser as G
import GenericParser.DomainParser.Common (DomainError) as DomainParser import GenericParser.DomainParser.Common (DomainError) as DomainParser
import GenericParser.DomainParser (sub_eof) as DomainParser import GenericParser.DomainParser (label, sub_eof) as DomainParser
import GenericParser.IPAddress as IPAddress import GenericParser.IPAddress as IPAddress
import GenericParser.RFC5234 as RFC5234 import GenericParser.RFC5234 as RFC5234
@ -161,19 +161,19 @@ txt_parser = do pos <- G.current_position
-- | `parse` allows to run any parser based on `GenericParser` and provide a validation error. -- | `parse` allows to run any parser based on `GenericParser` and provide a validation error.
-- | The actual validation error contains the parser's error including the position. -- | The actual validation error contains the parser's error including the position.
parse :: forall e v. G.Parser e v -> String -> ((G.Error e) -> Error) -> V AVErrors v parse :: forall e v. G.Parser e v -> String -> ((G.Error e) -> Error) -> V (Array Error) v
parse (G.Parser p) str c = case p { string: str, position: 0 } of parse (G.Parser p) str c = case p { string: str, position: 0 } of
Left x -> invalid $ [c x] Left x -> invalid $ [c x]
Right x -> pure x.result Right x -> pure x.result
validationA :: ResourceRecord -> V AVErrors ResourceRecord validationA :: ResourceRecord -> V (Array Error) ResourceRecord
validationA form = ado validationA form = ado
name <- parse DomainParser.sub_eof form.name VEName name <- parse DomainParser.sub_eof form.name VEName
ttl <- is_between min_ttl max_ttl form.ttl VETTL ttl <- is_between min_ttl max_ttl form.ttl VETTL
target <- parse IPAddress.ipv4 form.target VEIPv4 target <- parse IPAddress.ipv4 form.target VEIPv4
in toRR_basic form.rrid form.readonly "A" name ttl target in toRR_basic form.rrid form.readonly "A" name ttl target
validationAAAA :: ResourceRecord -> V AVErrors ResourceRecord validationAAAA :: ResourceRecord -> V (Array Error) ResourceRecord
validationAAAA form = ado validationAAAA form = ado
name <- parse DomainParser.sub_eof form.name VEName name <- parse DomainParser.sub_eof form.name VEName
ttl <- is_between min_ttl max_ttl form.ttl VETTL ttl <- is_between min_ttl max_ttl form.ttl VETTL
@ -181,21 +181,21 @@ validationAAAA form = ado
target <- parse (G.read_input IPAddress.ipv6) form.target VEIPv6 target <- parse (G.read_input IPAddress.ipv6) form.target VEIPv6
in toRR_basic form.rrid form.readonly "AAAA" name ttl target in toRR_basic form.rrid form.readonly "AAAA" name ttl target
validationTXT :: ResourceRecord -> V AVErrors ResourceRecord validationTXT :: ResourceRecord -> V (Array Error) ResourceRecord
validationTXT form = ado validationTXT form = ado
name <- parse DomainParser.sub_eof form.name VEName name <- parse DomainParser.sub_eof form.name VEName
ttl <- is_between min_ttl max_ttl form.ttl VETTL ttl <- is_between min_ttl max_ttl form.ttl VETTL
target <- parse txt_parser form.target VETXT target <- parse txt_parser form.target VETXT
in toRR_basic form.rrid form.readonly "TXT" name ttl target in toRR_basic form.rrid form.readonly "TXT" name ttl target
validationCNAME :: ResourceRecord -> V AVErrors ResourceRecord validationCNAME :: ResourceRecord -> V (Array Error) ResourceRecord
validationCNAME form = ado validationCNAME form = ado
name <- parse DomainParser.sub_eof form.name VEName name <- parse DomainParser.sub_eof form.name VEName
ttl <- is_between min_ttl max_ttl form.ttl VETTL ttl <- is_between min_ttl max_ttl form.ttl VETTL
target <- parse DomainParser.sub_eof form.target VECNAME target <- parse DomainParser.sub_eof form.target VECNAME
in toRR_basic form.rrid form.readonly "CNAME" name ttl target in toRR_basic form.rrid form.readonly "CNAME" name ttl target
validationNS :: ResourceRecord -> V AVErrors ResourceRecord validationNS :: ResourceRecord -> V (Array Error) ResourceRecord
validationNS form = ado validationNS form = ado
name <- parse DomainParser.sub_eof form.name VEName name <- parse DomainParser.sub_eof form.name VEName
ttl <- is_between min_ttl max_ttl form.ttl VETTL ttl <- is_between min_ttl max_ttl form.ttl VETTL
@ -210,12 +210,12 @@ protocol_parser = do
pos <- G.current_position pos <- G.current_position
G.string "tcp" <|> G.string "udp" <|> G.Parser \_ -> G.failureError pos (Just InvalidProtocol) G.string "tcp" <|> G.string "udp" <|> G.Parser \_ -> G.failureError pos (Just InvalidProtocol)
is_between :: Int -> Int -> Int -> (Int -> Int -> Int -> Error) -> V AVErrors Int is_between :: Int -> Int -> Int -> (Int -> Int -> Int -> Error) -> V (Array Error) Int
is_between min max n ve = if between min max n is_between min max n ve = if between min max n
then pure n then pure n
else invalid [ve min max n] else invalid [ve min max n]
validationMX :: ResourceRecord -> V AVErrors ResourceRecord validationMX :: ResourceRecord -> V (Array Error) ResourceRecord
validationMX form = ado validationMX form = ado
name <- parse DomainParser.sub_eof form.name VEName name <- parse DomainParser.sub_eof form.name VEName
ttl <- is_between min_ttl max_ttl form.ttl VETTL ttl <- is_between min_ttl max_ttl form.ttl VETTL
@ -223,7 +223,7 @@ validationMX form = ado
priority <- is_between min_priority max_priority (maybe 0 id form.priority) VEPriority priority <- is_between min_priority max_priority (maybe 0 id form.priority) VEPriority
in toRR_mx form.rrid form.readonly "MX" name ttl target priority in toRR_mx form.rrid form.readonly "MX" name ttl target priority
validationSRV :: ResourceRecord -> V AVErrors ResourceRecord validationSRV :: ResourceRecord -> V (Array Error) ResourceRecord
validationSRV form = ado validationSRV form = ado
name <- parse DomainParser.sub_eof form.name VEName name <- parse DomainParser.sub_eof form.name VEName
ttl <- is_between min_ttl max_ttl form.ttl VETTL ttl <- is_between min_ttl max_ttl form.ttl VETTL
@ -234,7 +234,7 @@ validationSRV form = ado
weight <- is_between min_weight max_weight (maybe 0 id form.weight) VEWeight weight <- is_between min_weight max_weight (maybe 0 id form.weight) VEWeight
in toRR_srv form.rrid form.readonly "SRV" name ttl target priority port protocol weight in toRR_srv form.rrid form.readonly "SRV" name ttl target priority port protocol weight
validation :: ResourceRecord -> Either AVErrors ResourceRecord validation :: ResourceRecord -> Either (Array Error) ResourceRecord
validation entry = case entry.rrtype of validation entry = case entry.rrtype of
"A" -> toEither $ validationA entry "A" -> toEither $ validationA entry
"AAAA" -> toEither $ validationAAAA entry "AAAA" -> toEither $ validationAAAA entry

View File

@ -4,7 +4,6 @@ import Prelude
import Control.Alt ((<|>)) import Control.Alt ((<|>))
import Data.Either (Either(..)) import Data.Either (Either(..))
import Data.String.CodeUnits as CU
import Data.Maybe (Maybe(..)) import Data.Maybe (Maybe(..))
import Data.Validation.Semigroup (V, invalid, toEither) import Data.Validation.Semigroup (V, invalid, toEither)
@ -32,12 +31,13 @@ parse (G.Parser p) str c = case p { string: str, position: 0 } of
login_parser :: G.Parser LoginParsingError String login_parser :: G.Parser LoginParsingError String
login_parser = do login_parser = do
l <- G.many1 (alpha <|> digit) <|> G.Parser \i -> G.failureError i.position (Just CannotParse) input <- G.current_input
_ <- SomeParsers.eof <|> G.Parser \i -> G.failureError i.position (Just CannotEntirelyParse) _ <- G.many1 (alpha <|> digit) G.<:> \_ -> CannotParse
_ <- SomeParsers.eof G.<:> \_ -> CannotEntirelyParse
pos <- G.current_position pos <- G.current_position
if pos < min_login_size || pos > max_login_size if between min_login_size max_login_size pos
then G.Parser \i -> G.failureError i.position (Just $ Size min_login_size max_login_size pos) then pure input.string
else pure $ CU.fromCharArray l else G.errorParser (Just $ Size min_login_size max_login_size pos)
login :: String -> Either (Array Error) String login :: String -> Either (Array Error) String
login s = toEither $ parse login_parser s ParsingError login s = toEither $ parse login_parser s ParsingError