1 {-# LANGUAGE TemplateHaskell, QuasiQuotes, RecordWildCards, DataKinds #-} 2 module Databrary.Model.Audit 3 ( module Databrary.Model.Audit.Types 4 , MonadAudit 5 , getRemoteIp 6 , getAuditIdentity 7 ) where 8 9 import Data.Maybe (fromMaybe) 10 import Database.PostgreSQL.Typed.Inet (PGInet(..), sockAddrPGInet) 11 import Network.Wai (remoteHost) 12 13 import Databrary.Has 14 import Databrary.Service.DB 15 import Databrary.HTTP.Request 16 import Databrary.Model.Id.Types 17 import Databrary.Model.Party.Types 18 import Databrary.Model.Audit.Types 19 20 -- | A context which carries enough information to enter audit data along with 21 -- viewing or data modification actions. The request allows us to get the web requests 22 -- IP. The party id provides us with the party who is performing auditable actions. 23 -- The DB gives us a connection to create data in the audit tables. 24 type MonadAudit c m = (MonadHasRequest c m, MonadHas (Id Party) c m, MonadDB c m) 25 26 -- | Retrieve the IP from the web request, if any is present 27 getRemoteIp :: MonadHasRequest c m => m PGInet 28 getRemoteIp = peeks (fromMaybe (PGInet 0 32) . sockAddrPGInet . remoteHost) 29 30 -- | Build up an identity summarizing the party and IP during a given action 31 getAuditIdentity :: (MonadHasRequest c m, MonadHas (Id Party) c m) => m AuditIdentity 32 getAuditIdentity = AuditIdentity <$> peek <*> getRemoteIp