-
Notifications
You must be signed in to change notification settings - Fork 2
/
iam.go
129 lines (110 loc) · 3.7 KB
/
iam.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
package s3
import (
"encoding/xml"
"io/ioutil"
"net/http"
"net/url"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/indigo-dc/liboidcagent-go"
"github.com/rclone/rclone/fs"
)
// IAMProvider credential provider for oidc
type IAMProvider struct {
stsEndpoint string
accountname string
useOidcAgent bool
httpClient *http.Client
creds *AssumeRoleWithWebIdentityResponse
}
// AssumeRoleWithWebIdentityResponse the struct of the STS WebIdentity call response
type AssumeRoleWithWebIdentityResponse struct {
XMLName xml.Name `xml:"https://sts.amazonaws.com/doc/2011-06-15/ AssumeRoleWithWebIdentityResponse" json:"-"`
Result WebIdentityResult `xml:"AssumeRoleWithWebIdentityResult"`
ResponseMetadata struct {
RequestID string `xml:"RequestId,omitempty"`
} `xml:"ResponseMetadata,omitempty"`
}
// AssumedRoleUser - The identifiers for the temporary security credentials that
// the operation returns. Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumedRoleUser
type AssumedRoleUser struct {
Arn string
AssumedRoleID string `xml:"AssumeRoleId"`
// contains filtered or unexported fields
}
// WebIdentityResult - Contains the response to a successful AssumeRoleWithWebIdentity
// request, including temporary credentials that can be used to make MinIO API requests.
type WebIdentityResult struct {
AssumedRoleUser AssumedRoleUser `xml:",omitempty"`
Audience string `xml:",omitempty"`
// Ref: https://github.com/minio/minio/blob/master/internal/auth/credentials.go#L96
Credentials Credentials `xml:",omitempty"`
PackedPolicySize int `xml:",omitempty"`
Provider string `xml:",omitempty"`
SubjectFromWebIdentityToken string `xml:",omitempty"`
}
// Retrieve credentials
func (t *IAMProvider) Retrieve() (credentials.Value, error) {
var err error
var token string
if t.useOidcAgent {
token, err = liboidcagent.GetAccessToken(liboidcagent.TokenRequest{
ShortName: t.accountname,
MinValidPeriod: 900,
})
if err != nil {
return credentials.Value{}, err
}
} else {
dat, err := ioutil.ReadFile(".token")
if err != nil {
fs.Errorf(err, "IAM - token read error")
return credentials.Value{}, err
}
token = string(dat)
}
fs.Debugf(token, "IAM - token")
//contentType := ""
body := url.Values{}
body.Set("Action", "AssumeRoleWithWebIdentity")
body.Set("Version", "2011-06-15")
body.Set("WebIdentityToken", token)
body.Set("DurationSeconds", "900")
// TODO: retrieve token with https POST with t.httpClient
//r, err := t.httpClient.Post(t.stsEndpoint, contentType, strings.NewReader(body.Encode()))
url, err := url.Parse(t.stsEndpoint + "?" + body.Encode())
if err != nil {
fs.Errorf(err, "IAM - encode URL")
return credentials.Value{}, err
}
fs.Debugf(url, "IAM - url")
req := http.Request{
Method: "POST",
URL: url,
}
// TODO: retrieve token with https POST with t.httpClient
r, err := t.httpClient.Do(&req)
if err != nil {
fs.Errorf(err, "IAM - http request")
return credentials.Value{}, err
}
t.creds = &AssumeRoleWithWebIdentityResponse{}
rbody, err := ioutil.ReadAll(r.Body)
if err != nil {
fs.Errorf(err, "IAM - read body")
return credentials.Value{}, err
}
err = xml.Unmarshal(rbody, t.creds)
if err != nil {
fs.Errorf(err, "IAM - unmarshal credentials")
return credentials.Value{}, err
}
return credentials.Value{
AccessKeyID: t.creds.Result.Credentials.AccessKey,
SecretAccessKey: t.creds.Result.Credentials.SecretKey,
SessionToken: t.creds.Result.Credentials.SessionToken,
}, nil
}
// IsExpired test
func (t *IAMProvider) IsExpired() bool {
return t.creds.Result.Credentials.IsExpired()
}