--
-- MinIO Haskell SDK, (C) 2017-2023 MinIO, Inc.
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
--     http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE StrictData #-}

module Network.Minio.Credentials.Types where

import qualified Data.ByteArray as BA
import Lib.Prelude (UTCTime)
import qualified Network.HTTP.Client as NC

-- | Access Key type.
newtype AccessKey = AccessKey {AccessKey -> Text
unAccessKey :: Text}
  deriving stock (Int -> AccessKey -> ShowS
[AccessKey] -> ShowS
AccessKey -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AccessKey] -> ShowS
$cshowList :: [AccessKey] -> ShowS
show :: AccessKey -> String
$cshow :: AccessKey -> String
showsPrec :: Int -> AccessKey -> ShowS
$cshowsPrec :: Int -> AccessKey -> ShowS
Show)
  deriving newtype (AccessKey -> AccessKey -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AccessKey -> AccessKey -> Bool
$c/= :: AccessKey -> AccessKey -> Bool
== :: AccessKey -> AccessKey -> Bool
$c== :: AccessKey -> AccessKey -> Bool
Eq, String -> AccessKey
forall a. (String -> a) -> IsString a
fromString :: String -> AccessKey
$cfromString :: String -> AccessKey
IsString, NonEmpty AccessKey -> AccessKey
AccessKey -> AccessKey -> AccessKey
forall b. Integral b => b -> AccessKey -> AccessKey
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
stimes :: forall b. Integral b => b -> AccessKey -> AccessKey
$cstimes :: forall b. Integral b => b -> AccessKey -> AccessKey
sconcat :: NonEmpty AccessKey -> AccessKey
$csconcat :: NonEmpty AccessKey -> AccessKey
<> :: AccessKey -> AccessKey -> AccessKey
$c<> :: AccessKey -> AccessKey -> AccessKey
Semigroup, Semigroup AccessKey
AccessKey
[AccessKey] -> AccessKey
AccessKey -> AccessKey -> AccessKey
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
mconcat :: [AccessKey] -> AccessKey
$cmconcat :: [AccessKey] -> AccessKey
mappend :: AccessKey -> AccessKey -> AccessKey
$cmappend :: AccessKey -> AccessKey -> AccessKey
mempty :: AccessKey
$cmempty :: AccessKey
Monoid)

-- | Secret Key type - has a show instance that does not print the value.
newtype SecretKey = SecretKey {SecretKey -> ScrubbedBytes
unSecretKey :: BA.ScrubbedBytes}
  deriving stock (Int -> SecretKey -> ShowS
[SecretKey] -> ShowS
SecretKey -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SecretKey] -> ShowS
$cshowList :: [SecretKey] -> ShowS
show :: SecretKey -> String
$cshow :: SecretKey -> String
showsPrec :: Int -> SecretKey -> ShowS
$cshowsPrec :: Int -> SecretKey -> ShowS
Show)
  deriving newtype (SecretKey -> SecretKey -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SecretKey -> SecretKey -> Bool
$c/= :: SecretKey -> SecretKey -> Bool
== :: SecretKey -> SecretKey -> Bool
$c== :: SecretKey -> SecretKey -> Bool
Eq, String -> SecretKey
forall a. (String -> a) -> IsString a
fromString :: String -> SecretKey
$cfromString :: String -> SecretKey
IsString, NonEmpty SecretKey -> SecretKey
SecretKey -> SecretKey -> SecretKey
forall b. Integral b => b -> SecretKey -> SecretKey
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
stimes :: forall b. Integral b => b -> SecretKey -> SecretKey
$cstimes :: forall b. Integral b => b -> SecretKey -> SecretKey
sconcat :: NonEmpty SecretKey -> SecretKey
$csconcat :: NonEmpty SecretKey -> SecretKey
<> :: SecretKey -> SecretKey -> SecretKey
$c<> :: SecretKey -> SecretKey -> SecretKey
Semigroup, Semigroup SecretKey
SecretKey
[SecretKey] -> SecretKey
SecretKey -> SecretKey -> SecretKey
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
mconcat :: [SecretKey] -> SecretKey
$cmconcat :: [SecretKey] -> SecretKey
mappend :: SecretKey -> SecretKey -> SecretKey
$cmappend :: SecretKey -> SecretKey -> SecretKey
mempty :: SecretKey
$cmempty :: SecretKey
Monoid)

-- | Session Token type - has a show instance that does not print the value.
newtype SessionToken = SessionToken {SessionToken -> ScrubbedBytes
unSessionToken :: BA.ScrubbedBytes}
  deriving stock (Int -> SessionToken -> ShowS
[SessionToken] -> ShowS
SessionToken -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SessionToken] -> ShowS
$cshowList :: [SessionToken] -> ShowS
show :: SessionToken -> String
$cshow :: SessionToken -> String
showsPrec :: Int -> SessionToken -> ShowS
$cshowsPrec :: Int -> SessionToken -> ShowS
Show)
  deriving newtype (SessionToken -> SessionToken -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SessionToken -> SessionToken -> Bool
$c/= :: SessionToken -> SessionToken -> Bool
== :: SessionToken -> SessionToken -> Bool
$c== :: SessionToken -> SessionToken -> Bool
Eq, String -> SessionToken
forall a. (String -> a) -> IsString a
fromString :: String -> SessionToken
$cfromString :: String -> SessionToken
IsString, NonEmpty SessionToken -> SessionToken
SessionToken -> SessionToken -> SessionToken
forall b. Integral b => b -> SessionToken -> SessionToken
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
stimes :: forall b. Integral b => b -> SessionToken -> SessionToken
$cstimes :: forall b. Integral b => b -> SessionToken -> SessionToken
sconcat :: NonEmpty SessionToken -> SessionToken
$csconcat :: NonEmpty SessionToken -> SessionToken
<> :: SessionToken -> SessionToken -> SessionToken
$c<> :: SessionToken -> SessionToken -> SessionToken
Semigroup, Semigroup SessionToken
SessionToken
[SessionToken] -> SessionToken
SessionToken -> SessionToken -> SessionToken
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
mconcat :: [SessionToken] -> SessionToken
$cmconcat :: [SessionToken] -> SessionToken
mappend :: SessionToken -> SessionToken -> SessionToken
$cmappend :: SessionToken -> SessionToken -> SessionToken
mempty :: SessionToken
$cmempty :: SessionToken
Monoid)

-- | Object storage credential data type. It has support for the optional
-- [SessionToken](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html)
-- for using temporary credentials requested via STS.
--
-- The show instance for this type does not print the value of secrets for
-- security.
--
-- @since 1.7.0
data CredentialValue = CredentialValue
  { CredentialValue -> AccessKey
cvAccessKey :: AccessKey,
    CredentialValue -> SecretKey
cvSecretKey :: SecretKey,
    CredentialValue -> Maybe SessionToken
cvSessionToken :: Maybe SessionToken
  }
  deriving stock (CredentialValue -> CredentialValue -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CredentialValue -> CredentialValue -> Bool
$c/= :: CredentialValue -> CredentialValue -> Bool
== :: CredentialValue -> CredentialValue -> Bool
$c== :: CredentialValue -> CredentialValue -> Bool
Eq, Int -> CredentialValue -> ShowS
[CredentialValue] -> ShowS
CredentialValue -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CredentialValue] -> ShowS
$cshowList :: [CredentialValue] -> ShowS
show :: CredentialValue -> String
$cshow :: CredentialValue -> String
showsPrec :: Int -> CredentialValue -> ShowS
$cshowsPrec :: Int -> CredentialValue -> ShowS
Show)

scrubbedToText :: BA.ScrubbedBytes -> Text
scrubbedToText :: ScrubbedBytes -> Text
scrubbedToText =
  let b2t :: ByteString -> Text
      b2t :: ByteString -> Text
b2t = forall a b. ConvertUtf8 a b => b -> a
decodeUtf8
      s2b :: BA.ScrubbedBytes -> ByteString
      s2b :: ScrubbedBytes -> ByteString
s2b = forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
BA.convert
   in ByteString -> Text
b2t forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScrubbedBytes -> ByteString
s2b

-- | Convert a 'CredentialValue' to a text tuple. Use this to output the
-- credential to files or other programs.
credentialValueText :: CredentialValue -> (Text, Text, Maybe Text)
credentialValueText :: CredentialValue -> (Text, Text, Maybe Text)
credentialValueText CredentialValue
cv =
  ( coerce :: forall a b. Coercible a b => a -> b
coerce forall a b. (a -> b) -> a -> b
$ CredentialValue -> AccessKey
cvAccessKey CredentialValue
cv,
    (ScrubbedBytes -> Text
scrubbedToText forall b c a. (b -> c) -> (a -> b) -> a -> c
. coerce :: forall a b. Coercible a b => a -> b
coerce) forall a b. (a -> b) -> a -> b
$ CredentialValue -> SecretKey
cvSecretKey CredentialValue
cv,
    ScrubbedBytes -> Text
scrubbedToText forall b c a. (b -> c) -> (a -> b) -> a -> c
. coerce :: forall a b. Coercible a b => a -> b
coerce forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CredentialValue -> Maybe SessionToken
cvSessionToken CredentialValue
cv
  )

-- | Endpoint represented by host, port and TLS enabled flag.
type Endpoint = (ByteString, Int, Bool)

-- | Typeclass for STS credential providers.
--
-- @since 1.7.0
class STSCredentialProvider p where
  retrieveSTSCredentials ::
    p ->
    -- | STS Endpoint (host, port, isSecure)
    Endpoint ->
    NC.Manager ->
    IO (CredentialValue, ExpiryTime)
  getSTSEndpoint :: p -> Maybe Text

-- | 'ExpiryTime' represents a time at which a credential expires.
newtype ExpiryTime = ExpiryTime {ExpiryTime -> UTCTime
unExpiryTime :: UTCTime}
  deriving stock (Int -> ExpiryTime -> ShowS
[ExpiryTime] -> ShowS
ExpiryTime -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ExpiryTime] -> ShowS
$cshowList :: [ExpiryTime] -> ShowS
show :: ExpiryTime -> String
$cshow :: ExpiryTime -> String
showsPrec :: Int -> ExpiryTime -> ShowS
$cshowsPrec :: Int -> ExpiryTime -> ShowS
Show)
  deriving newtype (ExpiryTime -> ExpiryTime -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ExpiryTime -> ExpiryTime -> Bool
$c/= :: ExpiryTime -> ExpiryTime -> Bool
== :: ExpiryTime -> ExpiryTime -> Bool
$c== :: ExpiryTime -> ExpiryTime -> Bool
Eq)