-- -- 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. -- module Network.Minio.Credentials ( CredentialValue (..), credentialValueText, STSCredentialProvider (..), AccessKey (..), SecretKey (..), SessionToken (..), ExpiryTime (..), STSCredentialStore, initSTSCredential, getSTSCredential, Creds (..), getCredential, Endpoint, -- * STS Assume Role defaultSTSAssumeRoleOptions, STSAssumeRole (..), STSAssumeRoleOptions (..), ) where import Data.Time (diffUTCTime, getCurrentTime) import qualified Network.HTTP.Client as NC import Network.Minio.Credentials.AssumeRole import Network.Minio.Credentials.Types import qualified UnliftIO.MVar as M data STSCredentialStore = STSCredentialStore { cachedCredentials :: M.MVar (CredentialValue, ExpiryTime), refreshAction :: Endpoint -> NC.Manager -> IO (CredentialValue, ExpiryTime) } initSTSCredential :: (STSCredentialProvider p) => p -> IO STSCredentialStore initSTSCredential p = do let action = retrieveSTSCredentials p -- start with dummy credential, so that refresh happens for first request. now <- getCurrentTime mvar <- M.newMVar (CredentialValue mempty mempty mempty, coerce now) return $ STSCredentialStore { cachedCredentials = mvar, refreshAction = action } getSTSCredential :: STSCredentialStore -> Endpoint -> NC.Manager -> IO (CredentialValue, Bool) getSTSCredential store ep mgr = M.modifyMVar (cachedCredentials store) $ \cc@(v, expiry) -> do now <- getCurrentTime if diffUTCTime now (coerce expiry) > 0 then do res <- refreshAction store ep mgr return (res, (fst res, True)) else return (cc, (v, False)) data Creds = CredsStatic CredentialValue | CredsSTS STSCredentialStore getCredential :: Creds -> Endpoint -> NC.Manager -> IO CredentialValue getCredential (CredsStatic v) _ _ = return v getCredential (CredsSTS s) ep mgr = fst <$> getSTSCredential s ep mgr