Put writes under basic auth

This commit is contained in:
Dhananjay Balan 2023-03-05 16:46:56 +05:30
parent 2c15c67480
commit 1011ac907d
2 changed files with 35 additions and 7 deletions

View File

@ -3,27 +3,50 @@
{-# LANGUAGE TypeOperators #-} {-# LANGUAGE TypeOperators #-}
module Main where module Main where
import Database.SQLite.Simple import Database.SQLite.Simple hiding ((:.))
import Database.SQLite.Simple.QQ import Database.SQLite.Simple.QQ
import Network.Wai.Handler.Warp import Network.Wai.Handler.Warp
import Data.Proxy import Data.Proxy
import Servant import Servant
import Control.Monad.IO.Class import Control.Monad.IO.Class
import Servant.HTML.Blaze import Servant.HTML.Blaze
import qualified Data.Text as T
import Data.Text.Encoding (decodeUtf8)
import Crypto.Argon2
import Data.Text.Short (fromText, ShortText)
import Data.ByteString (ByteString)
import Api.Types import Api.Types
import qualified Parsers.KOReader as KO import qualified Parsers.KOReader as KO
import Config import Config
import Options.Applicative import Options.Applicative
data User = User
{ username :: T.Text
, password :: ByteString
} deriving (Show, Eq)
type API = Get '[HTML] Quote type API = Get '[HTML] Quote
:<|> "quotes" :> Get '[JSON] [Quote] :<|> "quotes" :> Get '[JSON] [Quote]
:<|> "quote" :> "random" :> Get '[JSON] Quote :<|> "quote" :> "random" :> Get '[JSON] Quote
:<|> "today" :> Get '[HTML] Quote :<|> "today" :> Get '[HTML] Quote
:<|> "koreader" :> ReqBody '[JSON] KO.KoHighlight :> Post '[JSON] NoContent :<|> BasicAuth "update data" User :> ("koreader" :> ReqBody '[JSON] KO.KoHighlight :> Post '[JSON] NoContent)
api :: Proxy API api :: Proxy API
api = Proxy api = Proxy
checkBasicAuth :: T.Text -> ShortText -> BasicAuthCheck User
checkBasicAuth user passhash = BasicAuthCheck $ \authData ->
let username = decodeUtf8 (basicAuthUsername authData)
password = basicAuthPassword authData
in
case user == username of
False -> return NoSuchUser
True -> case verifyEncoded passhash password of
Argon2Ok -> return $ Authorized $ User username password
_ -> return Unauthorized
initDb :: FilePath -> IO () initDb :: FilePath -> IO ()
initDb dbFile = withConnection dbFile $ \conn -> initDb dbFile = withConnection dbFile $ \conn ->
execute_ conn execute_ conn
@ -36,12 +59,13 @@ initDb dbFile = withConnection dbFile $ \conn ->
-- | TODO: readerT -- | TODO: readerT
server :: FilePath -> Server API server :: FilePath -> Server API
server dbf = randomQuote dbf :<|> listQuotes dbf :<|> randomQuote dbf :<|> randomQuote dbf :<|> addKoReader dbf server dbf = randomQuote dbf :<|> listQuotes dbf :<|> randomQuote dbf :<|> randomQuote dbf :<|> (\_ -> addKoReader dbf)
-- | API begins here -- | API begins here
randomQuote :: FilePath -> Handler Quote randomQuote :: FilePath -> Handler Quote
randomQuote db = do randomQuote db = do
qts <- (liftIO $ withConnection db $ \c -> query_ c qry) qts <- liftIO $ withConnection db $ \c -> query_ c qry
case (length qts) of case length qts of
0 -> undefined 0 -> undefined
_ -> pure (head qts) _ -> pure (head qts)
where where
@ -60,7 +84,9 @@ addKoReader db hl = do
qts = KO.parse hl qts = KO.parse hl
runApp :: AppConfig -> IO () runApp :: AppConfig -> IO ()
runApp c = run (appPort c) (serve api $ server (appDbFile c)) runApp c = run (appPort c) (serveWithContext api ctx $ server (appDbFile c))
where
ctx = checkBasicAuth (appUser c) (fromText $ appPassHash c):. EmptyContext
main :: IO () main :: IO ()
main = do main = do

View File

@ -111,7 +111,9 @@ executable quotes-api
quotes-api, quotes-api,
servant-blaze, servant-blaze,
optparse-applicative, optparse-applicative,
argon2,
text-short,
bytestring,
-- Directories containing source files. -- Directories containing source files.
hs-source-dirs: app hs-source-dirs: app