full input validation for repository path
Expands ~ , checks for every crazy input problem I can think of
This commit is contained in:
parent
c950e8fba0
commit
bab80bf24a
2 changed files with 60 additions and 1 deletions
|
@ -20,6 +20,8 @@ import Annex.UUID (getUUID)
|
||||||
|
|
||||||
import Yesod
|
import Yesod
|
||||||
import Data.Text (Text, pack)
|
import Data.Text (Text, pack)
|
||||||
|
import qualified Data.Text as T
|
||||||
|
import Data.Char
|
||||||
|
|
||||||
{- An intro message, list of repositories, and nudge to make more. -}
|
{- An intro message, list of repositories, and nudge to make more. -}
|
||||||
introDisplay :: Text -> Widget
|
introDisplay :: Text -> Widget
|
||||||
|
@ -44,10 +46,64 @@ introDisplay ident = do
|
||||||
data RepositoryPath = RepositoryPath Text
|
data RepositoryPath = RepositoryPath Text
|
||||||
deriving Show
|
deriving Show
|
||||||
|
|
||||||
|
{- Custom field display for a RepositoryPath, with an icon etc.
|
||||||
|
-
|
||||||
|
- Validates that the path entered is not empty, and is a safe value
|
||||||
|
- to use as a repository. -}
|
||||||
|
repositoryPathField :: forall sub. Bool -> Field sub WebApp Text
|
||||||
|
repositoryPathField autofocus = Field { fieldParse = parse, fieldView = view }
|
||||||
|
where
|
||||||
|
view idAttr nameAttr attrs val isReq =
|
||||||
|
[whamlet|<input type="text" *{attrs} id="#{idAttr}" name="#{nameAttr}" :isReq:required :autofocus:autofocus value="#{either id id val}">|]
|
||||||
|
|
||||||
|
parse [path]
|
||||||
|
| T.null path = nopath
|
||||||
|
| otherwise = liftIO $ checkRepositoryPath path
|
||||||
|
parse [] = return $ Right Nothing
|
||||||
|
parse _ = nopath
|
||||||
|
|
||||||
|
nopath = return $ Left "Enter a location for the repository"
|
||||||
|
|
||||||
|
{- As well as checking the path for a lot of silly things, tilde is
|
||||||
|
- expanded in the returned path. -}
|
||||||
|
checkRepositoryPath :: Text -> IO (Either (SomeMessage WebApp) (Maybe Text))
|
||||||
|
checkRepositoryPath p = do
|
||||||
|
home <- myHomeDir
|
||||||
|
let basepath = expandTilde home $ T.unpack p
|
||||||
|
path <- absPath basepath
|
||||||
|
let parent = parentDir path
|
||||||
|
problems <- catMaybes <$> mapM runcheck
|
||||||
|
[ (return $ path == "/", "Enter the full path to use for the repository.")
|
||||||
|
, (return $ all isSpace basepath, "A blank path? Seems unlikely.")
|
||||||
|
, (doesFileExist path, "A file already exists with that name.")
|
||||||
|
, (return $ path == home, "Sorry, using git-annex for your whole home directory is not currently supported.")
|
||||||
|
, (not <$> doesDirectoryExist parent, "Parent directory does not exist.")
|
||||||
|
, (cannotWrite path, "Cannot write a repository there.")
|
||||||
|
]
|
||||||
|
return $
|
||||||
|
case headMaybe problems of
|
||||||
|
Nothing -> Right $ Just $ T.pack basepath
|
||||||
|
Just prob -> Left prob
|
||||||
|
where
|
||||||
|
runcheck (chk, msg) = ifM (chk)
|
||||||
|
( return $ Just msg
|
||||||
|
, return Nothing
|
||||||
|
)
|
||||||
|
cannotWrite path = do
|
||||||
|
tocheck <- ifM (doesDirectoryExist path)
|
||||||
|
(return path, return $ parentDir path)
|
||||||
|
not <$> (catchBoolIO $ fileAccess tocheck False True False)
|
||||||
|
expandTilde home ('~':path) = home </> path
|
||||||
|
expandTilde _ path = path
|
||||||
|
|
||||||
addRepositoryForm :: Form RepositoryPath
|
addRepositoryForm :: Form RepositoryPath
|
||||||
addRepositoryForm msg = do
|
addRepositoryForm msg = do
|
||||||
cwd <- liftIO $ getCurrentDirectory
|
cwd <- liftIO $ getCurrentDirectory
|
||||||
(pathRes, pathView) <- mreq textField "" (Just $ pack cwd)
|
(pathRes, pathView) <- mreq (repositoryPathField True) "" (Just $ pack $ cwd ++ "/")
|
||||||
|
let (err, errmsg) = case pathRes of
|
||||||
|
FormMissing -> (False, "")
|
||||||
|
FormFailure l -> (True, concat $ map T.unpack l)
|
||||||
|
FormSuccess _ -> (False, "")
|
||||||
let form = do
|
let form = do
|
||||||
webAppFormAuthToken
|
webAppFormAuthToken
|
||||||
$(widgetFile "configurators/addrepository/form")
|
$(widgetFile "configurators/addrepository/form")
|
||||||
|
|
|
@ -6,3 +6,6 @@
|
||||||
^{fvInput pathView}
|
^{fvInput pathView}
|
||||||
<button type=submit .btn>
|
<button type=submit .btn>
|
||||||
Make Repository
|
Make Repository
|
||||||
|
$if err
|
||||||
|
<div .alert .alert-error>
|
||||||
|
#{errmsg}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue