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