1package signers
2
3import (
4	"fmt"
5	"net/http"
6	"net/http/httptest"
7	"strings"
8	"testing"
9	"time"
10
11	"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
12	"github.com/stretchr/testify/assert"
13)
14
15func Test_ECSRamRole(t *testing.T) {
16	c := credentials.NewEcsRamRoleCredential("roleName")
17	singer := NewEcsRamRoleSigner(c, nil)
18	assert.NotNil(t, singer)
19	assert.Equal(t, "HMAC-SHA1", singer.GetName())
20	assert.Equal(t, "", singer.GetType())
21	assert.Equal(t, "1.0", singer.GetVersion())
22}
23
24func Test_EcsRamRoleSigner_buildCommonRequest(t *testing.T) {
25	c := credentials.NewEcsRamRoleCredential("roleName")
26	s := NewEcsRamRoleSigner(c, nil)
27	request, err := s.buildCommonRequest()
28	assert.Nil(t, err)
29	assert.Nil(t, request)
30}
31
32func Test_EcsRamRoleSigner_GetAccessKeyId(t *testing.T) {
33	c := credentials.NewEcsRamRoleCredential("roleName")
34	s := NewEcsRamRoleSigner(c, nil)
35	assert.NotNil(t, s)
36	// Update our securityCredURL to point at our local test server.
37	originalSecurityCredURL := securityCredURL
38	securityCredURL = strings.Replace(securityCredURL, "http://100.100.100.200", "http://invalid-domain-xxx", -1)
39	defer func() {
40		securityCredURL = originalSecurityCredURL
41	}()
42
43	accessKeyId, err := s.GetAccessKeyId()
44	assert.True(t, strings.HasSuffix(err.Error(), "no such host"))
45	assert.Equal(t, "", accessKeyId)
46}
47
48func mockServer(status int, json string) (server *httptest.Server) {
49	// Start a test server locally.
50	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
51		switch r.URL.Path {
52		case "/latest/meta-data/ram/security-credentials/roleName":
53			w.WriteHeader(status)
54			w.Write([]byte(json))
55		}
56	}))
57	return ts
58}
59
60func Test_EcsRamRoleSigner_GetAccessKeyId2(t *testing.T) {
61	c := credentials.NewEcsRamRoleCredential("roleName")
62	s := NewEcsRamRoleSigner(c, nil)
63	assert.NotNil(t, s)
64	// Start a test server locally.
65	ts := mockServer(400, "{}")
66	defer ts.Close()
67	originalSecurityCredURL := securityCredURL
68	securityCredURL = strings.Replace(securityCredURL, "http://100.100.100.200", ts.URL, -1)
69	defer func() {
70		securityCredURL = originalSecurityCredURL
71	}()
72	accessKeyId, err := s.GetAccessKeyId()
73	assert.Equal(t, "SDK.ServerError\nErrorCode: \nRecommend: \nRequestId: \nMessage: {}", err.Error())
74	assert.Equal(t, "", accessKeyId)
75}
76
77func Test_EcsRamRoleSigner_GetAccessKeyId3(t *testing.T) {
78	c := credentials.NewEcsRamRoleCredential("roleName")
79	s := NewEcsRamRoleSigner(c, nil)
80	assert.NotNil(t, s)
81	// Start a test server locally.
82	ts := mockServer(200, "invalid json")
83	defer ts.Close()
84	originalSecurityCredURL := securityCredURL
85	securityCredURL = strings.Replace(securityCredURL, "http://100.100.100.200", ts.URL, -1)
86	defer func() {
87		securityCredURL = originalSecurityCredURL
88	}()
89	accessKeyId, err := s.GetAccessKeyId()
90	assert.Equal(t, "refresh Ecs sts token err, json.Unmarshal fail: invalid character 'i' looking for beginning of value", err.Error())
91	assert.Equal(t, "", accessKeyId)
92}
93
94func Test_EcsRamRoleSigner_GetAccessKeyId4(t *testing.T) {
95	c := credentials.NewEcsRamRoleCredential("roleName")
96	s := NewEcsRamRoleSigner(c, nil)
97	assert.NotNil(t, s)
98	// Start a test server locally.
99	ts := mockServer(200, `{"Code":"Fails"}`)
100	defer ts.Close()
101	originalSecurityCredURL := securityCredURL
102	securityCredURL = strings.Replace(securityCredURL, "http://100.100.100.200", ts.URL, -1)
103	defer func() {
104		securityCredURL = originalSecurityCredURL
105	}()
106	accessKeyId, err := s.GetAccessKeyId()
107	assert.Equal(t, "refresh Ecs sts token err, Code is not Success", err.Error())
108	assert.Equal(t, "", accessKeyId)
109}
110
111func Test_EcsRamRoleSigner_GetAccessKeyId5(t *testing.T) {
112	c := credentials.NewEcsRamRoleCredential("roleName")
113	s := NewEcsRamRoleSigner(c, nil)
114	assert.NotNil(t, s)
115	// Start a test server locally.
116	ts := mockServer(200, `{"Code":"Success"}`)
117	defer ts.Close()
118	originalSecurityCredURL := securityCredURL
119	securityCredURL = strings.Replace(securityCredURL, "http://100.100.100.200", ts.URL, -1)
120	defer func() {
121		securityCredURL = originalSecurityCredURL
122	}()
123	accessKeyId, err := s.GetAccessKeyId()
124	assert.Nil(t, err)
125	assert.Equal(t, "", accessKeyId)
126}
127
128func Test_EcsRamRoleSigner_GetAccessKeyId6(t *testing.T) {
129	c := credentials.NewEcsRamRoleCredential("roleName")
130	s := NewEcsRamRoleSigner(c, nil)
131	assert.NotNil(t, s)
132	// Start a test server locally.
133	ts := mockServer(201, `{"Code":"Success"}`)
134	defer ts.Close()
135	originalSecurityCredURL := securityCredURL
136	securityCredURL = strings.Replace(securityCredURL, "http://100.100.100.200", ts.URL, -1)
137	defer func() {
138		securityCredURL = originalSecurityCredURL
139	}()
140	accessKeyId, err := s.GetAccessKeyId()
141	assert.Equal(t, "refresh Ecs sts token err, httpStatus: 201, message = {\"Code\":\"Success\"}", err.Error())
142	assert.Equal(t, "", accessKeyId)
143}
144
145func Test_EcsRamRoleSigner_GetAccessKeyId_Success(t *testing.T) {
146	c := credentials.NewEcsRamRoleCredential("roleName")
147	s := NewEcsRamRoleSigner(c, nil)
148	assert.NotNil(t, s)
149	// Start a test server locally.
150	nextDay := time.Now().AddDate(0, 0, 1)
151	ts := mockServer(200, fmt.Sprintf(`{
152		"Code": "Success",
153		"AccessKeyId":"access key id",
154		"AccessKeySecret":"access key secret",
155		"SecurityToken":"security token",
156		"Expiration": "%s"
157	}`, nextDay.Format("2006-01-02T15:04:05Z")))
158	defer ts.Close()
159	originalSecurityCredURL := securityCredURL
160	securityCredURL = strings.Replace(securityCredURL, "http://100.100.100.200", ts.URL, -1)
161	defer func() {
162		securityCredURL = originalSecurityCredURL
163	}()
164	// sessionCredential should be nil
165	assert.Len(t, s.GetExtraParam(), 0)
166	assert.Nil(t, s.GetSessionCredential())
167	accessKeyId, err := s.GetAccessKeyId()
168	assert.Nil(t, err)
169	assert.Equal(t, "access key id", accessKeyId)
170	expiration := s.credentialExpiration
171	accessKeyId, err = s.GetAccessKeyId()
172	assert.NotNil(t, s.GetSessionCredential())
173	assert.Nil(t, err)
174	assert.Equal(t, "access key id", accessKeyId)
175	assert.Len(t, s.GetExtraParam(), 1)
176	assert.Equal(t, "security token", s.GetExtraParam()["SecurityToken"])
177	// the expiration should not changed. hit cache
178	assert.Equal(t, expiration, s.credentialExpiration)
179
180	assert.Equal(t, "dcM4bWGEoD5QUp9xhLW3SfcWfgs=", s.Sign("string to sign", "/"))
181	s.sessionCredential.StsToken = ""
182	assert.Len(t, s.GetExtraParam(), 0)
183}
184