func (a *STSAuth) Logout() error {
	if !a.IsAuthenticated() {
		return api.ErrorUnauthenticated
	}
	if err := Logout(*a.baseURL, a.headers); err != nil {
		return err
	}
	a.token = ""
	a.headers.Del("X-Cerberus-Token")
	return nil
}
Logout deauthorizes the current valid token. This will return an error if the token
is expired or non-existent.
package auth
import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/Nike-Inc/cerberus-go-client/api"
	"github.com/Nike-Inc/cerberus-go-client/utils"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/defaults"
	"github.com/aws/aws-sdk-go/aws/endpoints"
	"github.com/aws/aws-sdk-go/aws/signer/v4"
	"net/http"
	"net/url"
	"os"
	"time"
)
type STSAuth struct {
	token   string
	region  string
	expiry  time.Time
	baseURL *url.URL
	headers http.Header
}
func NewSTSAuth(cerberusURL, region string) (*STSAuth, error) {
	if len(region) == 0 {
		return nil, fmt.Errorf("Region cannot be empty")
	}
	if len(cerberusURL) == 0 {
		return nil, fmt.Errorf("Cerberus URL cannot be empty")
	}
	parsedURL, err := utils.ValidateURL(cerberusURL)
	if err != nil {
		return nil, err
	}
	if err != nil {
		return nil, fmt.Errorf("Unable to create AWS session: %s", err)
	}
	return &STSAuth{
		region:  region,
		baseURL: parsedURL,
		headers: http.Header{
			"Content-Type": []string{"application/json"},
		},
	}, nil
}
func (a *STSAuth) GetToken(*os.File) (string, error) {
	if a.IsAuthenticated() {
		return a.token, nil
	}
	err := a.authenticate()
	return a.token, err
}
func (a *STSAuth) GetExpiry() (time.Time, error) {
	if len(a.token) > 0 {
		return a.expiry, nil
	}
	return time.Time{}, fmt.Errorf("Expiry time not set.")
}
func (a *STSAuth) authenticate() error {
	builtURL := *a.baseURL
	builtURL.Path = "v2/auth/sts-identity"
	body := bytes.NewReader([]byte("Action=GetCallerIdentity&Version=2011-06-15"))
	request, err := http.NewRequest("POST", builtURL.String(), body)
	if err != nil {
		return fmt.Errorf("Problem while creating request to Cerberus: %v", err)
	}
	headers, err := a.sign()
	if err != nil {
		return fmt.Errorf("Problem signing request to Cerberus: %v", err)
	}
	for k, v := range headers {
		request.Header.Set(k, v[0])
	}
	client := http.Client{Timeout: 10 * time.Second}
	response, err := client.Do(request)
	if err != nil {
		return fmt.Errorf("Problem while performing request to Cerberus: %v", err)
	}
	defer response.Body.Close()
	if response.StatusCode == http.StatusUnauthorized || response.StatusCode == http.StatusForbidden {
		return fmt.Errorf("Invalid credentials given. Verify that the role you are currently using is valid " +
			"with the AWS CLI ($ aws sts get-caller-identity) or with gimme-aws-creds.")
	}
	if response.StatusCode != http.StatusOK {
		apiErr := utils.ParseAPIError(response.Body)
		return fmt.Errorf("Error while trying to authenticate. Got HTTP response code %d\n%v", response.StatusCode, apiErr)
	}
	decoder := json.NewDecoder(response.Body)
	authResponse := &api.IAMAuthResponse{}
	dErr := decoder.Decode(authResponse)
	if dErr != nil {
		return fmt.Errorf("Error while trying to parse response from Cerberus: %v", err)
	}
	a.token = authResponse.Token
	a.headers.Set("X-Cerberus-Token", authResponse.Token)
	a.expiry = time.Now().Add((time.Duration(authResponse.Duration) * time.Second) - expiryDelta)
	return nil
}
func (a *STSAuth) IsAuthenticated() bool {
	return len(a.token) > 0 && time.Now().Before(a.expiry)
}
func (a *STSAuth) Refresh() error {
	if !a.IsAuthenticated() {
		return api.ErrorUnauthenticated
	}
	return a.authenticate()
}