mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-17 04:24:35 +03:00
40 lines
1.3 KiB
Haskell
40 lines
1.3 KiB
Haskell
|
module Network.HTTP.Client.Blocklisting
|
||
|
( block,
|
||
|
Blocklist (..),
|
||
|
)
|
||
|
where
|
||
|
|
||
|
import Hasura.Prelude
|
||
|
import Net.IPv4 qualified as IPv4
|
||
|
import Net.IPv6 qualified as IPv6
|
||
|
import Network.HTTP.Client.Restricted qualified as Restricted
|
||
|
import Network.Socket
|
||
|
|
||
|
data Blocklist = Blocklist
|
||
|
{ ipv4Blocklist :: [IPv4.IPv4Range],
|
||
|
ipv6Blocklist :: [IPv6.IPv6Range]
|
||
|
}
|
||
|
deriving (Show, Generic)
|
||
|
|
||
|
instance Semigroup Blocklist where
|
||
|
Blocklist ipv4Lst1 ipv6Lst1 <> Blocklist ipv4Lst2 ipv6Lst2 = Blocklist (ipv4Lst1 ++ ipv4Lst2) (ipv6Lst1 ++ ipv6Lst2)
|
||
|
|
||
|
instance Monoid Blocklist where
|
||
|
mempty = Blocklist [] []
|
||
|
|
||
|
-- | Determine whether the given address is blocked by the given blocklist.
|
||
|
-- NOTE: Only restricts IPv4 and IPv6 addresses. Other address families are
|
||
|
-- not restricted.
|
||
|
block :: Blocklist -> AddrInfo -> Restricted.Decision
|
||
|
block blocklist addr =
|
||
|
if sockAddrInBlocklist $ addrAddress addr
|
||
|
then Restricted.Deny
|
||
|
else Restricted.Allow
|
||
|
where
|
||
|
sockAddrInBlocklist = \case
|
||
|
(SockAddrInet _ hostAddr) -> any (IPv4.member $ ipv4Addr hostAddr) (ipv4Blocklist blocklist)
|
||
|
(SockAddrInet6 _ _ hostAddr6 _) -> any (IPv6.member $ ipv6Addr hostAddr6) (ipv6Blocklist blocklist)
|
||
|
_ -> False
|
||
|
ipv4Addr = IPv4.fromTupleOctets . hostAddressToTuple
|
||
|
ipv6Addr = IPv6.fromTupleWord32s
|