{-# LANGUAGE CPP               #-}
{-# LANGUAGE DeriveAnyClass    #-}
{-# LANGUAGE DeriveGeneric     #-}
{-# LANGUAGE OverloadedStrings #-}

module Database.Vault.KVv2.Client.Types where

import           Control.Monad                       (mzero)
import           Data.Aeson
#if MIN_VERSION_aeson(2,0,0)
import qualified Data.Aeson.Key                      as K
import qualified Data.Aeson.KeyMap                   as KM
#endif
import qualified Data.ByteString                     as B
import           Data.Hashable
import           Data.HashMap.Strict
import qualified Data.Text                           as T
import           Data.Text.Read                      (decimal)
import           GHC.Generics
import           Network.HTTP.Client                 (Manager)
import           Text.Read                           (readMaybe)

import           Database.Vault.KVv2.Client.Internal

type VaultAddr = String

type VaultToken = String

type Error = String

type KVEnginePath = String

type DisableCertValidation =Bool

data VaultConnection =
  VaultConnection
    { VaultConnection -> String
vaultAddr    :: !VaultAddr
    , VaultConnection -> String
kvEnginePath :: !KVEnginePath
    , VaultConnection -> ByteString
vaultToken   :: !B.ByteString
    , VaultConnection -> Manager
manager      :: !Manager
    }

instance Show VaultConnection where
  show :: VaultConnection -> String
show (VaultConnection String
a String
p ByteString
_ Manager
_) =
    ShowS
removeTrailingSlash String
a forall a. [a] -> [a] -> [a]
++ String
"/v1/"
    forall a. [a] -> [a] -> [a]
++ ShowS
removeTrailingSlash (ShowS
removeLeadingSlash String
p)

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

instance ToJSON SecretVersions where
  toJSON :: SecretVersions -> Value
toJSON (SecretVersions [SecretVersion]
svs) =
    [Pair] -> Value
object
      [ Key
"versions" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= ((\(SecretVersion Int
i) -> Int
i) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [SecretVersion]
svs) ]

newtype SecretVersion
  = SecretVersion Int
  deriving (Int -> SecretVersion -> ShowS
[SecretVersion] -> ShowS
SecretVersion -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SecretVersion] -> ShowS
$cshowList :: [SecretVersion] -> ShowS
show :: SecretVersion -> String
$cshow :: SecretVersion -> String
showsPrec :: Int -> SecretVersion -> ShowS
$cshowsPrec :: Int -> SecretVersion -> ShowS
Show, SecretVersion -> SecretVersion -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SecretVersion -> SecretVersion -> Bool
$c/= :: SecretVersion -> SecretVersion -> Bool
== :: SecretVersion -> SecretVersion -> Bool
$c== :: SecretVersion -> SecretVersion -> Bool
Eq, forall x. Rep SecretVersion x -> SecretVersion
forall x. SecretVersion -> Rep SecretVersion x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep SecretVersion x -> SecretVersion
$cfrom :: forall x. SecretVersion -> Rep SecretVersion x
Generic, Eq SecretVersion
Int -> SecretVersion -> Int
SecretVersion -> Int
forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: SecretVersion -> Int
$chash :: SecretVersion -> Int
hashWithSalt :: Int -> SecretVersion -> Int
$chashWithSalt :: Int -> SecretVersion -> Int
Hashable)

newtype SecretMetadata =
  SecretMetadata (HashMap SecretVersion Metadata)
  deriving (Int -> SecretMetadata -> ShowS
[SecretMetadata] -> ShowS
SecretMetadata -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SecretMetadata] -> ShowS
$cshowList :: [SecretMetadata] -> ShowS
show :: SecretMetadata -> String
$cshow :: SecretMetadata -> String
showsPrec :: Int -> SecretMetadata -> ShowS
$cshowsPrec :: Int -> SecretMetadata -> ShowS
Show, SecretMetadata -> SecretMetadata -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SecretMetadata -> SecretMetadata -> Bool
$c/= :: SecretMetadata -> SecretMetadata -> Bool
== :: SecretMetadata -> SecretMetadata -> Bool
$c== :: SecretMetadata -> SecretMetadata -> Bool
Eq)

instance FromJSON SecretMetadata where
  parseJSON :: Value -> Parser SecretMetadata
parseJSON (Object Object
o) =
#if MIN_VERSION_aeson(2,0,0)
    forall (f :: * -> *) a. Applicative f => a -> f a
pure (HashMap SecretVersion Metadata -> SecretMetadata
SecretMetadata forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
fromList forall a b. (a -> b) -> a -> b
$ forall {b}. FromJSON b => Pair -> (SecretVersion, b)
trans forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall k v. HashMap k v -> [(k, v)]
toList (forall v. KeyMap v -> HashMap Key v
KM.toHashMap Object
o))
#else
    pure (SecretMetadata . fromList $ trans <$> toList o)
#endif
    where
    trans :: Pair -> (SecretVersion, b)
trans Pair
p =
      case Pair
p of
        (Key
k,j :: Value
j@(Object Object
_)) -> do
#if MIN_VERSION_aeson(2,0,0)
          let d :: Either String (Int, Text)
d = forall a. Integral a => Reader a
decimal (Key -> Text
K.toText Key
k)
#else
          let d = decimal k
#endif
          (Int -> SecretVersion
SecretVersion (forall {a} {b}. Either String (a, b) -> a
fromDecimal Either String (Int, Text)
d),forall {a}. Result a -> a
fromSuccess forall a b. (a -> b) -> a -> b
$ forall a. FromJSON a => Value -> Result a
fromJSON Value
j)
        Pair
_anyOther        -> forall a. HasCallStack => String -> a
error String
"Expected JSON Object"
    fromDecimal :: Either String (a, b) -> a
fromDecimal (Right (a
i,b
_)) = a
i
    fromDecimal (Left String
e)      = forall a. HasCallStack => String -> a
error String
e
    fromSuccess :: Result a -> a
fromSuccess (Success a
s) = a
s
    fromSuccess (Error String
e)   = forall a. HasCallStack => String -> a
error String
e
  parseJSON Value
_          = forall (m :: * -> *) a. MonadPlus m => m a
mzero

data Metadata =
  Metadata
    { Metadata -> Bool
destroyed     :: !Bool
    , Metadata -> Text
deletion_time :: !T.Text
    , Metadata -> Text
created_time  :: !T.Text
    } deriving (Int -> Metadata -> ShowS
[Metadata] -> ShowS
Metadata -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Metadata] -> ShowS
$cshowList :: [Metadata] -> ShowS
show :: Metadata -> String
$cshow :: Metadata -> String
showsPrec :: Int -> Metadata -> ShowS
$cshowsPrec :: Int -> Metadata -> ShowS
Show, Metadata -> Metadata -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Metadata -> Metadata -> Bool
$c/= :: Metadata -> Metadata -> Bool
== :: Metadata -> Metadata -> Bool
$c== :: Metadata -> Metadata -> Bool
Eq, forall x. Rep Metadata x -> Metadata
forall x. Metadata -> Rep Metadata x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Metadata x -> Metadata
$cfrom :: forall x. Metadata -> Rep Metadata x
Generic, [Metadata] -> Encoding
[Metadata] -> Value
Metadata -> Encoding
Metadata -> Value
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [Metadata] -> Encoding
$ctoEncodingList :: [Metadata] -> Encoding
toJSONList :: [Metadata] -> Value
$ctoJSONList :: [Metadata] -> Value
toEncoding :: Metadata -> Encoding
$ctoEncoding :: Metadata -> Encoding
toJSON :: Metadata -> Value
$ctoJSON :: Metadata -> Value
ToJSON, Value -> Parser [Metadata]
Value -> Parser Metadata
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [Metadata]
$cparseJSONList :: Value -> Parser [Metadata]
parseJSON :: Value -> Parser Metadata
$cparseJSON :: Value -> Parser Metadata
FromJSON)

newtype SecretData =
  SecretData
    (HashMap T.Text T.Text)
    deriving (Int -> SecretData -> ShowS
[SecretData] -> ShowS
SecretData -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SecretData] -> ShowS
$cshowList :: [SecretData] -> ShowS
show :: SecretData -> String
$cshow :: SecretData -> String
showsPrec :: Int -> SecretData -> ShowS
$cshowsPrec :: Int -> SecretData -> ShowS
Show, forall x. Rep SecretData x -> SecretData
forall x. SecretData -> Rep SecretData x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep SecretData x -> SecretData
$cfrom :: forall x. SecretData -> Rep SecretData x
Generic, [SecretData] -> Encoding
[SecretData] -> Value
SecretData -> Encoding
SecretData -> Value
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [SecretData] -> Encoding
$ctoEncodingList :: [SecretData] -> Encoding
toJSONList :: [SecretData] -> Value
$ctoJSONList :: [SecretData] -> Value
toEncoding :: SecretData -> Encoding
$ctoEncoding :: SecretData -> Encoding
toJSON :: SecretData -> Value
$ctoJSON :: SecretData -> Value
ToJSON, Value -> Parser [SecretData]
Value -> Parser SecretData
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [SecretData]
$cparseJSONList :: Value -> Parser [SecretData]
parseJSON :: Value -> Parser SecretData
$cparseJSON :: Value -> Parser SecretData
FromJSON)

data SecretSettings =
  SecretSettings
    { SecretSettings -> Int
max_versions :: !Int
    , SecretSettings -> Bool
cas_required :: !Bool
    } deriving (Int -> SecretSettings -> ShowS
[SecretSettings] -> ShowS
SecretSettings -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SecretSettings] -> ShowS
$cshowList :: [SecretSettings] -> ShowS
show :: SecretSettings -> String
$cshow :: SecretSettings -> String
showsPrec :: Int -> SecretSettings -> ShowS
$cshowsPrec :: Int -> SecretSettings -> ShowS
Show, forall x. Rep SecretSettings x -> SecretSettings
forall x. SecretSettings -> Rep SecretSettings x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep SecretSettings x -> SecretSettings
$cfrom :: forall x. SecretSettings -> Rep SecretSettings x
Generic, [SecretSettings] -> Encoding
[SecretSettings] -> Value
SecretSettings -> Encoding
SecretSettings -> Value
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [SecretSettings] -> Encoding
$ctoEncodingList :: [SecretSettings] -> Encoding
toJSONList :: [SecretSettings] -> Value
$ctoJSONList :: [SecretSettings] -> Value
toEncoding :: SecretSettings -> Encoding
$ctoEncoding :: SecretSettings -> Encoding
toJSON :: SecretSettings -> Value
$ctoJSON :: SecretSettings -> Value
ToJSON, Value -> Parser [SecretSettings]
Value -> Parser SecretSettings
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [SecretSettings]
$cparseJSONList :: Value -> Parser [SecretSettings]
parseJSON :: Value -> Parser SecretSettings
$cparseJSON :: Value -> Parser SecretSettings
FromJSON)

newtype SecretPath =
  SecretPath
    { SecretPath -> String
path :: String }
    deriving (Int -> SecretPath -> ShowS
[SecretPath] -> ShowS
SecretPath -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SecretPath] -> ShowS
$cshowList :: [SecretPath] -> ShowS
show :: SecretPath -> String
$cshow :: SecretPath -> String
showsPrec :: Int -> SecretPath -> ShowS
$cshowsPrec :: Int -> SecretPath -> ShowS
Show, forall x. Rep SecretPath x -> SecretPath
forall x. SecretPath -> Rep SecretPath x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep SecretPath x -> SecretPath
$cfrom :: forall x. SecretPath -> Rep SecretPath x
Generic, [SecretPath] -> Encoding
[SecretPath] -> Value
SecretPath -> Encoding
SecretPath -> Value
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [SecretPath] -> Encoding
$ctoEncodingList :: [SecretPath] -> Encoding
toJSONList :: [SecretPath] -> Value
$ctoJSONList :: [SecretPath] -> Value
toEncoding :: SecretPath -> Encoding
$ctoEncoding :: SecretPath -> Encoding
toJSON :: SecretPath -> Value
$ctoJSON :: SecretPath -> Value
ToJSON)

data CheckAndSet
  = WriteAllowed
  | CreateOnly
  | CurrentVersion !Int
  deriving (Int -> CheckAndSet -> ShowS
[CheckAndSet] -> ShowS
CheckAndSet -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CheckAndSet] -> ShowS
$cshowList :: [CheckAndSet] -> ShowS
show :: CheckAndSet -> String
$cshow :: CheckAndSet -> String
showsPrec :: Int -> CheckAndSet -> ShowS
$cshowsPrec :: Int -> CheckAndSet -> ShowS
Show, forall x. Rep CheckAndSet x -> CheckAndSet
forall x. CheckAndSet -> Rep CheckAndSet x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep CheckAndSet x -> CheckAndSet
$cfrom :: forall x. CheckAndSet -> Rep CheckAndSet x
Generic, [CheckAndSet] -> Encoding
[CheckAndSet] -> Value
CheckAndSet -> Encoding
CheckAndSet -> Value
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [CheckAndSet] -> Encoding
$ctoEncodingList :: [CheckAndSet] -> Encoding
toJSONList :: [CheckAndSet] -> Value
$ctoJSONList :: [CheckAndSet] -> Value
toEncoding :: CheckAndSet -> Encoding
$ctoEncoding :: CheckAndSet -> Encoding
toJSON :: CheckAndSet -> Value
$ctoJSON :: CheckAndSet -> Value
ToJSON)

newtype PutSecretOptions =
  PutSecretOptions
    { PutSecretOptions -> CheckAndSet
cas :: CheckAndSet }
    deriving (Int -> PutSecretOptions -> ShowS
[PutSecretOptions] -> ShowS
PutSecretOptions -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PutSecretOptions] -> ShowS
$cshowList :: [PutSecretOptions] -> ShowS
show :: PutSecretOptions -> String
$cshow :: PutSecretOptions -> String
showsPrec :: Int -> PutSecretOptions -> ShowS
$cshowsPrec :: Int -> PutSecretOptions -> ShowS
Show)

instance ToJSON PutSecretOptions where
  toJSON :: PutSecretOptions -> Value
toJSON PutSecretOptions { cas :: PutSecretOptions -> CheckAndSet
cas = CheckAndSet
WriteAllowed } = [Pair] -> Value
object []
  toJSON PutSecretOptions { cas :: PutSecretOptions -> CheckAndSet
cas = CheckAndSet
CreateOnly }   = [Pair] -> Value
object [ Key
"cas" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Scientific -> Value
Number Scientific
0.0 ]
  toJSON PutSecretOptions { cas :: PutSecretOptions -> CheckAndSet
cas = CurrentVersion Int
v } =
    case forall a. Read a => String -> Maybe a
readMaybe (forall a. Show a => a -> String
show Int
v) of
      Just Scientific
s  -> [Pair] -> Value
object [ Key
"cas" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Scientific -> Value
Number Scientific
s ]
      Maybe Scientific
Nothing -> forall a. HasCallStack => String -> a
error String
"Expected type Int"

data PutSecretRequestBody =
  PutSecretRequestBody
    { PutSecretRequestBody -> PutSecretOptions
options  :: !PutSecretOptions
    , PutSecretRequestBody -> SecretData
put_data :: !SecretData
    }

instance ToJSON PutSecretRequestBody where
  toJSON :: PutSecretRequestBody -> Value
toJSON (PutSecretRequestBody PutSecretOptions
os SecretData
sd) =
    [Pair] -> Value
object
      [ Key
"options" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= PutSecretOptions
os
      , Key
"data"    forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= SecretData
sd
      ]

data VaultKey
  = VaultKey    !String
  | VaultFolder !String
  deriving (Int -> VaultKey -> ShowS
[VaultKey] -> ShowS
VaultKey -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [VaultKey] -> ShowS
$cshowList :: [VaultKey] -> ShowS
show :: VaultKey -> String
$cshow :: VaultKey -> String
showsPrec :: Int -> VaultKey -> ShowS
$cshowsPrec :: Int -> VaultKey -> ShowS
Show)