yesod-csp 0.2.2.0 → 0.2.3.0
raw patch · 3 files changed
+49/−4 lines, 3 filesdep +case-insensitivedep +waiPVP ok
version bump matches the API change (PVP)
Dependencies added: case-insensitive, wai
API changes (from Hackage documentation)
+ Yesod.Csp: cspMiddleware :: DirectiveList -> Middleware
Files
- src/Yesod/Csp.hs +23/−1
- test/Test.hs +23/−2
- yesod-csp.cabal +3/−1
src/Yesod/Csp.hs view
@@ -5,6 +5,7 @@ module Yesod.Csp ( cspPolicy , getCspPolicy+ , cspMiddleware , EscapedURI , escapeAndParseURI , escapedTextForNonce@@ -17,13 +18,17 @@ , textSource ) where +import qualified Data.CaseInsensitive as CI import Data.Data (Data) import Data.List.NonEmpty import Data.Text import qualified Data.Text as T+import qualified Data.Text.Encoding as TE import Data.Typeable (Typeable) import Network.URI import Yesod.Core+import Network.Wai (Middleware, mapResponseHeaders,+ modifyResponse) -- | Adds a "Content-Security-Policy" header to your response. --@@ -36,11 +41,28 @@ -- > [whamlet|hello|] -- cspPolicy :: (MonadHandler m) => DirectiveList -> m ()-cspPolicy = addHeader "Content-Security-Policy" . directiveListToHeader+cspPolicy = addHeader cspHeaderName . directiveListToHeader +cspHeaderName :: Text+cspHeaderName = "Content-Security-Policy"+ -- | Returns a generated Content-Security-Policy header. getCspPolicy :: DirectiveList -> Text getCspPolicy = directiveListToHeader++-- | Creates a WAI 'Middleware' to add a Content-Security-Policy+-- header to every response.+cspMiddleware :: DirectiveList -> Middleware+cspMiddleware = addHeaderMiddleware . mkHeader . directiveListToHeader+ where+ addHeaderMiddleware = modifyResponse . mapResponseHeaders . insertAt 5+ mkHeader dltext = (cspHeaderNameBS, TE.encodeUtf8 dltext)+ cspHeaderNameBS = CI.mk $ TE.encodeUtf8 cspHeaderName++insertAt :: Int -> a -> [a] -> [a]+insertAt n x xs =+ let (h, t) = Prelude.splitAt n xs+ in h ++ x : t newtype EscapedURI = EscapedURI { uri :: URI } deriving (Eq, Data, Typeable)
test/Test.hs view
@@ -5,6 +5,7 @@ {-# LANGUAGE TypeFamilies #-} import Data.Attoparsec.Text+import Data.Functor ((<$>)) import Data.List.NonEmpty import Data.Maybe import Test.Hspec@@ -14,7 +15,10 @@ import Yesod.Test data Test = Test-mkYesod "Test" [parseRoutes| / HomeR GET |]+mkYesod "Test" [parseRoutes|+/ HomeR GET+/nocsp NoCspR GET+|] instance Yesod Test @@ -23,8 +27,15 @@ cspPolicy [ScriptSrc (Self :| []), StyleSrc (Https :| [Self])] defaultLayout [whamlet|hello|] +getNoCspR :: Handler Html+getNoCspR = do+ defaultLayout [whamlet|hello|]+ main :: IO ()-main = hspec $ yesodSpec Test $ do+main = hspec $ tests >> middlewareTest++tests :: Spec+tests = yesodSpec Test $ do ydescribe "Generation" $ do yit "works" $ do let header = getCspPolicy [ScriptSrc (Self :| []), StyleSrc (Https :| [Self])]@@ -88,3 +99,13 @@ assertEq "with th" [csp|img-src 'self' https:; script-src https://foo.com|] result let url = fromJust $ escapeAndParseURI "https://foo.com" assertEq "with antiquoting" [csp|img-src 'self' https:; script-src $url|] result++middlewareTest :: Spec+middlewareTest = yesodSpecApp Test getApp $ do+ ydescribe "Middleware" $ do+ yit "works" $ do+ get NoCspR+ assertHeader "Content-Security-Policy" "frame-ancestors 'self'"+ where+ getApp = cspMiddleware [FrameAncestors (Self :| [])] <$>+ toWaiAppPlain Test
yesod-csp.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: yesod-csp-version: 0.2.2.0+version: 0.2.3.0 synopsis: Add CSP headers to Yesod apps description: Add CSP headers to Yesod apps. This helps reduce exposure to XSS attacks and bad assets. license: MIT@@ -32,6 +32,8 @@ , attoparsec , template-haskell , syb+ , wai+ , case-insensitive hs-source-dirs: src default-language: Haskell2010 ghc-options: -Wall