You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

264 lines
8.5 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. package iamapi
  2. import (
  3. "encoding/xml"
  4. "net/http"
  5. "net/http/httptest"
  6. "net/url"
  7. "regexp"
  8. "testing"
  9. "github.com/aws/aws-sdk-go/aws"
  10. "github.com/aws/aws-sdk-go/aws/session"
  11. "github.com/aws/aws-sdk-go/service/iam"
  12. "github.com/gorilla/mux"
  13. "github.com/jinzhu/copier"
  14. "github.com/seaweedfs/seaweedfs/weed/pb/iam_pb"
  15. "github.com/stretchr/testify/assert"
  16. )
  17. var GetS3ApiConfiguration func(s3cfg *iam_pb.S3ApiConfiguration) (err error)
  18. var PutS3ApiConfiguration func(s3cfg *iam_pb.S3ApiConfiguration) (err error)
  19. var GetPolicies func(policies *Policies) (err error)
  20. var PutPolicies func(policies *Policies) (err error)
  21. var s3config = iam_pb.S3ApiConfiguration{}
  22. var policiesFile = Policies{Policies: make(map[string]PolicyDocument)}
  23. var ias = IamApiServer{s3ApiConfig: iamS3ApiConfigureMock{}}
  24. type iamS3ApiConfigureMock struct{}
  25. func (iam iamS3ApiConfigureMock) GetS3ApiConfiguration(s3cfg *iam_pb.S3ApiConfiguration) (err error) {
  26. _ = copier.Copy(&s3cfg.Identities, &s3config.Identities)
  27. return nil
  28. }
  29. func (iam iamS3ApiConfigureMock) PutS3ApiConfiguration(s3cfg *iam_pb.S3ApiConfiguration) (err error) {
  30. _ = copier.Copy(&s3config.Identities, &s3cfg.Identities)
  31. return nil
  32. }
  33. func (iam iamS3ApiConfigureMock) GetPolicies(policies *Policies) (err error) {
  34. _ = copier.Copy(&policies, &policiesFile)
  35. return nil
  36. }
  37. func (iam iamS3ApiConfigureMock) PutPolicies(policies *Policies) (err error) {
  38. _ = copier.Copy(&policiesFile, &policies)
  39. return nil
  40. }
  41. func TestCreateUser(t *testing.T) {
  42. userName := aws.String("Test")
  43. params := &iam.CreateUserInput{UserName: userName}
  44. req, _ := iam.New(session.New()).CreateUserRequest(params)
  45. _ = req.Build()
  46. out := CreateUserResponse{}
  47. response, err := executeRequest(req.HTTPRequest, out)
  48. assert.Equal(t, nil, err)
  49. assert.Equal(t, http.StatusOK, response.Code)
  50. //assert.Equal(t, out.XMLName, "lol")
  51. }
  52. func TestListUsers(t *testing.T) {
  53. params := &iam.ListUsersInput{}
  54. req, _ := iam.New(session.New()).ListUsersRequest(params)
  55. _ = req.Build()
  56. out := ListUsersResponse{}
  57. response, err := executeRequest(req.HTTPRequest, out)
  58. assert.Equal(t, nil, err)
  59. assert.Equal(t, http.StatusOK, response.Code)
  60. }
  61. func TestListAccessKeys(t *testing.T) {
  62. svc := iam.New(session.New())
  63. params := &iam.ListAccessKeysInput{}
  64. req, _ := svc.ListAccessKeysRequest(params)
  65. _ = req.Build()
  66. out := ListAccessKeysResponse{}
  67. response, err := executeRequest(req.HTTPRequest, out)
  68. assert.Equal(t, nil, err)
  69. assert.Equal(t, http.StatusOK, response.Code)
  70. }
  71. func TestGetUser(t *testing.T) {
  72. userName := aws.String("Test")
  73. params := &iam.GetUserInput{UserName: userName}
  74. req, _ := iam.New(session.New()).GetUserRequest(params)
  75. _ = req.Build()
  76. out := GetUserResponse{}
  77. response, err := executeRequest(req.HTTPRequest, out)
  78. assert.Equal(t, nil, err)
  79. assert.Equal(t, http.StatusOK, response.Code)
  80. }
  81. // Todo flat statement
  82. func TestCreatePolicy(t *testing.T) {
  83. params := &iam.CreatePolicyInput{
  84. PolicyName: aws.String("S3-read-only-example-bucket"),
  85. PolicyDocument: aws.String(`
  86. {
  87. "Version": "2012-10-17",
  88. "Statement": [
  89. {
  90. "Effect": "Allow",
  91. "Action": [
  92. "s3:Get*",
  93. "s3:List*"
  94. ],
  95. "Resource": [
  96. "arn:aws:s3:::EXAMPLE-BUCKET",
  97. "arn:aws:s3:::EXAMPLE-BUCKET/*"
  98. ]
  99. }
  100. ]
  101. }`),
  102. }
  103. req, _ := iam.New(session.New()).CreatePolicyRequest(params)
  104. _ = req.Build()
  105. out := CreatePolicyResponse{}
  106. response, err := executeRequest(req.HTTPRequest, out)
  107. assert.Equal(t, nil, err)
  108. assert.Equal(t, http.StatusOK, response.Code)
  109. }
  110. func TestPutUserPolicy(t *testing.T) {
  111. userName := aws.String("Test")
  112. params := &iam.PutUserPolicyInput{
  113. UserName: userName,
  114. PolicyName: aws.String("S3-read-only-example-bucket"),
  115. PolicyDocument: aws.String(
  116. `{
  117. "Version": "2012-10-17",
  118. "Statement": [
  119. {
  120. "Effect": "Allow",
  121. "Action": [
  122. "s3:Get*",
  123. "s3:List*"
  124. ],
  125. "Resource": [
  126. "arn:aws:s3:::EXAMPLE-BUCKET",
  127. "arn:aws:s3:::EXAMPLE-BUCKET/*"
  128. ]
  129. }
  130. ]
  131. }`),
  132. }
  133. req, _ := iam.New(session.New()).PutUserPolicyRequest(params)
  134. _ = req.Build()
  135. out := PutUserPolicyResponse{}
  136. response, err := executeRequest(req.HTTPRequest, out)
  137. assert.Equal(t, nil, err)
  138. assert.Equal(t, http.StatusOK, response.Code)
  139. }
  140. func TestPutUserPolicyError(t *testing.T) {
  141. userName := aws.String("InvalidUser")
  142. params := &iam.PutUserPolicyInput{
  143. UserName: userName,
  144. PolicyName: aws.String("S3-read-only-example-bucket"),
  145. PolicyDocument: aws.String(
  146. `{
  147. "Version": "2012-10-17",
  148. "Statement": [
  149. {
  150. "Effect": "Allow",
  151. "Action": [
  152. "s3:Get*",
  153. "s3:List*"
  154. ],
  155. "Resource": [
  156. "arn:aws:s3:::EXAMPLE-BUCKET",
  157. "arn:aws:s3:::EXAMPLE-BUCKET/*"
  158. ]
  159. }
  160. ]
  161. }`),
  162. }
  163. req, _ := iam.New(session.New()).PutUserPolicyRequest(params)
  164. _ = req.Build()
  165. response, err := executeRequest(req.HTTPRequest, nil)
  166. assert.Equal(t, nil, err)
  167. assert.Equal(t, http.StatusNotFound, response.Code)
  168. expectedMessage := "the user with name InvalidUser cannot be found"
  169. expectedCode := "NoSuchEntity"
  170. code, message := extractErrorCodeAndMessage(response)
  171. assert.Equal(t, expectedMessage, message)
  172. assert.Equal(t, expectedCode, code)
  173. }
  174. func extractErrorCodeAndMessage(response *httptest.ResponseRecorder) (string, string) {
  175. pattern := `<Error><Code>(.*)</Code><Message>(.*)</Message><Type>(.*)</Type></Error>`
  176. re := regexp.MustCompile(pattern)
  177. code := re.FindStringSubmatch(response.Body.String())[1]
  178. message := re.FindStringSubmatch(response.Body.String())[2]
  179. return code, message
  180. }
  181. func TestGetUserPolicy(t *testing.T) {
  182. userName := aws.String("Test")
  183. params := &iam.GetUserPolicyInput{UserName: userName, PolicyName: aws.String("S3-read-only-example-bucket")}
  184. req, _ := iam.New(session.New()).GetUserPolicyRequest(params)
  185. _ = req.Build()
  186. out := GetUserPolicyResponse{}
  187. response, err := executeRequest(req.HTTPRequest, out)
  188. assert.Equal(t, nil, err)
  189. assert.Equal(t, http.StatusOK, response.Code)
  190. }
  191. func TestUpdateUser(t *testing.T) {
  192. userName := aws.String("Test")
  193. newUserName := aws.String("Test-New")
  194. params := &iam.UpdateUserInput{NewUserName: newUserName, UserName: userName}
  195. req, _ := iam.New(session.New()).UpdateUserRequest(params)
  196. _ = req.Build()
  197. out := UpdateUserResponse{}
  198. response, err := executeRequest(req.HTTPRequest, out)
  199. assert.Equal(t, nil, err)
  200. assert.Equal(t, http.StatusOK, response.Code)
  201. }
  202. func TestDeleteUser(t *testing.T) {
  203. userName := aws.String("Test-New")
  204. params := &iam.DeleteUserInput{UserName: userName}
  205. req, _ := iam.New(session.New()).DeleteUserRequest(params)
  206. _ = req.Build()
  207. out := DeleteUserResponse{}
  208. response, err := executeRequest(req.HTTPRequest, out)
  209. assert.Equal(t, nil, err)
  210. assert.Equal(t, http.StatusOK, response.Code)
  211. }
  212. func executeRequest(req *http.Request, v interface{}) (*httptest.ResponseRecorder, error) {
  213. rr := httptest.NewRecorder()
  214. apiRouter := mux.NewRouter().SkipClean(true)
  215. apiRouter.Path("/").Methods(http.MethodPost).HandlerFunc(ias.DoActions)
  216. apiRouter.ServeHTTP(rr, req)
  217. return rr, xml.Unmarshal(rr.Body.Bytes(), &v)
  218. }
  219. func TestHandleImplicitUsername(t *testing.T) {
  220. var tests = []struct {
  221. r *http.Request
  222. values url.Values
  223. userName string
  224. }{
  225. {&http.Request{}, url.Values{}, ""},
  226. {&http.Request{Header: http.Header{"Authorization": []string{"AWS4-HMAC-SHA256 Credential=197FSAQ7HHTA48X64O3A/20220420/test1/iam/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=6757dc6b3d7534d67e17842760310e99ee695408497f6edc4fdb84770c252dc8"}}}, url.Values{}, "test1"},
  227. {&http.Request{Header: http.Header{"Authorization": []string{"AWS4-HMAC-SHA256 =197FSAQ7HHTA48X64O3A/20220420/test1/iam/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=6757dc6b3d7534d67e17842760310e99ee695408497f6edc4fdb84770c252dc8"}}}, url.Values{}, ""},
  228. {&http.Request{Header: http.Header{"Authorization": []string{"AWS4-HMAC-SHA256 Credential=197FSAQ7HHTA48X64O3A/20220420/test1/iam/aws4_request SignedHeaders=content-type;host;x-amz-date Signature=6757dc6b3d7534d67e17842760310e99ee695408497f6edc4fdb84770c252dc8"}}}, url.Values{}, ""},
  229. {&http.Request{Header: http.Header{"Authorization": []string{"AWS4-HMAC-SHA256 Credential=197FSAQ7HHTA48X64O3A/20220420/test1/iam, SignedHeaders=content-type;host;x-amz-date, Signature=6757dc6b3d7534d67e17842760310e99ee695408497f6edc4fdb84770c252dc8"}}}, url.Values{}, ""},
  230. }
  231. for i, test := range tests {
  232. handleImplicitUsername(test.r, test.values)
  233. if un := test.values.Get("UserName"); un != test.userName {
  234. t.Errorf("No.%d: Got: %v, Expected: %v", i, un, test.userName)
  235. }
  236. }
  237. }