iptadmin-1.0.0: src/IptAdmin/EditForm/Render.hs
{-# LANGUAGE OverloadedStrings #-}
module IptAdmin.EditForm.Render where
import Data.Monoid
import Data.Set (member)
import Data.String
import IptAdmin.EditForm.Class
import IptAdmin.EditForm.Types
import Iptables.Types
import Text.Blaze
import qualified Text.Blaze.Html5 as H
import qualified Text.Blaze.Html5.Attributes as A
checkBox :: String -> Bool -> Html
checkBox name on = do
let chBox = H.input ! A.type_ "checkbox" ! A.name (fromString name) ! A.value "on"
if on then chBox ! A.checked "checked"
else chBox
printMesTd :: ResMessage -> Html
printMesTd rm = H.td $ fromString $ case rm of
RMError mes -> mes
RMSucc mes -> "ok " ++ mes
RMIgnore -> "ignored"
maybeListToListMaybe :: Maybe [a] -> [Maybe a]
maybeListToListMaybe (Just list) = map Just list
maybeListToListMaybe Nothing = repeat Nothing
editFormHtml :: EditForm a => (String,String,Int,[String]) -> a -> Maybe [ResMessage] -> Html
editFormHtml (tableName, chainName, rulePos, userChainNames) form errorListMay =
let entryList = toEntryList form
mesListMay = maybeListToListMaybe errorListMay
in
H.div ! A.class_ "editForm" $
H.form ! A.id "editform" ! A.method "post" $ do
H.input ! A.type_ "hidden" ! A.name "table" ! A.value (fromString tableName)
H.input ! A.type_ "hidden" ! A.name "chain" ! A.value (fromString chainName)
H.input ! A.type_ "hidden" ! A.name "rulePos" ! A.value (fromString $ show rulePos)
H.table ! A.class_ "editForm" $ do
H.tr $ do
H.th "Option"
H.th "Not"
H.th "Parameter"
maybe mempty (\_-> H.th "Message") errorListMay
mapM_ (renderFormEntry userChainNames) $ zip entryList mesListMay
H.input ! A.id "check" ! A.name "submit" ! A.type_ "submit" ! A.value "Check"
H.input ! A.id "submit" ! A.name "submit" ! A.type_ "submit" ! A.value "Submit"
renderFormEntry :: [String] -> (FormEntry, Maybe ResMessage) -> Html
renderFormEntry _ (FESrc en inv str, resMesMay) =
H.tr $ do
H.td $ do
"Source" >> H.br
checkBox "sourceEnable" en
H.td $ do
"!"
checkBox "sourceInv" inv
H.td $
H.input ! A.type_ "text" ! A.name "source" ! A.value (fromString str)
maybe mempty printMesTd resMesMay
renderFormEntry _ (FEDst en inv str, resMesMay) =
H.tr $ do
H.td $ do
"Destination" >> H.br
checkBox "destinationEnable" en
H.td $ do
"!"
checkBox "destinationInv" inv
H.td $
H.input ! A.type_ "text" ! A.name "destination" ! A.value (fromString str)
maybe mempty printMesTd resMesMay
renderFormEntry _ (FEProt en inv prot, resMesMay) =
H.tr $ do
H.td $ do
"Protocol" >> H.br
checkBox "protocolEnable" en
H.td $ do
"!"
checkBox "protocolInv" inv
H.td $
H.select ! A.id "protocol" ! A.name "protocol" $ do
let tcpOpt = H.option ! A.value "tcp" $ "TCP"
let udpOpt = H.option ! A.value "udp" $ "UDP"
let icmpOpt = H.option ! A.value "icmp" $ "ICMP"
case prot of
FTCP -> do
tcpOpt ! A.selected "selected"
udpOpt >> icmpOpt
FUDP -> do
tcpOpt
udpOpt ! A.selected "selected"
icmpOpt
FICMP -> do
tcpOpt >> udpOpt
icmpOpt ! A.selected "selected"
maybe mempty printMesTd resMesMay
renderFormEntry _ (FESPort en inv str, resMesMay) =
H.tr $ do
H.td $ do
"Source port" >> H.br
checkBox "sportEnable" en
H.td $ do
"!"
checkBox "sportInv" inv
H.td $
H.input ! A.type_ "text" ! A.name "sport" ! A.value (fromString str)
maybe mempty printMesTd resMesMay
renderFormEntry _ (FEDPort en inv str, resMesMay) =
H.tr $ do
H.td $ do
"Destination port" >> H.br
checkBox "dportEnable" en
H.td $ do
"!"
checkBox "dportInv" inv
H.td $
H.input ! A.type_ "text" ! A.name "dport" ! A.value (fromString str)
maybe mempty printMesTd resMesMay
renderFormEntry _ (FEInput en inv str, resMesMay) =
H.tr $ do
H.td $ do
"Input interface" >> H.br
checkBox "inputEnable" en
H.td $ do
"!"
checkBox "inputInv" inv
H.td $
H.input ! A.type_ "text" ! A.name "input" ! A.value (fromString str)
maybe mempty printMesTd resMesMay
renderFormEntry _ (FEOutput en inv str, resMesMay) =
H.tr $ do
H.td $ do
"Output interface" >> H.br
checkBox "outputEnable" en
H.td $ do
"!"
checkBox "outputInv" inv
H.td $
H.input ! A.type_ "text" ! A.name "output" ! A.value (fromString str)
maybe mempty printMesTd resMesMay
renderFormEntry _ (FEState en stateSet, resMesMay) =
H.tr $ do
H.td $ do
"State" >> H.br
checkBox "stateEnable" en
H.td ""
H.td $ do
checkBox "stateNew" $ CStNew `member` stateSet
"New" >> H.br
checkBox "stateEstablished" $ CStEstablished `member` stateSet
"Established" >> H.br
checkBox "stateRelated" $ CStRelated `member` stateSet
"Related" >> H.br
checkBox "stateInvalid" $ CStInvalid `member` stateSet
"Invalid" >> H.br
checkBox "stateUntracked" $ CStUntracked `member` stateSet
"Untracked" >> H.br
maybe mempty printMesTd resMesMay
renderFormEntry userChainNames (FEFiltTar filtTar rejectType userChain, resMesMay) =
H.tr $ do
H.td ! A.colspan "3" ! A.class_ "inline" $
H.table ! A.class_ "inline" $ do
H.tr $ do
H.th ! A.class_ "target" $ "Target"
H.th ! A.class_ "targetParam" $ "Parameters"
H.tr $ do
H.td ! A.class_ "target" $ do
let acceptRadio = H.input ! A.type_ "radio" ! A.name "target" ! A.value "accept"
case filtTar of
FAccept -> acceptRadio ! A.checked "checked"
_ -> acceptRadio
"Acccept"
H.td ! A.class_ "targetParam" $ ""
H.tr $ do
H.td ! A.class_ "target" $ do
let dropRadio = H.input ! A.type_ "radio" ! A.name "target" ! A.value "drop"
case filtTar of
FDrop -> dropRadio ! A.checked "checked"
_ -> dropRadio
"Drop"
H.td ! A.class_ "targetParam" $ ""
H.tr $ do
H.td ! A.class_ "target" $ do
let rejectRadio = H.input ! A.type_ "radio" ! A.name "target" ! A.value "reject"
case filtTar of
FReject -> rejectRadio ! A.checked "checked"
_ -> rejectRadio
"Reject" >> H.br
H.td ! A.class_ "targetParam" $
H.select ! A.id "rejectType" ! A.name "rejectType" $
let
netUnrOpt = H.option ! A.value "icmp-net-unreachable" $ "Icmp-net-unreachable"
netUnrOptSel = if rejectType == RTNetUnreachable then netUnrOpt ! A.selected "selected"
else netUnrOpt
hostUnrOpt = H.option ! A.value "icmp-host-unreachable" $ "Icmp-host-unreachable"
hostUnrOptSel = if rejectType == RTHostUnreachable then hostUnrOpt ! A.selected "selected"
else hostUnrOpt
portUnrOpt = H.option ! A.value "icmp-port-unreachable" $ "Icmp-port-unreachable"
portUnrOptSel = if rejectType == RTPortUnreachable then portUnrOpt ! A.selected "selected"
else portUnrOpt
protoUnrOpt = H.option ! A.value "icmp-proto-unreachable" $ "Icmp-proto-unreachable"
protoUnrOptSel = if rejectType == RTProtoUnreachable then protoUnrOpt ! A.selected "selected"
else protoUnrOpt
netProhOpt = H.option ! A.value "icmp-net-prohibited" $ "Icmp-net-prohibited"
netProhOptSel = if rejectType == RTNetProhibited then netProhOpt ! A.selected "selected"
else netProhOpt
hostProhOpt = H.option ! A.value "icmp-host-prohibited" $ "Icmp-host-prohibited"
hostProhOptSel = if rejectType == RTHostProhibited then hostProhOpt ! A.selected "selected"
else hostProhOpt
admProhOpt = H.option ! A.value "icmp-admin-prohibited" $ "Icmp-admin-prohibited"
admProhOptSel = if rejectType == RTAdminProhibited then admProhOpt ! A.selected "selected"
else admProhOpt
tcpResetOpt = H.option ! A.value "tcp-reset" $ "Tcp-reset"
tcpResetOptSel = if rejectType == RTTcpReset then tcpResetOpt ! A.selected "selected"
else tcpResetOpt
in
netUnrOptSel
>> hostUnrOptSel
>> portUnrOptSel
>> protoUnrOptSel
>> netProhOptSel
>> hostProhOptSel
>> admProhOptSel
>> tcpResetOptSel
if not $ null userChainNames
then
let checked = case filtTar of
FFUserChain -> True
_ -> False
in renderUserChain checked userChainNames userChain
else mempty
maybe mempty printMesTd resMesMay
renderFormEntry userChainNames (FENatPrerOutTar natPrerTar dnataddr dnatrand dnatpersist redirport redirrand userChain, resMesMay) =
H.tr $ do
H.td ! A.colspan "3" ! A.class_ "inline" $
H.table ! A.class_ "inline" $ do
H.tr $ do
H.th ! A.class_ "target" $ "Target"
H.th ! A.class_ "targetParam" $ "Parameters"
let checked = case natPrerTar of
FDNat -> True
_ -> False
renderDNat checked dnataddr dnatrand dnatpersist
let checked' = case natPrerTar of
FRedirect -> True
_ -> False
renderRedirect checked' redirport redirrand
if not $ null userChainNames
then
let checked'' = case natPrerTar of
FNPrerUserChain -> True
_ -> False
in renderUserChain checked'' userChainNames userChain
else mempty
maybe mempty printMesTd resMesMay
renderFormEntry userChainNames (FENatPostrTar natPostrTar snataddr snatrand snatpersist masqport masqrand userChain, resMesMay) =
H.tr $ do
H.td ! A.colspan "3" ! A.class_ "inline" $
H.table ! A.class_ "inline" $ do
H.tr $ do
H.th ! A.class_ "target" $ "Target"
H.th ! A.class_ "targetParam" $ "Parameters"
let checked = case natPostrTar of
FMasq -> True
_ -> False
renderMasq checked masqport masqrand
let checked' = case natPostrTar of
FSNat -> True
_ -> False
renderSNat checked' snataddr snatrand snatpersist
if not $ null userChainNames
then
let checked'' = case natPostrTar of
FNPostrUserChain -> True
_ -> False
in renderUserChain checked'' userChainNames userChain
else
mempty
maybe mempty printMesTd resMesMay
renderFormEntry userChainNames (FENatUserTar natUserTar dnatAddr dnatRand dnatPersist redirPort redirRand snatAddr snatRand snatPersist masqPort masqRand userChain, resMesMay) =
H.tr $ do
H.td ! A.colspan "3" ! A.class_ "inline" $
H.table ! A.class_ "inline" $ do
H.tr $ do
H.th ! A.class_ "target" $ "Target"
H.th ! A.class_ "targetParam" $ "Parameters"
let checked = case natUserTar of
FUDNat -> True
_ -> False
renderDNat checked dnatAddr dnatRand dnatPersist
let checked' = case natUserTar of
FURedirect -> True
_ -> False
renderRedirect checked' redirPort redirRand
let checked'' = case natUserTar of
FUSNat -> True
_ -> False
renderSNat checked'' snatAddr snatRand snatPersist
let checked''' = case natUserTar of
FUMasq -> True
_ -> False
renderMasq checked''' masqPort masqRand
if not $ null userChainNames
then
let checked'''' = case natUserTar of
FNUserUserChain -> True
_ -> False
in renderUserChain checked'''' userChainNames userChain
else
mempty
maybe mempty printMesTd resMesMay
renderFormEntry _ a = H.tr $ fromString $ "Unknown form entry: " ++ show a
renderDNat :: Bool -> String -> Bool -> Bool -> Html
renderDNat checked dnatAddr dnatRand dnatPersist =
H.tr $ do
H.td ! A.class_ "target" $ do
let dnatRadio = H.input ! A.type_ "radio" ! A.name "target" ! A.value "dnat"
if checked then dnatRadio ! A.checked "checked"
else dnatRadio
"Destination Nat"
H.td ! A.class_ "targetParam" $ do
"dnat address:"
H.input ! A.type_ "text" ! A.name "dnataddress" ! A.value (fromString dnatAddr) >> H.br
"random:"
checkBox "dnatrandom" dnatRand >> H.br
"persistent:"
checkBox "dnatpersistent" dnatPersist >> H.br
renderRedirect :: Bool -> String -> Bool -> Html
renderRedirect checked redirPort redirRand =
H.tr $ do
H.td ! A.class_ "target" $ do
let redirRadio = H.input ! A.type_ "radio" ! A.name "target" ! A.value "redirect"
if checked then redirRadio ! A.checked "checked"
else redirRadio
"Redirect"
H.td ! A.class_ "targetParam" $ do
"port:"
H.input ! A.type_ "text" ! A.name "redirport" ! A.value (fromString redirPort) >> H.br
"random:"
checkBox "redirrandom" redirRand
renderSNat :: Bool -> String -> Bool -> Bool -> Html
renderSNat checked snatAddr snatRand snatPersist =
H.tr $ do
H.td ! A.class_ "target" $ do
let snatRadio = H.input ! A.type_ "radio" ! A.name "target" ! A.value "snat"
if checked then snatRadio ! A.checked "checked"
else snatRadio
"Source Nat"
H.td ! A.class_ "targetParam" $ do
"snat address:"
H.input ! A.type_ "text" ! A.name "snataddress" ! A.value (fromString snatAddr) >> H.br
"random:"
checkBox "snatrandom" snatRand >> H.br
"persistent:"
checkBox "snatpersistent" snatPersist >> H.br
renderMasq :: Bool -> String -> Bool -> Html
renderMasq checked masqPort masqRand =
H.tr $ do
H.td ! A.class_ "target" $ do
let masqRadio = H.input ! A.type_ "radio" ! A.name "target" ! A.value "masquerade"
if checked then masqRadio ! A.checked "checked"
else masqRadio
"Masquerade"
H.td ! A.class_ "targetParam" $ do
"port:"
H.input ! A.type_ "text" ! A.name "masqport" ! A.value (fromString masqPort) >> H.br
"random:"
checkBox "masqrandom" masqRand
renderUserChain :: Bool -> [String] -> String -> Html
renderUserChain checked allChains chain =
H.tr $ do
H.td ! A.class_ "target" $ do
let userChainRadio = H.input ! A.type_ "radio" ! A.name "target" ! A.value "userChain"
if checked then userChainRadio ! A.checked "checked"
else userChainRadio
"User chain"
H.td ! A.class_ "targetParam" $
H.select ! A.id "userChain" ! A.name "userChain" $
mapM_ (renderOption chain) allChains
where
renderOption :: String -> String -> Html
renderOption selName optName = do
let opt = H.option ! A.value (fromString optName) $ fromString optName
let optSel = if optName == selName then opt ! A.selected "selected"
else opt
optSel