forked from cubefs/cubefs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsts_handler.go
115 lines (110 loc) · 3.9 KB
/
sts_handler.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
// Copyright 2023 The CubeFS Authors.
//
// 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.
package objectnode
import (
"fmt"
"net/http"
"regexp"
"strconv"
"time"
"github.com/cubefs/cubefs/util"
"github.com/cubefs/cubefs/util/log"
)
// https://docs.aws.amazon.com/zh_cn/STS/latest/APIReference/API_GetFederationToken.html
func (o *ObjectNode) getFederationTokenHandler(w http.ResponseWriter, r *http.Request) {
var (
err error
erc *ErrorCode
)
defer func() {
o.errorResponse(w, r, err, erc)
}()
// request param check
if token := r.Header.Get(XAmzSecurityToken); token != "" {
erc = AccessDeniedBySTS
return
}
if action := r.PostFormValue(stsActionKey); action != stsActionValue {
log.LogErrorf("getFederationTokenHandler: sts action invalid: requestID(%v) action(%v)",
GetRequestID(r), action)
erc = InvalidArgument
return
}
name := r.PostFormValue(stsNameKey)
matched, _ := regexp.MatchString(`^[\w+=,.@-]*$`, name)
if len(name) < 2 || len(name) > 32 || !matched {
log.LogErrorf("getFederationTokenHandler: sts name invalid: requestID(%v) name(%v) err(%v)",
GetRequestID(r), name, err)
erc = InvalidArgument
return
}
policy := r.PostFormValue(stsPolicyKey)
if _, err = ParsePolicyV2Config(policy); err != nil {
log.LogErrorf("getFederationTokenHandler: sts policy invalid: requestID(%v) policy(%v) err(%v)",
GetRequestID(r), policy, err)
erc = &ErrorCode{
ErrorCode: "MalformedPolicyDocument",
ErrorMessage: fmt.Sprintf("The policy document was malformed: %v.", err.Error()),
StatusCode: http.StatusBadRequest,
}
return
}
seconds := r.PostFormValue(stsDurationSecondsKey)
durationSeconds, _ := strconv.ParseInt(seconds, 10, 64)
if durationSeconds < 900 || durationSeconds > 129600 {
durationSeconds = 43200
}
param := ParseRequestParam(r)
user, err := o.getUserInfoByAccessKeyV2(param.AccessKey())
if err != nil {
log.LogErrorf("getFederationTokenHandler: get user info fail: requestID(%v) accessKey(%v) err(%v)",
GetRequestID(r), param.AccessKey(), err)
return
}
// federated ak/sk generation
now := time.Now().UTC()
expireUnixStr := fmt.Sprint(now.Unix() + durationSeconds)
fedAk := stsAkPrefix + util.RandomString(13, util.Numeric|util.LowerLetter|util.UpperLetter)
fedSk := util.RandomString(32, util.Numeric|util.LowerLetter|util.UpperLetter)
sessionToken, err := EncodeFedSessionToken(user.AccessKey, user.SecretKey, fedAk, fedSk, name, policy, expireUnixStr)
if err != nil {
log.LogErrorf("getFederationTokenHandler: encode session token fail: requestID(%v) err(%v)",
GetRequestID(r), err)
return
}
// response result return
fedToken := FederationTokenResponse{
GetFederationTokenResult: &FederationTokenResult{
FederatedUser: &FederatedUser{
Arn: fmt.Sprintf("arn:aws:sts::%s:federated-user/%s", user.UserID, name),
FederatedUserId: fmt.Sprintf("%s:%s", user.UserID, name),
},
Credentials: &FederatedCredentials{
AccessKeyId: fedAk,
SecretAccessKey: fedSk,
SessionToken: sessionToken,
Expiration: now.Add(time.Duration(durationSeconds) * time.Second).Format(time.RFC3339),
},
},
}
fedToken.ResponseMetadata.RequestID = GetRequestID(r)
response, err := MarshalXMLEntity(&fedToken)
if err != nil {
log.LogErrorf("getFederationTokenHandler: xml marshal result fail: requestID(%v) fedToken(%v) err(%v)",
GetRequestID(r), fedToken, err)
return
}
writeSuccessResponseXML(w, response)
return
}