Changes to Gitit
This is my version of the Network.Gitit file with some changes to try and prevent non logged in users from accessing the /private directory
module Network.Gitit (
-- * Wiki handlers
wiki
, reloadTemplates
, runHandler
-- * Initialization
, module Network.Gitit.Initialize
-- * Configuration
, module Network.Gitit.Config
, loginUserForm
-- * Types
, module Network.Gitit.Types
-- * Tools for building handlers
, module Network.Gitit.Framework
, module Network.Gitit.ContentTransformer
, getFileStore
, getUser
, getConfig
)
where
import Network.Gitit.Types
import Network.Gitit.Server
import Network.Gitit.Framework
import Network.Gitit.Handlers
import Network.Gitit.Initialize
import Network.Gitit.Config
import Network.Gitit.State (getFileStore, getUser, getConfig)
import Network.Gitit.ContentTransformer
import Network.Gitit.Authentication (loginUserForm)
import Paths_gitit (getDataFileName)
import Control.Monad.Reader
import Prelude hiding (readFile)
import qualified Data.ByteString.Char8 as B
import System.FilePath ((</>))
-- | Happstack handler for a gitit wiki.
wiki :: Config -> ServerPart Response
wiki conf = do
let static = staticDir conf
defaultStatic <- liftIO $ getDataFileName $ "data" </> "static"
-- if file not found in staticDir, we check also in the data/static
-- directory, which contains defaults
let staticHandler = withExpiresHeaders $
fileServeStrict' [] static `mplus` fileServeStrict' [] defaultStatic
let handlers = [debugHandler | debugMode conf] ++ (authHandler conf : wikiHandlers)
let fs = filestoreFromConfig conf
let ws = WikiState { wikiConfig = conf, wikiFileStore = fs }
if compressResponses conf
then compressedResponseFilter
else return ""
staticHandler `mplus` runHandler ws (withUser conf $ msum handlers)
-- | Like 'fileServeStrict', but if file is not found, fail instead of
-- returning a 404 error.
fileServeStrict' :: [FilePath] -> FilePath -> ServerPart Response
fileServeStrict' ps p = do
rq <- askRq
resp <- fileServeStrict ps p
if rsCode resp == 404 || last (rqUri rq) == '/'
then mzero -- pass through if not found or directory index
else do
-- turn off compresion filter unless it's text
case getHeader "Content-Type" resp of
Just ct | B.pack "text/" `B.isPrefixOf` ct -> return resp
_ -> ignoreFilters >> return resp
wikiHandlers :: [Handler]
wikiHandlers =
[ -- redirect /wiki -> /wiki/ when gitit is being served at /wiki
-- so that relative wikilinks on the page will work properly:
guardBareBase >> getWikiBase >>= \b -> movedPermanently (b ++ "/") (toResponse ())
, dir "_user" currentUser
, dir "_activity" showActivity
, dir "_go" goToPage
, dir "_search" searchResults
, dir "_upload" $ methodOnly GET >> requireUser uploadForm
, dir "_upload" $ methodOnly POST >> requireUser uploadFile
, dir "_random" $ methodOnly GET >> randomPage
, dir "_index" indexPage
, dir "_feed" feedHandler
, dir "_category" categoryPage
, dir "_categories" categoryListPage
, dir "_expire" expireCache
, dir "_showraw" $ msum
[ showRawPage
, guardPath isSourceCode >> showFileAsText ]
, dir "_history" $ msum
[ showPageHistory
, guardPath isSourceCode >> showFileHistory ]
, dir "_edit" $ requireUser (unlessNoEdit editPage showPage)
I have added a "requireUser" to the line below so that only people who are logged in can see the changes made to a page
, dir "_diff" $ requireUser (msum
[ showPageDiff
, guardPath isSourceCode >> showFileDiff ])
, dir "_discuss" discussPage
, dir "_delete" $ msum
[ methodOnly GET >>
requireUser (unlessNoDelete confirmDelete showPage)
, methodOnly POST >>
requireUser (unlessNoDelete deletePage showPage) ]
, dir "_preview" preview
, guardIndex >> indexPage
, guardCommand "export" >> exportPage
, methodOnly POST >> guardCommand "cancel" >> showPage
, methodOnly POST >> guardCommand "update" >>
requireUser (unlessNoEdit updatePage showPage)
The line below means that people have to be logged in to view a page in the "private" directory. It is still possible to find the URIs of pages in the directory, but it is not possible to view the page contents
, dir "private" $ requireUser showPage
, showPage
, guardPath isSourceCode >> methodOnly GET >> showHighlightedSource
, handleAny
, notFound =<< (guardPath isPage >> createPage)
]
-- | Recompiles the gitit templates.
reloadTemplates :: ServerPart Response
reloadTemplates = do
liftIO recompilePageTemplate
ok $ toResponse "Page templates have been recompiled."
-- | Converts a gitit Handler into a standard happstack ServerPart.
runHandler :: WikiState -> Handler -> ServerPart Response
runHandler = mapServerPartT . unpackReaderT
unpackReaderT:: (Monad m)
=> c
-> (ReaderT c m) (Maybe ((Either b a), FilterFun b))
-> m (Maybe ((Either b a), FilterFun b))
unpackReaderT st handler = runReaderT handler st
