forked from Cox-Automotive/alks-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
session.go
139 lines (110 loc) · 3.4 KB
/
session.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package alks
import (
"encoding/json"
"fmt"
"log"
"time"
)
// SessionRequest is used to represent a new STS session request.
type SessionRequest struct {
SessionDuration int `json:"sessionTime"`
}
// SessionResponse is used to represent a new STS session.
type SessionResponse struct {
AccessKey string `json:"accessKey"`
SecretKey string `json:"secretKey"`
SessionToken string `json:"sessionToken"`
SessionDuration int `json:"sessionDuration"`
Expires time.Time `json:"expires"`
}
// AccountRole is used to represent an ALKS account and role combination
type AccountRole struct {
Account string `json:"account"`
Role string `json:"role"`
IamActive bool `json:"iamKeyActive"`
}
// AccountsResponseInt is used internally to represent a collection of ALKS accounts
type AccountsResponseInt struct {
Accounts map[string][]AccountRole `json:"accountListRole"`
StatusMessage string `json:"statusMessage"`
}
// AccountsResponse is used to represent a collection of ALKS accounts
type AccountsResponse struct {
Accounts []AccountRole `json:"accountListRole"`
}
func (c *Client) GetAccounts() (*AccountsResponse, error) {
log.Printf("[INFO] Requesting available accounts from ALKS")
b, err := json.Marshal(c.Account)
if err != nil {
return nil, fmt.Errorf("Error encoding account request JSON: %s", err)
}
req, err := c.NewRequest(b, "POST", "/getAccounts/")
if err != nil {
return nil, err
}
resp, err := checkResp(c.Http.Do(req))
if err != nil {
return nil, err
}
_accts := new(AccountsResponseInt)
err = decodeBody(resp, &_accts)
if err != nil {
return nil, fmt.Errorf("Error parsing session create response: %s", err)
}
if _accts.StatusMessage != "Success" {
return nil, fmt.Errorf(_accts.StatusMessage)
}
accts := new(AccountsResponse)
for k, v := range _accts.Accounts {
v[0].Account = k
accts.Accounts = append(accts.Accounts, v[0])
}
return accts, nil
}
// CreateSession will create a new STS session on AWS. If no error is
// returned then you will receive a SessionResponse object representing
// your STS session.
func (c *Client) CreateSession(sessionDuration int, useIAM bool) (*SessionResponse, error) {
log.Printf("[INFO] Creating %v hr session", sessionDuration)
var found bool = false
for _, v := range c.Durations() {
if sessionDuration == v {
found = true
}
}
if !found {
return nil, fmt.Errorf("Unsupported session duration")
}
session := SessionRequest{sessionDuration}
b, err := json.Marshal(struct {
SessionRequest
AlksAccount
}{session, c.Account})
if err != nil {
return nil, fmt.Errorf("Error encoding session create JSON: %s", err)
}
var endpoint string = "/getKeys/"
if useIAM {
endpoint = "/getIAMKeys/"
}
req, err := c.NewRequest(b, "POST", endpoint)
if err != nil {
return nil, err
}
resp, httpErr := checkResp(c.Http.Do(req))
if httpErr != nil {
return nil, err
}
sr := new(SessionResponse)
err = decodeBody(resp, &sr)
if err != nil {
return nil, fmt.Errorf("Error parsing session create response: %s", err)
}
// Most API responses that are 401 include a JSON body with error messages. getKeys & getIAMKeys do not
if len(sr.AccessKey) == 0 {
return nil, fmt.Errorf("Please validate username/password and account/role.")
}
sr.Expires = time.Now().Local().Add(time.Hour * time.Duration(sessionDuration))
sr.SessionDuration = sessionDuration
return sr, nil
}