{-# LANGUAGE DataKinds                   #-}
{-# LANGUAGE DeriveGeneric               #-}
{-# LANGUAGE FlexibleInstances           #-}
{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
{-# LANGUAGE LambdaCase                  #-}
{-# LANGUAGE NoImplicitPrelude           #-}
{-# LANGUAGE OverloadedStrings           #-}
{-# LANGUAGE RecordWildCards             #-}
{-# LANGUAGE TypeFamilies                #-}

{-# OPTIONS_GHC -fno-warn-unused-imports #-}

-- Module      : Network.AWS.STS.GetSessionToken
-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
-- License     : This Source Code Form is subject to the terms of
--               the Mozilla Public License, v. 2.0.
--               A copy of the MPL can be found in the LICENSE file or
--               you can obtain it at http://mozilla.org/MPL/2.0/.
-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
-- Stability   : experimental
-- Portability : non-portable (GHC extensions)
--
-- Derived from AWS service descriptions, licensed under Apache 2.0.

-- | Returns a set of temporary credentials for an AWS account or IAM user. The
-- credentials consist of an access key ID, a secret access key, and a security
-- token. Typically, you use 'GetSessionToken' if you want to use MFA to protect
-- programmatic calls to specific AWS APIs like Amazon EC2 'StopInstances'.
-- MFA-enabled IAM users would need to call 'GetSessionToken' and submit an MFA
-- code that is associated with their MFA device. Using the temporary security
-- credentials that are returned from the call, IAM users can then make
-- programmatic calls to APIs that require MFA authentication.
--
-- The 'GetSessionToken' action must be called by using the long-term AWS
-- security credentials of the AWS account or an IAM user. Credentials that are
-- created by IAM users are valid for the duration that you specify, between 900
-- seconds (15 minutes) and 129600 seconds (36 hours); credentials that are
-- created by using account credentials have a maximum duration of 3600 seconds
-- (1 hour).
--
-- The permissions associated with the temporary security credentials returned
-- by 'GetSessionToken' are based on the permissions associated with account or
-- IAM user whose credentials are used to call the action. If 'GetSessionToken' is
-- called using root account credentials, the temporary credentials have root
-- account permissions. Similarly, if 'GetSessionToken' is called using the
-- credentials of an IAM user, the temporary credentials have the same
-- permissions as the IAM user.
--
-- For more information about using 'GetSessionToken' to create temporary
-- credentials, go to Creating Temporary Credentials to Enable Access for IAM
-- Users in /Using Temporary Security Credentials/.
--
-- <http://docs.aws.amazon.com/STS/latest/APIReference/API_GetSessionToken.html>
module Network.AWS.STS.GetSessionToken
    (
    -- * Request
      GetSessionToken
    -- ** Request constructor
    , getSessionToken
    -- ** Request lenses
    , gstDurationSeconds
    , gstSerialNumber
    , gstTokenCode

    -- * Response
    , GetSessionTokenResponse
    -- ** Response constructor
    , getSessionTokenResponse
    -- ** Response lenses
    , gstrCredentials
    ) where

import Network.AWS.Prelude
import Network.AWS.Request.Query
import Network.AWS.STS.Types
import qualified GHC.Exts

data GetSessionToken = GetSessionToken
    { _gstDurationSeconds :: Maybe Nat
    , _gstSerialNumber    :: Maybe Text
    , _gstTokenCode       :: Maybe Text
    } deriving (Eq, Ord, Show)

-- | 'GetSessionToken' constructor.
--
-- The fields accessible through corresponding lenses are:
--
-- * 'gstDurationSeconds' @::@ 'Maybe' 'Natural'
--
-- * 'gstSerialNumber' @::@ 'Maybe' 'Text'
--
-- * 'gstTokenCode' @::@ 'Maybe' 'Text'
--
getSessionToken :: GetSessionToken
getSessionToken = GetSessionToken
    { _gstDurationSeconds = Nothing
    , _gstSerialNumber    = Nothing
    , _gstTokenCode       = Nothing
    }

-- | The duration, in seconds, that the credentials should remain valid.
-- Acceptable durations for IAM user sessions range from 900 seconds (15
-- minutes) to 129600 seconds (36 hours), with 43200 seconds (12 hours) as the
-- default. Sessions for AWS account owners are restricted to a maximum of 3600
-- seconds (one hour). If the duration is longer than one hour, the session for
-- AWS account owners defaults to one hour.
gstDurationSeconds :: Lens' GetSessionToken (Maybe Natural)
gstDurationSeconds =
    lens _gstDurationSeconds (\s a -> s { _gstDurationSeconds = a })
        . mapping _Nat

-- | The identification number of the MFA device that is associated with the IAM
-- user who is making the 'GetSessionToken' call. Specify this value if the IAM
-- user has a policy that requires MFA authentication. The value is either the
-- serial number for a hardware device (such as 'GAHT12345678') or an Amazon
-- Resource Name (ARN) for a virtual device (such as 'arn:aws:iam::123456789012:mfa/user'). You can find the device for an IAM user by going to the AWS Management
-- Console and viewing the user's security credentials.
gstSerialNumber :: Lens' GetSessionToken (Maybe Text)
gstSerialNumber = lens _gstSerialNumber (\s a -> s { _gstSerialNumber = a })

-- | The value provided by the MFA device, if MFA is required. If any policy
-- requires the IAM user to submit an MFA code, specify this value. If MFA
-- authentication is required, and the user does not provide a code when
-- requesting a set of temporary security credentials, the user will receive an
-- "access denied" response when requesting resources that require MFA
-- authentication.
gstTokenCode :: Lens' GetSessionToken (Maybe Text)
gstTokenCode = lens _gstTokenCode (\s a -> s { _gstTokenCode = a })

newtype GetSessionTokenResponse = GetSessionTokenResponse
    { _gstrCredentials :: Maybe Credentials
    } deriving (Eq, Show)

-- | 'GetSessionTokenResponse' constructor.
--
-- The fields accessible through corresponding lenses are:
--
-- * 'gstrCredentials' @::@ 'Maybe' 'Credentials'
--
getSessionTokenResponse :: GetSessionTokenResponse
getSessionTokenResponse = GetSessionTokenResponse
    { _gstrCredentials = Nothing
    }

-- | The session credentials for API authentication.
gstrCredentials :: Lens' GetSessionTokenResponse (Maybe Credentials)
gstrCredentials = lens _gstrCredentials (\s a -> s { _gstrCredentials = a })

instance ToPath GetSessionToken where
    toPath = const "/"

instance ToQuery GetSessionToken where
    toQuery GetSessionToken{..} = mconcat
        [ "DurationSeconds" =? _gstDurationSeconds
        , "SerialNumber"    =? _gstSerialNumber
        , "TokenCode"       =? _gstTokenCode
        ]

instance ToHeaders GetSessionToken

instance AWSRequest GetSessionToken where
    type Sv GetSessionToken = STS
    type Rs GetSessionToken = GetSessionTokenResponse

    request  = post "GetSessionToken"
    response = xmlResponse

instance FromXML GetSessionTokenResponse where
    parseXML = withElement "GetSessionTokenResult" $ \x -> GetSessionTokenResponse
        <$> x .@? "Credentials"