]> gitweb @ CieloNegro.org - Rakka.git/blobdiff - Rakka/Authorization.hs
Build error fix
[Rakka.git] / Rakka / Authorization.hs
index 8da8afe95a590ca44552084ee92f9a95672d17db..ccc4b36c477318177f064fdca75f79d7ab43b427 100644 (file)
@@ -2,17 +2,22 @@ module Rakka.Authorization
     ( AuthDB
     , mkAuthDB
     , isValidPair
+    , getUserList
+    , addUser
+    , delUser
     )
     where
 
-import qualified Codec.Binary.Base64 as B64
 import qualified Codec.Binary.UTF8.String as UTF8
 import           Control.Concurrent.STM
-import qualified Data.Digest.SHA1 as SHA1
+import           Control.Monad
+import           Control.Monad.Trans
+import qualified Data.ByteString as B
 import           Data.Map (Map)
 import qualified Data.Map as M hiding (Map)
 import           Data.Maybe
-import           Data.Word
+import           OpenSSL.EVP.Base64
+import           OpenSSL.EVP.Digest
 import           Rakka.SystemConfig
 import           System.Directory
 import           System.FilePath
@@ -27,7 +32,7 @@ data AuthDB
       }
 
 
-type UserMap = Map String [Word8]
+type UserMap = Map String String
 
 
 mkAuthDB :: FilePath -> IO AuthDB
@@ -42,32 +47,72 @@ mkAuthDB lsdir
                     }
 
 
-isValidPair :: AuthDB -> String -> String -> IO Bool
+isValidPair :: MonadIO m => AuthDB -> String -> String -> m Bool
 isValidPair adb name pass
-    = let hash = SHA1.hash (UTF8.encode pass)
-      in
-        atomically $ do m <- readTVar (adbUserMap adb)
-                        return (M.lookup name m == Just hash)
+    = liftIO $ do sha1 <- return . fromJust =<< getDigestByName "SHA1"
+                  let hash = digestBS sha1 $ B.pack $ UTF8.encode pass
+                  atomically $ do m <- readTVar (adbUserMap adb)
+                                  return (M.lookup name m == Just hash)
+
+
+getUserList :: MonadIO m => AuthDB -> m [String]
+getUserList adb
+    = liftIO $
+      atomically $
+      do m <- readTVar (adbUserMap adb)
+        return (M.keys m)
+
+
+addUser :: MonadIO m => AuthDB -> String -> String -> m ()
+addUser adb name pass
+    = liftIO $
+      do sha1 <- return . fromJust =<< getDigestByName "SHA1"
+        let hash = digestBS sha1 $ B.pack $ UTF8.encode pass
+        m <- atomically $ do m <- readTVar (adbUserMap adb)
+                             let m' = M.insert name hash m
+                             writeTVar (adbUserMap adb) m'
+                             return m'
+        saveUserMap (adbFilePath adb) m
+
+
+delUser :: MonadIO m => AuthDB -> String -> m ()
+delUser adb name
+    = liftIO $
+      do m <- atomically $ do m <- readTVar (adbUserMap adb)
+                             let m' = M.delete name m
+                             writeTVar (adbUserMap adb) m'
+                             return m'
+        saveUserMap (adbFilePath adb) m
 
 
 loadUserMap :: FilePath -> IO UserMap
 loadUserMap path
     = do exist <- doesFileExist path
-         if exist then
-             readFile path
-                >>=
-                return . initMap . M.fromList . map decodePair . fromJust . deserializeStringPairs
-           else
-             return M.empty
+         m     <- if exist then
+                      liftM (M.fromList . map decodePair . fromJust . deserializeStringPairs)
+                            (readFile path)
+                  else
+                      return M.empty
+         sha1  <- return . fromJust =<< getDigestByName "SHA1"
+         return (initMap sha1 m)
     where
-      decodePair :: (String, String) -> (String, [Word8])
+      decodePair :: (String, String) -> (String, String)
       decodePair (name, b64Hash)
-          = (UTF8.decodeString name, B64.decode b64Hash)
+          = (UTF8.decodeString name, decodeBase64 b64Hash)
 
-      initMap :: UserMap -> UserMap
-      initMap m
+      initMap :: Digest -> UserMap -> UserMap
+      initMap sha1 m
           | M.null m  = let name = "root"
-                            hash = SHA1.hash []
+                            hash = digest sha1 ""
                         in
                           M.singleton name hash
           | otherwise = m
+
+
+saveUserMap :: FilePath -> UserMap -> IO ()
+saveUserMap path m
+    = writeFile path $ serializeStringPairs $ map encodePair $ M.toList m
+    where
+    encodePair :: (String, String) -> (String, String)
+    encodePair (name, hash)
+       = (UTF8.encodeString name, encodeBase64 hash)