Skip to content

Commit 6a99ecb

Browse files
committed
enforce access-question on anonymous page edits
This commit presents an additional form field for anonymous editors, and validates it. It is the same access-question text field as seen on the unauthenticated registration page.
1 parent 1b1f598 commit 6a99ecb

File tree

1 file changed

+47
-30
lines changed

1 file changed

+47
-30
lines changed

src/Network/Gitit/Handlers.hs

Lines changed: 47 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ import qualified Control.Exception as E
6767
import System.FilePath
6868
import Network.Gitit.State
6969
import Text.XHtml hiding ( (</>), dir, method, password, rev )
70-
import qualified Text.XHtml as X ( method )
70+
import qualified Text.XHtml as X ( method, password )
7171
import Data.List (intercalate, intersperse, delete, nub, sortBy, find, isPrefixOf, inits, sort, (\\))
7272
import Data.List.Split (wordsBy)
7373
import Data.Maybe (fromMaybe, mapMaybe, isJust, catMaybes)
@@ -501,6 +501,7 @@ editPage' params = do
501501
fs <- getFileStore
502502
page <- getPage
503503
cfg <- getConfig
504+
mbUser <- getLoggedInUser
504505
let getRevisionAndText = E.catch
505506
(do c <- liftIO $ retrieve fs (pathForPage page $ defaultExtension cfg) rev
506507
-- even if pRevision is set, we return revId of latest
@@ -529,12 +530,20 @@ editPage' params = do
529530
then [strAttr "readonly" "yes",
530531
strAttr "style" "color: gray"]
531532
else []
533+
let accessQ = case mbUser of
534+
Just _ -> noHtml
535+
Nothing -> case accessQuestion cfg of
536+
Nothing -> noHtml
537+
Just (prompt, _) -> label ! [thefor "accessCode"] << prompt +++ br +++
538+
X.password "accessCode" ! [size "15", intAttr "tabindex" 1]
539+
+++ br
532540
base' <- getWikiBase
533541
let editForm = gui (base' ++ urlForPage page) ! [identifier "editform"] <<
534542
[ sha1Box
535543
, textarea ! (readonly ++ [cols "80", name "editedText",
536544
identifier "editedText"]) << raw
537545
, br
546+
, accessQ
538547
, label ! [thefor "logMsg"] << "Description of changes:"
539548
, br
540549
, textfield "logMsg" ! (readonly ++ [value (logMsg `orIfNull` defaultSummary cfg) ])
@@ -630,39 +639,47 @@ updatePage = withData $ \(params :: Params) -> do
630639
Just b -> applyPreCommitPlugins b
631640
let logMsg = pLogMsg params `orIfNull` defaultSummary cfg
632641
let oldSHA1 = pSHA1 params
642+
let accessCode = pAccessCode params
643+
let isValidAccessCode = case accessQuestion cfg of
644+
Nothing -> True
645+
Just (_, answers) -> case mbUser of
646+
Just _ -> True
647+
Nothing -> accessCode `elem` answers
633648
fs <- getFileStore
634649
base' <- getWikiBase
635650
if null . filter (not . isSpace) $ logMsg
636651
then withMessages ["Description cannot be empty."] editPage
637-
else do
638-
when (length editedText > fromIntegral (maxPageSize cfg)) $
639-
error "Page exceeds maximum size."
640-
-- check SHA1 in case page has been modified, merge
641-
modifyRes <- if null oldSHA1
642-
then liftIO $ create fs (pathForPage page $ defaultExtension cfg)
643-
(Author user email) logMsg editedText >>
644-
return (Right ())
645-
else do
646-
expireCachedFile (pathForPage page $ defaultExtension cfg) `mplus` return ()
647-
liftIO $ E.catch (modify fs (pathForPage page $ defaultExtension cfg)
648-
oldSHA1 (Author user email) logMsg
649-
editedText)
650-
(\e -> if e == Unchanged
651-
then return (Right ())
652-
else E.throwIO e)
653-
case modifyRes of
654-
Right () -> seeOther (base' ++ urlForPage page) $ toResponse $ p << "Page updated"
655-
Left (MergeInfo mergedWithRev conflicts mergedText) -> do
656-
let mergeMsg = "The page has been edited since you checked it out. " ++
657-
"Changes from revision " ++ revId mergedWithRev ++
658-
" have been merged into your edits below. " ++
659-
if conflicts
660-
then "Please resolve conflicts and Save."
661-
else "Please review and Save."
662-
editPage' $
663-
params{ pEditedText = Just mergedText,
664-
pSHA1 = revId mergedWithRev,
665-
pMessages = [mergeMsg] }
652+
else if not isValidAccessCode
653+
then withMessages ["Access code is invalid."] editPage
654+
else do
655+
when (length editedText > fromIntegral (maxPageSize cfg)) $
656+
error "Page exceeds maximum size."
657+
-- check SHA1 in case page has been modified, merge
658+
modifyRes <- if null oldSHA1
659+
then liftIO $ create fs (pathForPage page $ defaultExtension cfg)
660+
(Author user email) logMsg editedText >>
661+
return (Right ())
662+
else do
663+
expireCachedFile (pathForPage page $ defaultExtension cfg) `mplus` return ()
664+
liftIO $ E.catch (modify fs (pathForPage page $ defaultExtension cfg)
665+
oldSHA1 (Author user email) logMsg
666+
editedText)
667+
(\e -> if e == Unchanged
668+
then return (Right ())
669+
else E.throwIO e)
670+
case modifyRes of
671+
Right () -> seeOther (base' ++ urlForPage page) $ toResponse $ p << "Page updated"
672+
Left (MergeInfo mergedWithRev conflicts mergedText) -> do
673+
let mergeMsg = "The page has been edited since you checked it out. " ++
674+
"Changes from revision " ++ revId mergedWithRev ++
675+
" have been merged into your edits below. " ++
676+
if conflicts
677+
then "Please resolve conflicts and Save."
678+
else "Please review and Save."
679+
editPage' $
680+
params{ pEditedText = Just mergedText,
681+
pSHA1 = revId mergedWithRev,
682+
pMessages = [mergeMsg] }
666683

667684
indexPage :: Handler
668685
indexPage = do

0 commit comments

Comments
 (0)