web: Modify the --cors option to require a specific origin

- Modified the cors option to require a String
- Moved the logic to build the cors policy to WebOptions.hs
- Specify the --cors "*" example in the cors option help
- Added utf8-string dependency to convert a String into a ByteString
This commit is contained in:
Alejandro García Montoro 2019-10-07 11:29:06 +02:00 committed by Simon Michael
parent e96dfe832f
commit 4efd0242da
4 changed files with 33 additions and 12 deletions

View File

@ -10,7 +10,6 @@ module Hledger.Web.Application
import Data.IORef (newIORef, writeIORef) import Data.IORef (newIORef, writeIORef)
import Network.Wai.Middleware.RequestLogger (logStdoutDev, logStdout) import Network.Wai.Middleware.RequestLogger (logStdoutDev, logStdout)
import Network.Wai.Middleware.Cors
import Network.HTTP.Client (defaultManagerSettings) import Network.HTTP.Client (defaultManagerSettings)
import Network.HTTP.Conduit (newManager) import Network.HTTP.Conduit (newManager)
import Yesod.Default.Config import Yesod.Default.Config
@ -24,7 +23,7 @@ import Hledger.Web.Handler.UploadR
import Hledger.Web.Handler.JournalR import Hledger.Web.Handler.JournalR
import Hledger.Web.Handler.RegisterR import Hledger.Web.Handler.RegisterR
import Hledger.Web.Import import Hledger.Web.Import
import Hledger.Web.WebOptions (WebOpts(serve_,serve_api_,cors_)) import Hledger.Web.WebOptions (WebOpts(serve_,serve_api_), corsPolicy)
-- This line actually creates our YesodDispatch instance. It is the second half -- This line actually creates our YesodDispatch instance. It is the second half
-- of the call to mkYesodData which occurs in Foundation.hs. Please see the -- of the call to mkYesodData which occurs in Foundation.hs. Please see the
@ -39,13 +38,11 @@ makeApplication :: WebOpts -> Journal -> AppConfig DefaultEnv Extra -> IO Applic
makeApplication opts' j' conf' = do makeApplication opts' j' conf' = do
foundation <- makeFoundation conf' opts' foundation <- makeFoundation conf' opts'
writeIORef (appJournal foundation) j' writeIORef (appJournal foundation) j'
(logWare . corsWare) <$> toWaiApp foundation (logWare . (corsPolicy opts')) <$> toWaiApp foundation
where where
logWare | development = logStdoutDev logWare | development = logStdoutDev
| serve_ opts' || serve_api_ opts' = logStdout | serve_ opts' || serve_api_ opts' = logStdout
| otherwise = id | otherwise = id
corsWare | cors_ opts' = simpleCors
| otherwise = id
makeFoundation :: AppConfig DefaultEnv Extra -> WebOpts -> IO App makeFoundation :: AppConfig DefaultEnv Extra -> WebOpts -> IO App
makeFoundation conf opts' = do makeFoundation conf opts' = do

View File

@ -4,6 +4,7 @@ module Hledger.Web.WebOptions where
import Data.ByteString (ByteString) import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as BC import qualified Data.ByteString.Char8 as BC
import Data.ByteString.UTF8 (fromString)
import Data.CaseInsensitive (CI, mk) import Data.CaseInsensitive (CI, mk)
import Control.Monad (join) import Control.Monad (join)
import Data.Default (Default(def)) import Data.Default (Default(def))
@ -11,6 +12,8 @@ import Data.Maybe (fromMaybe)
import qualified Data.Text as T import qualified Data.Text as T
import Data.Text (Text) import Data.Text (Text)
import System.Environment (getArgs) import System.Environment (getArgs)
import Network.Wai as WAI
import Network.Wai.Middleware.Cors
import Hledger.Cli hiding (progname, version) import Hledger.Cli hiding (progname, version)
import Hledger.Web.Settings (defhost, defport, defbaseurl) import Hledger.Web.Settings (defhost, defport, defbaseurl)
@ -35,10 +38,11 @@ webflags =
["serve-api"] ["serve-api"]
(setboolopt "serve-api") (setboolopt "serve-api")
"like --serve, but serve only the JSON web API, without the server-side web UI" "like --serve, but serve only the JSON web API, without the server-side web UI"
, flagNone , flagReq
["cors"] ["cors"]
(setboolopt "cors") (\s opts -> Right $ setopt "cors" s opts)
("allow cross-origin requests, setting the Access-Control-Allow-Origin HTTP header to *") "ORIGIN"
("allow cross-origin requests from the specified origin; setting ORIGIN to \"*\" allows requests from any origin")
, flagReq , flagReq
["host"] ["host"]
(\s opts -> Right $ setopt "host" s opts) (\s opts -> Right $ setopt "host" s opts)
@ -98,7 +102,7 @@ webmode =
data WebOpts = WebOpts data WebOpts = WebOpts
{ serve_ :: Bool { serve_ :: Bool
, serve_api_ :: Bool , serve_api_ :: Bool
, cors_ :: Bool , cors_ :: Maybe String
, host_ :: String , host_ :: String
, port_ :: Int , port_ :: Int
, base_url_ :: String , base_url_ :: String
@ -109,7 +113,7 @@ data WebOpts = WebOpts
} deriving (Show) } deriving (Show)
defwebopts :: WebOpts defwebopts :: WebOpts
defwebopts = WebOpts def def def def def def def [CapView, CapAdd] Nothing def defwebopts = WebOpts def def Nothing def def def def [CapView, CapAdd] Nothing def
instance Default WebOpts where def = defwebopts instance Default WebOpts where def = defwebopts
@ -131,7 +135,7 @@ rawOptsToWebOpts rawopts =
defwebopts defwebopts
{ serve_ = boolopt "serve" rawopts { serve_ = boolopt "serve" rawopts
, serve_api_ = boolopt "serve-api" rawopts , serve_api_ = boolopt "serve-api" rawopts
, cors_ = boolopt "cors" rawopts , cors_ = maybestringopt "cors" rawopts
, host_ = h , host_ = h
, port_ = p , port_ = p
, base_url_ = b , base_url_ = b
@ -172,3 +176,21 @@ capabilityFromBS "view" = Right CapView
capabilityFromBS "add" = Right CapAdd capabilityFromBS "add" = Right CapAdd
capabilityFromBS "manage" = Right CapManage capabilityFromBS "manage" = Right CapManage
capabilityFromBS x = Left x capabilityFromBS x = Left x
simplePolicyWithOrigin :: Origin -> CorsResourcePolicy
simplePolicyWithOrigin origin =
simpleCorsResourcePolicy { corsOrigins = Just ([origin], False) }
corsPolicyFromString :: String -> WAI.Middleware
corsPolicyFromString origin =
let
policy = case origin of
"*" -> simpleCorsResourcePolicy
url -> simplePolicyWithOrigin $ fromString url
in
cors (const $ Just policy)
corsPolicy :: WebOpts -> (Application -> Application)
corsPolicy opts =
maybe id corsPolicyFromString $ cors_ opts

View File

@ -4,7 +4,7 @@ cabal-version: 1.12
-- --
-- see: https://github.com/sol/hpack -- see: https://github.com/sol/hpack
-- --
-- hash: bb22226fe2d7562c91dc7dabb7767a786db0ea4441bb79b9016c414c0d5edf59 -- hash: 4595326c17d463479b0d80c19012ffd367ef2cedbbdee610e8792fd88d4e4c4c
name: hledger-web name: hledger-web
version: 1.15.99 version: 1.15.99
@ -183,6 +183,7 @@ library
, text >=1.2 , text >=1.2
, time >=1.5 , time >=1.5
, transformers , transformers
, utf8-string
, wai , wai
, wai-cors , wai-cors
, wai-extra , wai-extra

View File

@ -129,6 +129,7 @@ library:
- text >=1.2 - text >=1.2
- time >=1.5 - time >=1.5
- transformers - transformers
- utf8-string
- wai - wai
- wai-extra - wai-extra
- wai-handler-launch >=1.3 - wai-handler-launch >=1.3