Switch to text, add code for basic auth checking

This commit is contained in:
osmarks 2017-09-17 19:31:56 +01:00
parent 49a24c11ed
commit e2e9900257
3 changed files with 41 additions and 11 deletions

View File

@ -29,6 +29,9 @@ executable pastecan
, containers , containers
, string-conversions , string-conversions
, monad-logger , monad-logger
, pwstore-fast
, text
, bytestring
default-language: Haskell2010 default-language: Haskell2010
other-modules: Model other-modules: Model
, API , API

View File

@ -6,17 +6,22 @@ module API where
import Servant import Servant
import Control.Monad.Except import Control.Monad.Except
import Database.Persist.Sqlite import Database.Persist.Sqlite
import Data.String.Conversions
import Control.Monad.Logger import Control.Monad.Logger
import Crypto.PasswordStore
import qualified Data.Text as T
import Data.Text (Text(..))
import Data.Text.Encoding
import Network.Wai.Handler.Warp as Warp import Network.Wai.Handler.Warp as Warp
import Model import Model
import Config import Config
type GetPasteAPI = type GetPasteAPI =
Capture "username" String :> Capture "pasteName" String :> Get '[JSON] Paste Capture "username" Text :> Capture "pasteName" Text :> Get '[JSON] Paste
:<|> "raw" :> Capture "username" String :> Capture "pasteName" String :> Get '[PlainText] String :<|> "raw" :> Capture "username" Text :> Capture "pasteName" Text :> Get '[PlainText] Text
type API = GetPasteAPI type API = GetPasteAPI
@ -33,15 +38,33 @@ justOrError e m =
justOr404 :: App (Maybe a) -> App a justOr404 :: App (Maybe a) -> App a
justOr404 = justOrError err404 justOr404 = justOrError err404
getPasteData :: String -> String -> App Paste basicAuthCheck :: HandlerConfig -> BasicAuthCheck User
basicAuthCheck HandlerConfig{db = db} =
BasicAuthCheck check
where
check :: BasicAuthData -> IO (BasicAuthResult User)
check (BasicAuthData username suppliedPassword) = do
-- Annoyingly, we can't use the App monad here.
userEntity <- flip runSqlPool db $ getBy $ Username (decodeUtf8 username)
case userEntity of
Just (Entity _ userData) -> do
let correctPassword = encodeUtf8 $ userPassword userData
if verifyPassword suppliedPassword correctPassword then
return $ Authorized userData
else
return BadPassword
Nothing -> return NoSuchUser
getPasteData :: Text -> Text -> App Paste
getPasteData username name = do getPasteData username name = do
userEntity <- justOr404 $ runDB $ getBy $ Username username userEntity <- justOr404 $ runDB $ getBy $ Username username
let (Entity uid _) = userEntity let (Entity uid _) = userEntity
pasteEntity <- justOr404 $ runDB $ selectFirst [PasteParent ==. uid, PasteName ==. name] [] pasteEntity <- justOr404 $ runDB $ getBy (PasteNamePoster name uid)
let (Entity _ paste) = pasteEntity let (Entity _ paste) = pasteEntity
return paste return paste
getPasteRaw :: String -> String -> App String getPasteRaw :: Text -> Text -> App Text
getPasteRaw u n = pasteContent <$> getPasteData u n getPasteRaw u n = pasteContent <$> getPasteData u n
server :: HandlerConfig -> Server API server :: HandlerConfig -> Server API
@ -52,7 +75,7 @@ proxy = Proxy
mkApp :: FilePath -> IO Application mkApp :: FilePath -> IO Application
mkApp path = do mkApp path = do
pool <- runStderrLoggingT $ createSqlitePool (cs path) 5 pool <- runStderrLoggingT $ createSqlitePool (T.pack path) 5
runSqlPool doMigrations pool runSqlPool doMigrations pool
let cfg = HandlerConfig pool let cfg = HandlerConfig pool
return $ serve proxy (server cfg) return $ serve proxy (server cfg)

View File

@ -16,20 +16,24 @@ import GHC.Generics
import Database.Persist import Database.Persist
import Database.Persist.Sql import Database.Persist.Sql
import Database.Persist.TH import Database.Persist.TH
import qualified Data.Text as T
import Data.Text (Text(..))
import PasteType import PasteType
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase| share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
User json User json
username String username Text
password Text
Username username Username username
deriving Show Generic deriving Show Generic
Paste json Paste json
parent UserId poster UserId
name String name Text
content String content Text
type PasteType type PasteType
PasteNamePoster name poster
deriving Show Generic deriving Show Generic
|] |]