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:
		
							parent
							
								
									e96dfe832f
								
							
						
					
					
						commit
						4efd0242da
					
				| @ -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 | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user