Reformatting
This commit is contained in:
		@@ -25,6 +25,7 @@ executable ebook-manager
 | 
				
			|||||||
                     , Database.Schema
 | 
					                     , Database.Schema
 | 
				
			||||||
                     , Database.User
 | 
					                     , Database.User
 | 
				
			||||||
                     , Server
 | 
					                     , Server
 | 
				
			||||||
 | 
					                     , Server.Auth
 | 
				
			||||||
                     , Types
 | 
					                     , Types
 | 
				
			||||||
  -- other-extensions:
 | 
					  -- other-extensions:
 | 
				
			||||||
  build-depends:       base >=4.10 && <4.11
 | 
					  build-depends:       base >=4.10 && <4.11
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,10 +15,9 @@ import Web.FormUrlEncoded
 | 
				
			|||||||
import Database (runDB)
 | 
					import Database (runDB)
 | 
				
			||||||
import Database.User
 | 
					import Database.User
 | 
				
			||||||
import Database.Schema
 | 
					import Database.Schema
 | 
				
			||||||
import Control.Lens (view)
 | 
					import Server.Auth
 | 
				
			||||||
import Data.Generics.Product
 | 
					 | 
				
			||||||
import Servant.Auth as SA
 | 
					 | 
				
			||||||
import Servant.Auth.Server as SAS
 | 
					import Servant.Auth.Server as SAS
 | 
				
			||||||
 | 
					import Servant.Auth as SA
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
data RegisterForm = RegisterForm { username :: Username
 | 
					data RegisterForm = RegisterForm { username :: Username
 | 
				
			||||||
@@ -41,33 +40,6 @@ instance FromJSON RegisterStatus
 | 
				
			|||||||
instance FromForm RegisterForm
 | 
					instance FromForm RegisterForm
 | 
				
			||||||
instance ToForm RegisterForm
 | 
					instance ToForm RegisterForm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- generic-lens can convert similar types to this
 | 
					 | 
				
			||||||
-- I'm trying out servant-auth-server which uses a jwt style login. IIRC anyone
 | 
					 | 
				
			||||||
-- can open the jwt token and view what's inside, you just can't modify it.
 | 
					 | 
				
			||||||
--
 | 
					 | 
				
			||||||
-- Is it a problem that a human readable username and email are visible?
 | 
					 | 
				
			||||||
data SafeUser = SafeUser { email :: Email
 | 
					 | 
				
			||||||
                         , username :: Username
 | 
					 | 
				
			||||||
                         , role :: Role }
 | 
					 | 
				
			||||||
              deriving (Show, Generic)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
instance ToJSON SafeUser where
 | 
					 | 
				
			||||||
instance FromJSON SafeUser where
 | 
					 | 
				
			||||||
instance ToJWT SafeUser where
 | 
					 | 
				
			||||||
instance FromJWT SafeUser where
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
authCheck :: App -> BasicAuthData -> IO (AuthResult SafeUser)
 | 
					 | 
				
			||||||
authCheck app (BasicAuthData username password) = flip runReaderT app $
 | 
					 | 
				
			||||||
  maybe SAS.Indefinite authenticated <$> runDB (validateUser username' password')
 | 
					 | 
				
			||||||
  where
 | 
					 | 
				
			||||||
    username' = Username $ decodeUtf8 username
 | 
					 | 
				
			||||||
    password' = PlainPassword $ decodeUtf8 password
 | 
					 | 
				
			||||||
    authenticated = SAS.Authenticated . view (super @SafeUser)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type instance BasicAuthCfg = BasicAuthData -> IO (AuthResult SafeUser)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
instance FromBasicAuthData SafeUser where
 | 
					 | 
				
			||||||
  fromBasicAuthData authData authCheckFunction = authCheckFunction authData
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
type API = Auth '[SA.BasicAuth] SafeUser :> "login" :> Get '[JSON] LoginStatus
 | 
					type API = Auth '[SA.BasicAuth] SafeUser :> "login" :> Get '[JSON] LoginStatus
 | 
				
			||||||
      :<|> "register" :> ReqBody '[JSON, FormUrlEncoded] RegisterForm :> Post '[JSON] RegisterStatus
 | 
					      :<|> "register" :> ReqBody '[JSON, FormUrlEncoded] RegisterForm :> Post '[JSON] RegisterStatus
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,7 @@
 | 
				
			|||||||
module Server where
 | 
					module Server where
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import qualified API as API
 | 
					import qualified API as API
 | 
				
			||||||
import qualified API.Users as Users
 | 
					import Server.Auth (authCheck)
 | 
				
			||||||
import Servant
 | 
					import Servant
 | 
				
			||||||
import Types
 | 
					import Types
 | 
				
			||||||
import ClassyPrelude hiding (Handler)
 | 
					import ClassyPrelude hiding (Handler)
 | 
				
			||||||
@@ -31,7 +31,7 @@ server app = serveWithContext api cfg (enter server' API.handler :<|> serveDirec
 | 
				
			|||||||
  where
 | 
					  where
 | 
				
			||||||
    myKey = view (field @"jwk") app
 | 
					    myKey = view (field @"jwk") app
 | 
				
			||||||
    jwtCfg = defaultJWTSettings myKey
 | 
					    jwtCfg = defaultJWTSettings myKey
 | 
				
			||||||
    authCfg = Users.authCheck app
 | 
					    authCfg = authCheck app
 | 
				
			||||||
    cfg = jwtCfg :. defaultCookieSettings :. authCfg :. EmptyContext
 | 
					    cfg = jwtCfg :. defaultCookieSettings :. authCfg :. EmptyContext
 | 
				
			||||||
    server' :: AppM :~> Servant.Handler
 | 
					    server' :: AppM :~> Servant.Handler
 | 
				
			||||||
    server' = NT (Handler . ExceptT . try . (`runReaderT` app) . (runFileLoggingT "logs/server.log"))
 | 
					    server' = NT (Handler . ExceptT . try . (`runReaderT` app) . (runFileLoggingT "logs/server.log"))
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										46
									
								
								src/Server/Auth.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/Server/Auth.hs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
				
			|||||||
 | 
					{-# Language DataKinds #-}
 | 
				
			||||||
 | 
					{-# Language TypeFamilies #-}
 | 
				
			||||||
 | 
					{-# Language OverloadedStrings #-}
 | 
				
			||||||
 | 
					{-# Language NoImplicitPrelude #-}
 | 
				
			||||||
 | 
					{-# Language TypeOperators #-}
 | 
				
			||||||
 | 
					{-# Language DuplicateRecordFields #-}
 | 
				
			||||||
 | 
					{-# Language TypeApplications #-}
 | 
				
			||||||
 | 
					module Server.Auth where
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import ClassyPrelude
 | 
				
			||||||
 | 
					import Servant.Auth.Server as SAS
 | 
				
			||||||
 | 
					import Data.Aeson
 | 
				
			||||||
 | 
					import Database.Schema
 | 
				
			||||||
 | 
					import Database.User
 | 
				
			||||||
 | 
					import Database
 | 
				
			||||||
 | 
					import Types
 | 
				
			||||||
 | 
					import Control.Lens (view)
 | 
				
			||||||
 | 
					import Data.Generics.Product
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- generic-lens can convert similar types to this
 | 
				
			||||||
 | 
					-- I'm trying out servant-auth-server which uses a jwt style login. IIRC anyone
 | 
				
			||||||
 | 
					-- can open the jwt token and view what's inside, you just can't modify it.
 | 
				
			||||||
 | 
					--
 | 
				
			||||||
 | 
					-- Is it a problem that a human readable username and email are visible?
 | 
				
			||||||
 | 
					data SafeUser = SafeUser { email :: Email
 | 
				
			||||||
 | 
					                         , username :: Username
 | 
				
			||||||
 | 
					                         , role :: Role }
 | 
				
			||||||
 | 
					              deriving (Show, Generic)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					instance ToJSON SafeUser where
 | 
				
			||||||
 | 
					instance FromJSON SafeUser where
 | 
				
			||||||
 | 
					instance ToJWT SafeUser where
 | 
				
			||||||
 | 
					instance FromJWT SafeUser where
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type instance BasicAuthCfg = BasicAuthData -> IO (AuthResult SafeUser)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					instance FromBasicAuthData SafeUser where
 | 
				
			||||||
 | 
					  fromBasicAuthData authData authCheckFunction = authCheckFunction authData
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					authCheck :: App -> BasicAuthData -> IO (AuthResult SafeUser)
 | 
				
			||||||
 | 
					authCheck app (BasicAuthData username password) = flip runReaderT app $
 | 
				
			||||||
 | 
					  maybe SAS.Indefinite authenticated <$> runDB (validateUser username' password')
 | 
				
			||||||
 | 
					  where
 | 
				
			||||||
 | 
					    username' = Username $ decodeUtf8 username
 | 
				
			||||||
 | 
					    password' = PlainPassword $ decodeUtf8 password
 | 
				
			||||||
 | 
					    authenticated = SAS.Authenticated . view (super @SafeUser)
 | 
				
			||||||
		Reference in New Issue
	
	Block a user