From d658442d22fc79829372b79be5b2baf94c151ca5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Hamal=20Dvo=C5=99=C3=A1k?= <mordae@anilinux.org>
Date: Sat, 26 Sep 2020 19:32:50 +0200
Subject: [PATCH] Remove Configurator dependency
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Jan Hamal Dvořák <mordae@anilinux.org>
---
 hikaru.cabal         |  4 +---
 lib/Hikaru/Action.hs | 47 +++++++++++++++++++++++++++++++-------------
 lib/Hikaru/CSRF.hs   | 11 ++++++++---
 package.yaml         |  1 -
 4 files changed, 42 insertions(+), 21 deletions(-)

diff --git a/hikaru.cabal b/hikaru.cabal
index b87781b..6a41019 100644
--- a/hikaru.cabal
+++ b/hikaru.cabal
@@ -4,7 +4,7 @@ cabal-version: 1.12
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: e297323a7b6cecac97f8dd18ae01703782f331a12328a6934ad0a62d7cb0daf3
+-- hash: 5ac50160b1396ef3e336b16f172ed703e020f37d729d4384049493c620bd5167
 
 name:           hikaru
 version:        0.1.0.0
@@ -55,7 +55,6 @@ library
     , binary >=0.8 && <0.9
     , bytestring >=0.10 && <0.11
     , case-insensitive >=1.2 && <1.3
-    , configurator >=0.3 && <0.4
     , containers >=0.6 && <0.7
     , cookie >=0.4 && <0.5
     , cryptonite >=0.26 && <0.27
@@ -94,7 +93,6 @@ test-suite spec
     , binary >=0.8 && <0.9
     , bytestring >=0.10 && <0.11
     , case-insensitive >=1.2 && <1.3
-    , configurator >=0.3 && <0.4
     , containers >=0.6 && <0.7
     , cookie >=0.4 && <0.5
     , cryptonite >=0.26 && <0.27
diff --git a/lib/Hikaru/Action.hs b/lib/Hikaru/Action.hs
index d13e91d..107b35f 100644
--- a/lib/Hikaru/Action.hs
+++ b/lib/Hikaru/Action.hs
@@ -89,6 +89,8 @@ module Hikaru.Action
   , dropCaches
 
   -- ** Configuration
+  , updateConfig
+  , updateConfigFromEnv
   , getConfigMaybe
   , getConfigDefault
 
@@ -108,8 +110,6 @@ where
 
   import qualified Data.ByteString as BS
   import qualified Data.ByteString.Lazy as LBS
-  import qualified Data.Configurator as Cfg
-  import qualified Data.Configurator.Types as Cfg
   import qualified Data.Map.Strict as Map
   import qualified Data.Text.Lazy as LT
   import qualified Network.Wai.Parse as Parse
@@ -128,6 +128,7 @@ where
   import Network.HTTP.Types.Method
   import Network.HTTP.Types.Status
   import Network.Wai
+  import System.Environment
   import System.IO.Unsafe
   import Web.Cookie
 
@@ -194,7 +195,7 @@ where
   data ActionEnv
     = ActionEnv
       { aeRequest      :: Request
-      , aeConfig       :: Cfg.Config
+      , aeConfig       :: IORef (Map.Map Text String)
       , aeBody         :: IORef RequestBody
       , aeRespStatus   :: IORef Status
       , aeRespHeaders  :: IORef ResponseHeaders
@@ -264,10 +265,10 @@ where
   -- |
   -- Create the initial action environment from the 'Request'.
   --
-  makeActionEnv :: Cfg.Config -> Request -> IO ActionEnv
-  makeActionEnv cfg req =
+  makeActionEnv :: Request -> IO ActionEnv
+  makeActionEnv req =
     ActionEnv <$> pure req
-              <*> pure cfg
+              <*> newIORef Map.empty
               <*> newIORef BodyUnparsed
               <*> newIORef status200
               <*> newIORef []
@@ -1095,24 +1096,42 @@ where
   -- Configuration -----------------------------------------------------------
 
 
+  -- |
+  -- Update configuration using supplied key-value pairs.
+  --
+  -- Request starts with an empty configuration.
+  --
+  updateConfig :: (MonadAction m) => [(Text, String)] -> m ()
+  updateConfig = modifyActionField aeConfig . Map.union . Map.fromList
+
+
+  -- |
+  -- Update configuration using the program environment.
+  --
+  updateConfigFromEnv :: (MonadAction m) => m ()
+  updateConfigFromEnv = do
+    env <- liftIO $ getEnvironment
+
+    let conv (k, v) = (cs k, v)
+     in updateConfig (map conv env)
+
+
   -- |
   -- Lookup a configuration value.
   --
-  getConfigMaybe :: (MonadAction m, Cfg.Configured a) => Text -> m (Maybe a)
+  getConfigMaybe :: (MonadAction m, Read a) => Text -> m (Maybe a)
   getConfigMaybe name = do
-    cfg <- aeConfig <$> getActionEnv
-    liftIO do
-      Cfg.lookup cfg name
+    cfg <- getActionField aeConfig
+    return $ readMaybe =<< Map.lookup name cfg
 
 
   -- |
   -- Lookup a configuration value with a fallback to return if not found.
   --
-  getConfigDefault :: (MonadAction m, Cfg.Configured a) => Text -> a -> m a
+  getConfigDefault :: (MonadAction m, Read a) => Text -> a -> m a
   getConfigDefault name value = do
-    cfg <- aeConfig <$> getActionEnv
-    liftIO do
-      Cfg.lookupDefault value cfg name
+    cfg <- getActionField aeConfig
+    return $ fromMaybe value $ readMaybe =<< Map.lookup name cfg
 
 
   -- Finalizing --------------------------------------------------------------
diff --git a/lib/Hikaru/CSRF.hs b/lib/Hikaru/CSRF.hs
index 52e57c6..c8821eb 100644
--- a/lib/Hikaru/CSRF.hs
+++ b/lib/Hikaru/CSRF.hs
@@ -29,10 +29,12 @@ where
   -- |
   -- Generate an anti-CSRF token to be used with forms.
   --
+  -- Uses the @CSRF_SECRET@ configuration key.
+  --
   generateToken :: (MonadAction m) => m Text
   generateToken = do
     now    <- getTimestamp
-    secret <- getConfigDefault "csrf.secret" ""
+    secret <- getConfigDefault "CSRF_SECRET" ""
 
     let signature = sign now secret
      in return $ mconcat [ show now, ":", signature ]
@@ -41,6 +43,9 @@ where
   -- |
   -- Verify that the anti-CSRF token is currently valid.
   --
+  -- Uses the @CSRF_SECRET@ and @CSRF_VALIDITY@ configuration keys.
+  -- Valididy defaults to 86400 seconds (24 hours).
+  --
   isTokenValid :: (MonadAction m) => Text -> m Bool
   isTokenValid token = do
     case splitOn ":" token of
@@ -48,8 +53,8 @@ where
         case readMaybe (cs time) of
           Just (timestamp :: Int64) -> do
             now    <- getTimestamp
-            valid  <- getConfigDefault "csrf.validity" 86400
-            secret <- getConfigDefault "csrf.secret" ""
+            valid  <- getConfigDefault "CSRF_VALIDITY" 86400
+            secret <- getConfigDefault "CSRF_SECRET" ""
 
             if timestamp + valid >= now
                then return (sign timestamp secret == signature)
diff --git a/package.yaml b/package.yaml
index d493b40..0680073 100644
--- a/package.yaml
+++ b/package.yaml
@@ -49,7 +49,6 @@ dependencies:
   - binary             >= 0.8  && <0.9
   - bytestring         >= 0.10 && <0.11
   - case-insensitive   >= 1.2  && <1.3
-  - configurator       >= 0.3  && <0.4
   - containers         >= 0.6  && <0.7
   - cookie             >= 0.4  && <0.5
   - cryptonite         >= 0.26 && <0.27
-- 
GitLab