1 {-# LANGUAGE DataKinds #-}
    2 module Model.Audit
    3   ( module 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 Has
   14 import Service.DB
   15 import HTTP.Request
   16 import Model.Id.Types
   17 import Model.Party.Types
   18 import 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