Skip to content

Commit b7a3376

Browse files
committed
enforce access-question on anonymous page edits
This commit causes an access-question form field to appear on the edit page for anonymous (logged out) users when require-authentication = none and the access-question variables are non-empty. If the field is present, and if the wrong answer is provided by the user, then the user is returned to the edit page with an error message "Access code is invalid.". This new form field behaves in the same way as the access-question form field on the unauthenticated registration page.
1 parent 1b1f598 commit b7a3376

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 mbUser of
644+
Just _ -> True
645+
Nothing -> case accessQuestion cfg of
646+
Nothing -> True
647+
Just (_, answers) -> 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)