{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
-- Disabling for this module, as Getters have a functor
-- constraint that GHC is complaining about.
{-# OPTIONS_GHC -Wno-redundant-constraints #-}

-- This file is part of the Wire Server implementation.
--
-- Copyright (C) 2022 Wire Swiss GmbH <opensource@wire.com>
--
-- This program is free software: you can redistribute it and/or modify it under
-- the terms of the GNU Affero General Public License as published by the Free
-- Software Foundation, either version 3 of the License, or (at your option) any
-- later version.
--
-- This program is distributed in the hope that it will be useful, but WITHOUT
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-- FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
-- details.
--
-- You should have received a copy of the GNU Affero General Public License along
-- with this program. If not, see <https://www.gnu.org/licenses/>.

module Data.ZAuth.Token
  ( -- * Token
    Token,
    signature,
    header,
    body,
    mkToken,

    -- * Header
    Header,
    version,
    key,
    time,
    typ,
    tag,
    mkHeader,
    Type (..),
    Tag (..),

    -- * Access body
    Access,
    userId,
    clientId,
    connection,
    mkAccess,

    -- * User body
    User,
    user,
    client,
    rand,
    mkUser,

    -- * Bot body
    Bot,
    prov,
    bot,
    conv,
    mkBot,

    -- * Provider body
    Provider,
    provider,
    mkProvider,

    -- * LegalHold body
    LegalHoldUser,
    legalHoldUser,
    mkLegalHoldUser,
    LegalHoldAccess,
    legalHoldAccess,
    mkLegalHoldAccess,
    writeData,
  )
where

import Control.Error
import Control.Lens
import Data.Attoparsec.ByteString (takeLazyByteString)
import Data.ByteString.Base64.URL
import Data.ByteString.Builder (Builder, byteString, char8)
import Data.ByteString.Conversion
import Data.ByteString.Lazy (toStrict)
import Data.ByteString.Lazy.Char8 (break, drop, split)
import Data.UUID
import Imports hiding (break, drop)
import Sodium.Crypto.Sign (Signature (..))

data Type
  = -- | Access (Used as short-lived token for Users)
    A
  | -- | User (Used as a cookie for Users to refresh access tokens)
    U
  | -- | Bot
    B
  | -- | Provider
    P
  | -- | LegalHold Access (Used as short-lived token for LegalHold Service)
    LA
  | -- | LegalHold User (Used as a cookie for LegalHold Service to refresh access tokens)
    LU
  deriving (Type -> Type -> Bool
(Type -> Type -> Bool) -> (Type -> Type -> Bool) -> Eq Type
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Type -> Type -> Bool
== :: Type -> Type -> Bool
$c/= :: Type -> Type -> Bool
/= :: Type -> Type -> Bool
Eq, Int -> Type -> ShowS
[Type] -> ShowS
Type -> String
(Int -> Type -> ShowS)
-> (Type -> String) -> ([Type] -> ShowS) -> Show Type
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Type -> ShowS
showsPrec :: Int -> Type -> ShowS
$cshow :: Type -> String
show :: Type -> String
$cshowList :: [Type] -> ShowS
showList :: [Type] -> ShowS
Show)

-- | Tag: Tokens for Users with no tag are refreshable themselves and called "UserToken"
-- Tokens for Users with the tag 'S' are non-refreshable themselves and called "SessionToken"
-- FUTUREWORK: rename 'S' to 'SessionTag' for clarity
data Tag = S deriving (Tag -> Tag -> Bool
(Tag -> Tag -> Bool) -> (Tag -> Tag -> Bool) -> Eq Tag
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Tag -> Tag -> Bool
== :: Tag -> Tag -> Bool
$c/= :: Tag -> Tag -> Bool
/= :: Tag -> Tag -> Bool
Eq, Int -> Tag -> ShowS
[Tag] -> ShowS
Tag -> String
(Int -> Tag -> ShowS)
-> (Tag -> String) -> ([Tag] -> ShowS) -> Show Tag
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Tag -> ShowS
showsPrec :: Int -> Tag -> ShowS
$cshow :: Tag -> String
show :: Tag -> String
$cshowList :: [Tag] -> ShowS
showList :: [Tag] -> ShowS
Show)

data Token a = Token
  { forall a. Token a -> Signature
_signature :: !Signature,
    forall a. Token a -> Header
_header :: !Header,
    forall a. Token a -> a
_body :: !a
  }
  deriving (Token a -> Token a -> Bool
(Token a -> Token a -> Bool)
-> (Token a -> Token a -> Bool) -> Eq (Token a)
forall a. Eq a => Token a -> Token a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Token a -> Token a -> Bool
== :: Token a -> Token a -> Bool
$c/= :: forall a. Eq a => Token a -> Token a -> Bool
/= :: Token a -> Token a -> Bool
Eq, Int -> Token a -> ShowS
[Token a] -> ShowS
Token a -> String
(Int -> Token a -> ShowS)
-> (Token a -> String) -> ([Token a] -> ShowS) -> Show (Token a)
forall a. Show a => Int -> Token a -> ShowS
forall a. Show a => [Token a] -> ShowS
forall a. Show a => Token a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Token a -> ShowS
showsPrec :: Int -> Token a -> ShowS
$cshow :: forall a. Show a => Token a -> String
show :: Token a -> String
$cshowList :: forall a. Show a => [Token a] -> ShowS
showList :: [Token a] -> ShowS
Show)

-- FUTUREWORK: maybe refactor to
-- data Header (t :: Type) =
--      Header { ... everything except _typ ...} ?
data Header = Header
  { Header -> Int
_version :: !Int,
    Header -> Int
_key :: !Int,
    Header -> Integer
_time :: !Integer,
    Header -> Type
_typ :: !Type,
    Header -> Maybe Tag
_tag :: Maybe Tag
  }
  deriving (Header -> Header -> Bool
(Header -> Header -> Bool)
-> (Header -> Header -> Bool) -> Eq Header
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Header -> Header -> Bool
== :: Header -> Header -> Bool
$c/= :: Header -> Header -> Bool
/= :: Header -> Header -> Bool
Eq, Int -> Header -> ShowS
[Header] -> ShowS
Header -> String
(Int -> Header -> ShowS)
-> (Header -> String) -> ([Header] -> ShowS) -> Show Header
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Header -> ShowS
showsPrec :: Int -> Header -> ShowS
$cshow :: Header -> String
show :: Header -> String
$cshowList :: [Header] -> ShowS
showList :: [Header] -> ShowS
Show)

data Access = Access
  { Access -> UUID
_userId :: !UUID,
    Access -> Maybe Text
_clientId :: Maybe Text,
    -- | 'ConnId' is derived from this.
    Access -> Word64
_connection :: !Word64
  }
  deriving (Access -> Access -> Bool
(Access -> Access -> Bool)
-> (Access -> Access -> Bool) -> Eq Access
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Access -> Access -> Bool
== :: Access -> Access -> Bool
$c/= :: Access -> Access -> Bool
/= :: Access -> Access -> Bool
Eq, Int -> Access -> ShowS
[Access] -> ShowS
Access -> String
(Int -> Access -> ShowS)
-> (Access -> String) -> ([Access] -> ShowS) -> Show Access
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Access -> ShowS
showsPrec :: Int -> Access -> ShowS
$cshow :: Access -> String
show :: Access -> String
$cshowList :: [Access] -> ShowS
showList :: [Access] -> ShowS
Show)

data User = User
  { User -> UUID
_user :: !UUID,
    User -> Maybe Text
_client :: Maybe Text,
    User -> Word32
_rand :: !Word32
  }
  deriving (User -> User -> Bool
(User -> User -> Bool) -> (User -> User -> Bool) -> Eq User
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: User -> User -> Bool
== :: User -> User -> Bool
$c/= :: User -> User -> Bool
/= :: User -> User -> Bool
Eq, Int -> User -> ShowS
[User] -> ShowS
User -> String
(Int -> User -> ShowS)
-> (User -> String) -> ([User] -> ShowS) -> Show User
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> User -> ShowS
showsPrec :: Int -> User -> ShowS
$cshow :: User -> String
show :: User -> String
$cshowList :: [User] -> ShowS
showList :: [User] -> ShowS
Show)

data Bot = Bot
  { Bot -> UUID
_prov :: !UUID,
    Bot -> UUID
_bot :: !UUID,
    Bot -> UUID
_conv :: !UUID
  }
  deriving (Bot -> Bot -> Bool
(Bot -> Bot -> Bool) -> (Bot -> Bot -> Bool) -> Eq Bot
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Bot -> Bot -> Bool
== :: Bot -> Bot -> Bool
$c/= :: Bot -> Bot -> Bool
/= :: Bot -> Bot -> Bool
Eq, Int -> Bot -> ShowS
[Bot] -> ShowS
Bot -> String
(Int -> Bot -> ShowS)
-> (Bot -> String) -> ([Bot] -> ShowS) -> Show Bot
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Bot -> ShowS
showsPrec :: Int -> Bot -> ShowS
$cshow :: Bot -> String
show :: Bot -> String
$cshowList :: [Bot] -> ShowS
showList :: [Bot] -> ShowS
Show)

newtype Provider = Provider
  { Provider -> UUID
_provider :: UUID
  }
  deriving (Provider -> Provider -> Bool
(Provider -> Provider -> Bool)
-> (Provider -> Provider -> Bool) -> Eq Provider
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Provider -> Provider -> Bool
== :: Provider -> Provider -> Bool
$c/= :: Provider -> Provider -> Bool
/= :: Provider -> Provider -> Bool
Eq, Int -> Provider -> ShowS
[Provider] -> ShowS
Provider -> String
(Int -> Provider -> ShowS)
-> (Provider -> String) -> ([Provider] -> ShowS) -> Show Provider
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Provider -> ShowS
showsPrec :: Int -> Provider -> ShowS
$cshow :: Provider -> String
show :: Provider -> String
$cshowList :: [Provider] -> ShowS
showList :: [Provider] -> ShowS
Show)

newtype LegalHoldUser = LegalHoldUser
  { LegalHoldUser -> User
_legalHoldUser :: User
  }
  deriving (LegalHoldUser -> LegalHoldUser -> Bool
(LegalHoldUser -> LegalHoldUser -> Bool)
-> (LegalHoldUser -> LegalHoldUser -> Bool) -> Eq LegalHoldUser
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: LegalHoldUser -> LegalHoldUser -> Bool
== :: LegalHoldUser -> LegalHoldUser -> Bool
$c/= :: LegalHoldUser -> LegalHoldUser -> Bool
/= :: LegalHoldUser -> LegalHoldUser -> Bool
Eq, Int -> LegalHoldUser -> ShowS
[LegalHoldUser] -> ShowS
LegalHoldUser -> String
(Int -> LegalHoldUser -> ShowS)
-> (LegalHoldUser -> String)
-> ([LegalHoldUser] -> ShowS)
-> Show LegalHoldUser
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> LegalHoldUser -> ShowS
showsPrec :: Int -> LegalHoldUser -> ShowS
$cshow :: LegalHoldUser -> String
show :: LegalHoldUser -> String
$cshowList :: [LegalHoldUser] -> ShowS
showList :: [LegalHoldUser] -> ShowS
Show)

newtype LegalHoldAccess = LegalHoldAccess
  { LegalHoldAccess -> Access
_legalHoldAccess :: Access
  }
  deriving (LegalHoldAccess -> LegalHoldAccess -> Bool
(LegalHoldAccess -> LegalHoldAccess -> Bool)
-> (LegalHoldAccess -> LegalHoldAccess -> Bool)
-> Eq LegalHoldAccess
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: LegalHoldAccess -> LegalHoldAccess -> Bool
== :: LegalHoldAccess -> LegalHoldAccess -> Bool
$c/= :: LegalHoldAccess -> LegalHoldAccess -> Bool
/= :: LegalHoldAccess -> LegalHoldAccess -> Bool
Eq, Int -> LegalHoldAccess -> ShowS
[LegalHoldAccess] -> ShowS
LegalHoldAccess -> String
(Int -> LegalHoldAccess -> ShowS)
-> (LegalHoldAccess -> String)
-> ([LegalHoldAccess] -> ShowS)
-> Show LegalHoldAccess
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> LegalHoldAccess -> ShowS
showsPrec :: Int -> LegalHoldAccess -> ShowS
$cshow :: LegalHoldAccess -> String
show :: LegalHoldAccess -> String
$cshowList :: [LegalHoldAccess] -> ShowS
showList :: [LegalHoldAccess] -> ShowS
Show)

type Properties = [(LByteString, LByteString)]

signature :: Getter (Token a) Signature
signature :: forall a (f :: * -> *).
(Contravariant f, Functor f) =>
(Signature -> f Signature) -> Token a -> f (Token a)
signature = (Token a -> Signature)
-> (Signature -> f Signature) -> Token a -> f (Token a)
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to Token a -> Signature
forall a. Token a -> Signature
_signature

header :: Getter (Token a) Header
header :: forall a (f :: * -> *).
(Contravariant f, Functor f) =>
(Header -> f Header) -> Token a -> f (Token a)
header = (Token a -> Header)
-> (Header -> f Header) -> Token a -> f (Token a)
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to Token a -> Header
forall a. Token a -> Header
_header

body :: Getter (Token a) a
body :: forall a (f :: * -> *).
(Contravariant f, Functor f) =>
(a -> f a) -> Token a -> f (Token a)
body = (Token a -> a) -> (a -> f a) -> Token a -> f (Token a)
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to Token a -> a
forall a. Token a -> a
_body

makeLenses ''Header

makeLenses ''Access

makeLenses ''User

makeLenses ''Bot

makeLenses ''Provider

makeLenses ''LegalHoldUser

makeLenses ''LegalHoldAccess

instance FromByteString (Token Access) where
  parser :: Parser (Token Access)
parser =
    Parser LByteString
takeLazyByteString Parser LByteString
-> (LByteString -> Parser (Token Access)) -> Parser (Token Access)
forall a b.
Parser ByteString a
-> (a -> Parser ByteString b) -> Parser ByteString b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \LByteString
b ->
      case Type
-> (Properties -> Maybe Access)
-> LByteString
-> Maybe (Token Access)
forall a.
Type -> (Properties -> Maybe a) -> LByteString -> Maybe (Token a)
readToken Type
A Properties -> Maybe Access
readAccessBody LByteString
b of
        Maybe (Token Access)
Nothing -> String -> Parser (Token Access)
forall a. String -> Parser ByteString a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Invalid access token"
        Just Token Access
t -> Token Access -> Parser (Token Access)
forall a. a -> Parser ByteString a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Token Access
t

instance FromByteString (Token User) where
  parser :: Parser (Token User)
parser =
    Parser LByteString
takeLazyByteString Parser LByteString
-> (LByteString -> Parser (Token User)) -> Parser (Token User)
forall a b.
Parser ByteString a
-> (a -> Parser ByteString b) -> Parser ByteString b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \LByteString
b ->
      case Type
-> (Properties -> Maybe User) -> LByteString -> Maybe (Token User)
forall a.
Type -> (Properties -> Maybe a) -> LByteString -> Maybe (Token a)
readToken Type
U Properties -> Maybe User
readUserBody LByteString
b of
        Maybe (Token User)
Nothing -> String -> Parser (Token User)
forall a. String -> Parser ByteString a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Invalid user token"
        Just Token User
t -> Token User -> Parser (Token User)
forall a. a -> Parser ByteString a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Token User
t

instance FromByteString (Token Bot) where
  parser :: Parser (Token Bot)
parser =
    Parser LByteString
takeLazyByteString Parser LByteString
-> (LByteString -> Parser (Token Bot)) -> Parser (Token Bot)
forall a b.
Parser ByteString a
-> (a -> Parser ByteString b) -> Parser ByteString b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \LByteString
b ->
      case Type
-> (Properties -> Maybe Bot) -> LByteString -> Maybe (Token Bot)
forall a.
Type -> (Properties -> Maybe a) -> LByteString -> Maybe (Token a)
readToken Type
B Properties -> Maybe Bot
readBotBody LByteString
b of
        Maybe (Token Bot)
Nothing -> String -> Parser (Token Bot)
forall a. String -> Parser ByteString a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Invalid bot token"
        Just Token Bot
t -> Token Bot -> Parser (Token Bot)
forall a. a -> Parser ByteString a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Token Bot
t

instance FromByteString (Token Provider) where
  parser :: Parser (Token Provider)
parser =
    Parser LByteString
takeLazyByteString Parser LByteString
-> (LByteString -> Parser (Token Provider))
-> Parser (Token Provider)
forall a b.
Parser ByteString a
-> (a -> Parser ByteString b) -> Parser ByteString b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \LByteString
b ->
      case Type
-> (Properties -> Maybe Provider)
-> LByteString
-> Maybe (Token Provider)
forall a.
Type -> (Properties -> Maybe a) -> LByteString -> Maybe (Token a)
readToken Type
P Properties -> Maybe Provider
readProviderBody LByteString
b of
        Maybe (Token Provider)
Nothing -> String -> Parser (Token Provider)
forall a. String -> Parser ByteString a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Invalid provider token"
        Just Token Provider
t -> Token Provider -> Parser (Token Provider)
forall a. a -> Parser ByteString a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Token Provider
t

instance FromByteString (Token LegalHoldAccess) where
  parser :: Parser (Token LegalHoldAccess)
parser =
    Parser LByteString
takeLazyByteString Parser LByteString
-> (LByteString -> Parser (Token LegalHoldAccess))
-> Parser (Token LegalHoldAccess)
forall a b.
Parser ByteString a
-> (a -> Parser ByteString b) -> Parser ByteString b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \LByteString
b ->
      case Type
-> (Properties -> Maybe LegalHoldAccess)
-> LByteString
-> Maybe (Token LegalHoldAccess)
forall a.
Type -> (Properties -> Maybe a) -> LByteString -> Maybe (Token a)
readToken Type
LA Properties -> Maybe LegalHoldAccess
readLegalHoldAccessBody LByteString
b of
        Maybe (Token LegalHoldAccess)
Nothing -> String -> Parser (Token LegalHoldAccess)
forall a. String -> Parser ByteString a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Invalid access token"
        Just Token LegalHoldAccess
t -> Token LegalHoldAccess -> Parser (Token LegalHoldAccess)
forall a. a -> Parser ByteString a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Token LegalHoldAccess
t

instance FromByteString (Token LegalHoldUser) where
  parser :: Parser (Token LegalHoldUser)
parser =
    Parser LByteString
takeLazyByteString Parser LByteString
-> (LByteString -> Parser (Token LegalHoldUser))
-> Parser (Token LegalHoldUser)
forall a b.
Parser ByteString a
-> (a -> Parser ByteString b) -> Parser ByteString b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \LByteString
b ->
      case Type
-> (Properties -> Maybe LegalHoldUser)
-> LByteString
-> Maybe (Token LegalHoldUser)
forall a.
Type -> (Properties -> Maybe a) -> LByteString -> Maybe (Token a)
readToken Type
LU Properties -> Maybe LegalHoldUser
readLegalHoldUserBody LByteString
b of
        Maybe (Token LegalHoldUser)
Nothing -> String -> Parser (Token LegalHoldUser)
forall a. String -> Parser ByteString a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Invalid user token"
        Just Token LegalHoldUser
t -> Token LegalHoldUser -> Parser (Token LegalHoldUser)
forall a. a -> Parser ByteString a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Token LegalHoldUser
t

instance (ToByteString a) => ToByteString (Token a) where
  builder :: Token a -> Builder
builder = Token a -> Builder
forall a. ToByteString a => Token a -> Builder
writeToken

-----------------------------------------------------------------------------
-- Constructing

mkToken :: Signature -> Header -> a -> Token a
mkToken :: forall a. Signature -> Header -> a -> Token a
mkToken = Signature -> Header -> a -> Token a
forall a. Signature -> Header -> a -> Token a
Token

mkHeader :: Int -> Int -> Integer -> Type -> Maybe Tag -> Header
mkHeader :: Int -> Int -> Integer -> Type -> Maybe Tag -> Header
mkHeader = Int -> Int -> Integer -> Type -> Maybe Tag -> Header
Header

mkAccess :: UUID -> Maybe Text -> Word64 -> Access
mkAccess :: UUID -> Maybe Text -> Word64 -> Access
mkAccess = UUID -> Maybe Text -> Word64 -> Access
Access

mkUser :: UUID -> Maybe Text -> Word32 -> User
mkUser :: UUID -> Maybe Text -> Word32 -> User
mkUser = UUID -> Maybe Text -> Word32 -> User
User

mkBot :: UUID -> UUID -> UUID -> Bot
mkBot :: UUID -> UUID -> UUID -> Bot
mkBot = UUID -> UUID -> UUID -> Bot
Bot

mkProvider :: UUID -> Provider
mkProvider :: UUID -> Provider
mkProvider = UUID -> Provider
Provider

mkLegalHoldAccess :: UUID -> Maybe Text -> Word64 -> LegalHoldAccess
mkLegalHoldAccess :: UUID -> Maybe Text -> Word64 -> LegalHoldAccess
mkLegalHoldAccess UUID
uid Maybe Text
clt Word64
con = Access -> LegalHoldAccess
LegalHoldAccess (Access -> LegalHoldAccess) -> Access -> LegalHoldAccess
forall a b. (a -> b) -> a -> b
$ UUID -> Maybe Text -> Word64 -> Access
Access UUID
uid Maybe Text
clt Word64
con

mkLegalHoldUser :: UUID -> Maybe Text -> Word32 -> LegalHoldUser
mkLegalHoldUser :: UUID -> Maybe Text -> Word32 -> LegalHoldUser
mkLegalHoldUser UUID
uid Maybe Text
cid Word32
r = User -> LegalHoldUser
LegalHoldUser (User -> LegalHoldUser) -> User -> LegalHoldUser
forall a b. (a -> b) -> a -> b
$ UUID -> Maybe Text -> Word32 -> User
User UUID
uid Maybe Text
cid Word32
r

-----------------------------------------------------------------------------
-- Reading

readToken :: Type -> (Properties -> Maybe a) -> LByteString -> Maybe (Token a)
readToken :: forall a.
Type -> (Properties -> Maybe a) -> LByteString -> Maybe (Token a)
readToken Type
t Properties -> Maybe a
f LByteString
b = case Char -> LByteString -> [LByteString]
split Char
'.' LByteString
b of
  (LByteString
s : [LByteString]
rest) ->
    let p :: Properties
p = (LByteString -> (LByteString, LByteString))
-> [LByteString] -> Properties
forall a b. (a -> b) -> [a] -> [b]
map LByteString -> (LByteString, LByteString)
pairwise [LByteString]
rest
     in Signature -> Header -> a -> Token a
forall a. Signature -> Header -> a -> Token a
Token
          (Signature -> Header -> a -> Token a)
-> Maybe Signature -> Maybe (Header -> a -> Token a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Either String Signature -> Maybe Signature
forall a b. Either a b -> Maybe b
hush (ByteString -> Signature
Signature (ByteString -> Signature)
-> Either String ByteString -> Either String Signature
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ByteString -> Either String ByteString
decode (LByteString -> ByteString
toStrict LByteString
s))
          Maybe (Header -> a -> Token a)
-> Maybe Header -> Maybe (a -> Token a)
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Type -> Properties -> Maybe Header
readHeader Type
t Properties
p
          Maybe (a -> Token a) -> Maybe a -> Maybe (Token a)
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Properties -> Maybe a
f Properties
p
  [LByteString]
_ -> Maybe (Token a)
forall a. Maybe a
Nothing
  where
    pairwise :: LByteString -> (LByteString, LByteString)
    pairwise :: LByteString -> (LByteString, LByteString)
pairwise LByteString
x = let (LByteString
k, LByteString
v) = (Char -> Bool) -> LByteString -> (LByteString, LByteString)
break (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'=') LByteString
x in (LByteString
k, Int64 -> LByteString -> LByteString
drop Int64
1 LByteString
v)

readHeader :: Type -> Properties -> Maybe Header
readHeader :: Type -> Properties -> Maybe Header
readHeader Type
t Properties
p =
  Int -> Int -> Integer -> Type -> Maybe Tag -> Header
Header
    (Int -> Int -> Integer -> Type -> Maybe Tag -> Header)
-> Maybe Int
-> Maybe (Int -> Integer -> Type -> Maybe Tag -> Header)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (LByteString -> Properties -> Maybe LByteString
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup LByteString
"v" Properties
p Maybe LByteString -> (LByteString -> Maybe Int) -> Maybe Int
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= LByteString -> Maybe Int
forall a. FromByteString a => LByteString -> Maybe a
fromByteString')
    Maybe (Int -> Integer -> Type -> Maybe Tag -> Header)
-> Maybe Int -> Maybe (Integer -> Type -> Maybe Tag -> Header)
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (LByteString -> Properties -> Maybe LByteString
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup LByteString
"k" Properties
p Maybe LByteString -> (LByteString -> Maybe Int) -> Maybe Int
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= LByteString -> Maybe Int
forall a. FromByteString a => LByteString -> Maybe a
fromByteString')
    Maybe (Integer -> Type -> Maybe Tag -> Header)
-> Maybe Integer -> Maybe (Type -> Maybe Tag -> Header)
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (LByteString -> Properties -> Maybe LByteString
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup LByteString
"d" Properties
p Maybe LByteString
-> (LByteString -> Maybe Integer) -> Maybe Integer
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= LByteString -> Maybe Integer
forall a. FromByteString a => LByteString -> Maybe a
fromByteString')
    Maybe (Type -> Maybe Tag -> Header)
-> Maybe Type -> Maybe (Maybe Tag -> Header)
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (LByteString -> Properties -> Maybe LByteString
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup LByteString
"t" Properties
p Maybe LByteString -> (LByteString -> Maybe Type) -> Maybe Type
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Type -> LByteString -> Maybe Type
forall {a}. (Eq a, IsString a) => Type -> a -> Maybe Type
readType Type
t)
    Maybe (Maybe Tag -> Header) -> Maybe (Maybe Tag) -> Maybe Header
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (LByteString -> Maybe Tag
forall {a}. (Eq a, IsString a) => a -> Maybe Tag
readTag (LByteString -> Maybe Tag)
-> Maybe LByteString -> Maybe (Maybe Tag)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> LByteString -> Properties -> Maybe LByteString
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup LByteString
"l" Properties
p)
  where
    readType :: Type -> a -> Maybe Type
readType Type
A a
"a" = Type -> Maybe Type
forall a. a -> Maybe a
Just Type
A
    readType Type
U a
"u" = Type -> Maybe Type
forall a. a -> Maybe a
Just Type
U
    readType Type
B a
"b" = Type -> Maybe Type
forall a. a -> Maybe a
Just Type
B
    readType Type
P a
"p" = Type -> Maybe Type
forall a. a -> Maybe a
Just Type
P
    readType Type
LA a
"la" = Type -> Maybe Type
forall a. a -> Maybe a
Just Type
LA
    readType Type
LU a
"lu" = Type -> Maybe Type
forall a. a -> Maybe a
Just Type
LU
    readType Type
_ a
_ = Maybe Type
forall a. Maybe a
Nothing
    readTag :: a -> Maybe Tag
readTag a
"s" = Tag -> Maybe Tag
forall a. a -> Maybe a
Just Tag
S
    readTag a
_ = Maybe Tag
forall a. Maybe a
Nothing

readAccessBody :: Properties -> Maybe Access
readAccessBody :: Properties -> Maybe Access
readAccessBody Properties
t =
  UUID -> Maybe Text -> Word64 -> Access
Access
    (UUID -> Maybe Text -> Word64 -> Access)
-> Maybe UUID -> Maybe (Maybe Text -> Word64 -> Access)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (LByteString -> Properties -> Maybe LByteString
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup LByteString
"u" Properties
t Maybe LByteString -> (LByteString -> Maybe UUID) -> Maybe UUID
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= LByteString -> Maybe UUID
fromLazyASCIIBytes)
    Maybe (Maybe Text -> Word64 -> Access)
-> Maybe (Maybe Text) -> Maybe (Word64 -> Access)
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe Text -> Maybe (Maybe Text)
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (LByteString -> Properties -> Maybe LByteString
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup LByteString
"i" Properties
t Maybe LByteString -> (LByteString -> Maybe Text) -> Maybe Text
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= LByteString -> Maybe Text
forall a. FromByteString a => LByteString -> Maybe a
fromByteString')
    Maybe (Word64 -> Access) -> Maybe Word64 -> Maybe Access
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (LByteString -> Properties -> Maybe LByteString
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup LByteString
"c" Properties
t Maybe LByteString -> (LByteString -> Maybe Word64) -> Maybe Word64
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= LByteString -> Maybe Word64
forall a. FromByteString a => LByteString -> Maybe a
fromByteString')

readUserBody :: Properties -> Maybe User
readUserBody :: Properties -> Maybe User
readUserBody Properties
t =
  UUID -> Maybe Text -> Word32 -> User
User
    (UUID -> Maybe Text -> Word32 -> User)
-> Maybe UUID -> Maybe (Maybe Text -> Word32 -> User)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (LByteString -> Properties -> Maybe LByteString
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup LByteString
"u" Properties
t Maybe LByteString -> (LByteString -> Maybe UUID) -> Maybe UUID
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= LByteString -> Maybe UUID
fromLazyASCIIBytes)
    Maybe (Maybe Text -> Word32 -> User)
-> Maybe (Maybe Text) -> Maybe (Word32 -> User)
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe Text -> Maybe (Maybe Text)
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (LByteString -> Properties -> Maybe LByteString
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup LByteString
"i" Properties
t Maybe LByteString -> (LByteString -> Maybe Text) -> Maybe Text
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= LByteString -> Maybe Text
forall a. FromByteString a => LByteString -> Maybe a
fromByteString')
    Maybe (Word32 -> User) -> Maybe Word32 -> Maybe User
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (LByteString -> Properties -> Maybe LByteString
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup LByteString
"r" Properties
t Maybe LByteString -> (LByteString -> Maybe Word32) -> Maybe Word32
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Hex Word32 -> Word32) -> Maybe (Hex Word32) -> Maybe Word32
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Hex Word32 -> Word32
forall a. Hex a -> a
fromHex (Maybe (Hex Word32) -> Maybe Word32)
-> (LByteString -> Maybe (Hex Word32))
-> LByteString
-> Maybe Word32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LByteString -> Maybe (Hex Word32)
forall a. FromByteString a => LByteString -> Maybe a
fromByteString')

readBotBody :: Properties -> Maybe Bot
readBotBody :: Properties -> Maybe Bot
readBotBody Properties
t =
  UUID -> UUID -> UUID -> Bot
Bot
    (UUID -> UUID -> UUID -> Bot)
-> Maybe UUID -> Maybe (UUID -> UUID -> Bot)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (LByteString -> Properties -> Maybe LByteString
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup LByteString
"p" Properties
t Maybe LByteString -> (LByteString -> Maybe UUID) -> Maybe UUID
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= LByteString -> Maybe UUID
fromLazyASCIIBytes)
    Maybe (UUID -> UUID -> Bot) -> Maybe UUID -> Maybe (UUID -> Bot)
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (LByteString -> Properties -> Maybe LByteString
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup LByteString
"b" Properties
t Maybe LByteString -> (LByteString -> Maybe UUID) -> Maybe UUID
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= LByteString -> Maybe UUID
fromLazyASCIIBytes)
    Maybe (UUID -> Bot) -> Maybe UUID -> Maybe Bot
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (LByteString -> Properties -> Maybe LByteString
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup LByteString
"c" Properties
t Maybe LByteString -> (LByteString -> Maybe UUID) -> Maybe UUID
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= LByteString -> Maybe UUID
fromLazyASCIIBytes)

readProviderBody :: Properties -> Maybe Provider
readProviderBody :: Properties -> Maybe Provider
readProviderBody Properties
t = UUID -> Provider
Provider (UUID -> Provider) -> Maybe UUID -> Maybe Provider
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (LByteString -> Properties -> Maybe LByteString
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup LByteString
"p" Properties
t Maybe LByteString -> (LByteString -> Maybe UUID) -> Maybe UUID
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= LByteString -> Maybe UUID
fromLazyASCIIBytes)

readLegalHoldAccessBody :: Properties -> Maybe LegalHoldAccess
readLegalHoldAccessBody :: Properties -> Maybe LegalHoldAccess
readLegalHoldAccessBody Properties
t = Access -> LegalHoldAccess
LegalHoldAccess (Access -> LegalHoldAccess)
-> Maybe Access -> Maybe LegalHoldAccess
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Properties -> Maybe Access
readAccessBody Properties
t

readLegalHoldUserBody :: Properties -> Maybe LegalHoldUser
readLegalHoldUserBody :: Properties -> Maybe LegalHoldUser
readLegalHoldUserBody Properties
t = User -> LegalHoldUser
LegalHoldUser (User -> LegalHoldUser) -> Maybe User -> Maybe LegalHoldUser
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Properties -> Maybe User
readUserBody Properties
t

-----------------------------------------------------------------------------
-- Writing

writeToken :: (ToByteString a) => Token a -> Builder
writeToken :: forall a. ToByteString a => Token a -> Builder
writeToken Token a
t =
  ByteString -> Builder
byteString (ByteString -> ByteString
encode (Signature -> ByteString
sigBytes (Token a
t Token a -> Getting Signature (Token a) Signature -> Signature
forall s a. s -> Getting a s a -> a
^. Getting Signature (Token a) Signature
forall a (f :: * -> *).
(Contravariant f, Functor f) =>
(Signature -> f Signature) -> Token a -> f (Token a)
signature)))
    Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
dot
    Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Header -> a -> Builder
forall a. ToByteString a => Header -> a -> Builder
writeData (Token a
t Token a -> Getting Header (Token a) Header -> Header
forall s a. s -> Getting a s a -> a
^. Getting Header (Token a) Header
forall a (f :: * -> *).
(Contravariant f, Functor f) =>
(Header -> f Header) -> Token a -> f (Token a)
header) (Token a
t Token a -> Getting a (Token a) a -> a
forall s a. s -> Getting a s a -> a
^. Getting a (Token a) a
forall a (f :: * -> *).
(Contravariant f, Functor f) =>
(a -> f a) -> Token a -> f (Token a)
body)

writeData :: (ToByteString a) => Header -> a -> Builder
writeData :: forall a. ToByteString a => Header -> a -> Builder
writeData Header
h a
a = Header -> Builder
writeHeader Header
h Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
dot Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> a -> Builder
forall a. ToByteString a => a -> Builder
builder a
a

writeHeader :: Header -> Builder
writeHeader :: Header -> Builder
writeHeader Header
t =
  LByteString -> Int -> Builder
forall a. ToByteString a => LByteString -> a -> Builder
field LByteString
"v" (Header
t Header -> Getting Int Header Int -> Int
forall s a. s -> Getting a s a -> a
^. Getting Int Header Int
Lens' Header Int
version)
    Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
dot
    Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> LByteString -> Int -> Builder
forall a. ToByteString a => LByteString -> a -> Builder
field LByteString
"k" (Header
t Header -> Getting Int Header Int -> Int
forall s a. s -> Getting a s a -> a
^. Getting Int Header Int
Lens' Header Int
key)
    Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
dot
    Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> LByteString -> Integer -> Builder
forall a. ToByteString a => LByteString -> a -> Builder
field LByteString
"d" (Header
t Header -> Getting Integer Header Integer -> Integer
forall s a. s -> Getting a s a -> a
^. Getting Integer Header Integer
Lens' Header Integer
time)
    Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
dot
    Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> LByteString -> Type -> Builder
forall a. ToByteString a => LByteString -> a -> Builder
field LByteString
"t" (Header
t Header -> Getting Type Header Type -> Type
forall s a. s -> Getting a s a -> a
^. Getting Type Header Type
Lens' Header Type
typ)
    Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
dot
    Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> LByteString -> Builder -> Builder
forall a. ToByteString a => LByteString -> a -> Builder
field LByteString
"l" ((Tag -> Builder) -> Maybe Tag -> Builder
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Tag -> Builder
forall a. ToByteString a => a -> Builder
builder (Header
t Header -> Getting (Maybe Tag) Header (Maybe Tag) -> Maybe Tag
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Tag) Header (Maybe Tag)
Lens' Header (Maybe Tag)
tag))

instance ToByteString Access where
  builder :: Access -> Builder
builder Access
t =
    LByteString -> LByteString -> Builder
forall a. ToByteString a => LByteString -> a -> Builder
field LByteString
"u" (UUID -> LByteString
toLazyASCIIBytes (UUID -> LByteString) -> UUID -> LByteString
forall a b. (a -> b) -> a -> b
$ Access
t Access -> Getting UUID Access UUID -> UUID
forall s a. s -> Getting a s a -> a
^. Getting UUID Access UUID
Lens' Access UUID
userId)
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> (Text -> Builder) -> Maybe Text -> Builder
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (\Text
c -> Builder
dot Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> LByteString -> Text -> Builder
forall a. ToByteString a => LByteString -> a -> Builder
field LByteString
"i" Text
c) (Access
t Access -> Getting (Maybe Text) Access (Maybe Text) -> Maybe Text
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Text) Access (Maybe Text)
Lens' Access (Maybe Text)
clientId)
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
dot
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> LByteString -> Word64 -> Builder
forall a. ToByteString a => LByteString -> a -> Builder
field LByteString
"c" (Access
t Access -> Getting Word64 Access Word64 -> Word64
forall s a. s -> Getting a s a -> a
^. Getting Word64 Access Word64
Lens' Access Word64
connection)

instance ToByteString User where
  builder :: User -> Builder
builder User
t =
    LByteString -> LByteString -> Builder
forall a. ToByteString a => LByteString -> a -> Builder
field LByteString
"u" (UUID -> LByteString
toLazyASCIIBytes (UUID -> LByteString) -> UUID -> LByteString
forall a b. (a -> b) -> a -> b
$ User
t User -> Getting UUID User UUID -> UUID
forall s a. s -> Getting a s a -> a
^. Getting UUID User UUID
Lens' User UUID
user)
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
dot
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> LByteString -> Hex Word32 -> Builder
forall a. ToByteString a => LByteString -> a -> Builder
field LByteString
"r" (Word32 -> Hex Word32
forall a. a -> Hex a
Hex (User
t User -> Getting Word32 User Word32 -> Word32
forall s a. s -> Getting a s a -> a
^. Getting Word32 User Word32
Lens' User Word32
rand))
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> (Text -> Builder) -> Maybe Text -> Builder
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (\Text
c -> Builder
dot Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> LByteString -> Text -> Builder
forall a. ToByteString a => LByteString -> a -> Builder
field LByteString
"i" Text
c) (User
t User -> Getting (Maybe Text) User (Maybe Text) -> Maybe Text
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Text) User (Maybe Text)
Lens' User (Maybe Text)
client)

instance ToByteString Bot where
  builder :: Bot -> Builder
builder Bot
t =
    LByteString -> LByteString -> Builder
forall a. ToByteString a => LByteString -> a -> Builder
field LByteString
"p" (UUID -> LByteString
toLazyASCIIBytes (UUID -> LByteString) -> UUID -> LByteString
forall a b. (a -> b) -> a -> b
$ Bot
t Bot -> Getting UUID Bot UUID -> UUID
forall s a. s -> Getting a s a -> a
^. Getting UUID Bot UUID
Lens' Bot UUID
prov)
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
dot
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> LByteString -> LByteString -> Builder
forall a. ToByteString a => LByteString -> a -> Builder
field LByteString
"b" (UUID -> LByteString
toLazyASCIIBytes (UUID -> LByteString) -> UUID -> LByteString
forall a b. (a -> b) -> a -> b
$ Bot
t Bot -> Getting UUID Bot UUID -> UUID
forall s a. s -> Getting a s a -> a
^. Getting UUID Bot UUID
Lens' Bot UUID
bot)
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
dot
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> LByteString -> LByteString -> Builder
forall a. ToByteString a => LByteString -> a -> Builder
field LByteString
"c" (UUID -> LByteString
toLazyASCIIBytes (UUID -> LByteString) -> UUID -> LByteString
forall a b. (a -> b) -> a -> b
$ Bot
t Bot -> Getting UUID Bot UUID -> UUID
forall s a. s -> Getting a s a -> a
^. Getting UUID Bot UUID
Lens' Bot UUID
conv)

instance ToByteString Provider where
  builder :: Provider -> Builder
builder Provider
t = LByteString -> LByteString -> Builder
forall a. ToByteString a => LByteString -> a -> Builder
field LByteString
"p" (UUID -> LByteString
toLazyASCIIBytes (UUID -> LByteString) -> UUID -> LByteString
forall a b. (a -> b) -> a -> b
$ Provider
t Provider -> Getting UUID Provider UUID -> UUID
forall s a. s -> Getting a s a -> a
^. Getting UUID Provider UUID
Iso' Provider UUID
provider)

instance ToByteString LegalHoldAccess where
  builder :: LegalHoldAccess -> Builder
builder LegalHoldAccess
t =
    LByteString -> LByteString -> Builder
forall a. ToByteString a => LByteString -> a -> Builder
field LByteString
"u" (UUID -> LByteString
toLazyASCIIBytes (UUID -> LByteString) -> UUID -> LByteString
forall a b. (a -> b) -> a -> b
$ LegalHoldAccess
t LegalHoldAccess -> Getting UUID LegalHoldAccess UUID -> UUID
forall s a. s -> Getting a s a -> a
^. (Access -> Const UUID Access)
-> LegalHoldAccess -> Const UUID LegalHoldAccess
Iso' LegalHoldAccess Access
legalHoldAccess ((Access -> Const UUID Access)
 -> LegalHoldAccess -> Const UUID LegalHoldAccess)
-> Getting UUID Access UUID -> Getting UUID LegalHoldAccess UUID
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting UUID Access UUID
Lens' Access UUID
userId)
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> (Text -> Builder) -> Maybe Text -> Builder
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (\Text
c -> Builder
dot Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> LByteString -> Text -> Builder
forall a. ToByteString a => LByteString -> a -> Builder
field LByteString
"i" Text
c) (LegalHoldAccess
t LegalHoldAccess
-> Getting (Maybe Text) LegalHoldAccess (Maybe Text) -> Maybe Text
forall s a. s -> Getting a s a -> a
^. (Access -> Const (Maybe Text) Access)
-> LegalHoldAccess -> Const (Maybe Text) LegalHoldAccess
Iso' LegalHoldAccess Access
legalHoldAccess ((Access -> Const (Maybe Text) Access)
 -> LegalHoldAccess -> Const (Maybe Text) LegalHoldAccess)
-> Getting (Maybe Text) Access (Maybe Text)
-> Getting (Maybe Text) LegalHoldAccess (Maybe Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting (Maybe Text) Access (Maybe Text)
Lens' Access (Maybe Text)
clientId)
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
dot
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> LByteString -> Word64 -> Builder
forall a. ToByteString a => LByteString -> a -> Builder
field LByteString
"c" (LegalHoldAccess
t LegalHoldAccess -> Getting Word64 LegalHoldAccess Word64 -> Word64
forall s a. s -> Getting a s a -> a
^. (Access -> Const Word64 Access)
-> LegalHoldAccess -> Const Word64 LegalHoldAccess
Iso' LegalHoldAccess Access
legalHoldAccess ((Access -> Const Word64 Access)
 -> LegalHoldAccess -> Const Word64 LegalHoldAccess)
-> Getting Word64 Access Word64
-> Getting Word64 LegalHoldAccess Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting Word64 Access Word64
Lens' Access Word64
connection)

instance ToByteString LegalHoldUser where
  builder :: LegalHoldUser -> Builder
builder LegalHoldUser
t =
    LByteString -> LByteString -> Builder
forall a. ToByteString a => LByteString -> a -> Builder
field LByteString
"u" (UUID -> LByteString
toLazyASCIIBytes (UUID -> LByteString) -> UUID -> LByteString
forall a b. (a -> b) -> a -> b
$ LegalHoldUser
t LegalHoldUser -> Getting UUID LegalHoldUser UUID -> UUID
forall s a. s -> Getting a s a -> a
^. (User -> Const UUID User)
-> LegalHoldUser -> Const UUID LegalHoldUser
Iso' LegalHoldUser User
legalHoldUser ((User -> Const UUID User)
 -> LegalHoldUser -> Const UUID LegalHoldUser)
-> Getting UUID User UUID -> Getting UUID LegalHoldUser UUID
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting UUID User UUID
Lens' User UUID
user)
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
dot
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> LByteString -> Hex Word32 -> Builder
forall a. ToByteString a => LByteString -> a -> Builder
field LByteString
"r" (Word32 -> Hex Word32
forall a. a -> Hex a
Hex (LegalHoldUser
t LegalHoldUser -> Getting Word32 LegalHoldUser Word32 -> Word32
forall s a. s -> Getting a s a -> a
^. (User -> Const Word32 User)
-> LegalHoldUser -> Const Word32 LegalHoldUser
Iso' LegalHoldUser User
legalHoldUser ((User -> Const Word32 User)
 -> LegalHoldUser -> Const Word32 LegalHoldUser)
-> Getting Word32 User Word32
-> Getting Word32 LegalHoldUser Word32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting Word32 User Word32
Lens' User Word32
rand))
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> (Text -> Builder) -> Maybe Text -> Builder
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (\Text
c -> Builder
dot Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> LByteString -> Text -> Builder
forall a. ToByteString a => LByteString -> a -> Builder
field LByteString
"i" Text
c) (LegalHoldUser
t LegalHoldUser
-> Getting (Maybe Text) LegalHoldUser (Maybe Text) -> Maybe Text
forall s a. s -> Getting a s a -> a
^. (User -> Const (Maybe Text) User)
-> LegalHoldUser -> Const (Maybe Text) LegalHoldUser
Iso' LegalHoldUser User
legalHoldUser ((User -> Const (Maybe Text) User)
 -> LegalHoldUser -> Const (Maybe Text) LegalHoldUser)
-> Getting (Maybe Text) User (Maybe Text)
-> Getting (Maybe Text) LegalHoldUser (Maybe Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting (Maybe Text) User (Maybe Text)
Lens' User (Maybe Text)
client)

instance ToByteString Type where
  builder :: Type -> Builder
builder Type
A = Char -> Builder
char8 Char
'a'
  builder Type
U = Char -> Builder
char8 Char
'u'
  builder Type
B = Char -> Builder
char8 Char
'b'
  builder Type
P = Char -> Builder
char8 Char
'p'
  builder Type
LA = Char -> Builder
char8 Char
'l' Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Char -> Builder
char8 Char
'a'
  builder Type
LU = Char -> Builder
char8 Char
'l' Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Char -> Builder
char8 Char
'u'

instance ToByteString Tag where
  builder :: Tag -> Builder
builder Tag
S = Char -> Builder
char8 Char
's'

field :: (ToByteString a) => LByteString -> a -> Builder
field :: forall a. ToByteString a => LByteString -> a -> Builder
field LByteString
k a
v = LByteString -> Builder
forall a. ToByteString a => a -> Builder
builder LByteString
k Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
eq Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> a -> Builder
forall a. ToByteString a => a -> Builder
builder a
v

dot, eq :: Builder
dot :: Builder
dot = Char -> Builder
char8 Char
'.'
eq :: Builder
eq = Char -> Builder
char8 Char
'='