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.

1789 lines
56 KiB

  1. package s3api
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "github.com/aws/aws-sdk-go/aws"
  6. "github.com/aws/aws-sdk-go/service/s3"
  7. "github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
  8. "github.com/seaweedfs/seaweedfs/weed/pb/iam_pb"
  9. "github.com/seaweedfs/seaweedfs/weed/s3api/s3_constants"
  10. "github.com/seaweedfs/seaweedfs/weed/s3api/s3err"
  11. "io"
  12. "net/http"
  13. "testing"
  14. )
  15. var accountManager *IdentityAccessManagement
  16. func init() {
  17. accountManager = &IdentityAccessManagement{}
  18. _ = accountManager.loadS3ApiConfiguration(&iam_pb.S3ApiConfiguration{
  19. Accounts: []*iam_pb.Account{
  20. {
  21. Id: "accountA",
  22. DisplayName: "accountAName",
  23. EmailAddress: "accountA@example.com",
  24. },
  25. {
  26. Id: "accountB",
  27. DisplayName: "accountBName",
  28. EmailAddress: "accountB@example.com",
  29. },
  30. },
  31. })
  32. }
  33. func TestGetAccountId(t *testing.T) {
  34. req := &http.Request{
  35. Header: make(map[string][]string),
  36. }
  37. //case1
  38. //accountId: "admin"
  39. req.Header.Set(s3_constants.AmzAccountId, s3_constants.AccountAdminId)
  40. if GetAccountId(req) != s3_constants.AccountAdminId {
  41. t.Fatal("expect accountId: admin")
  42. }
  43. //case2
  44. //accountId: "anoymous"
  45. req.Header.Set(s3_constants.AmzAccountId, s3_constants.AccountAnonymousId)
  46. if GetAccountId(req) != s3_constants.AccountAnonymousId {
  47. t.Fatal("expect accountId: anonymous")
  48. }
  49. //case3
  50. //accountId is nil => "anonymous"
  51. req.Header.Del(s3_constants.AmzAccountId)
  52. if GetAccountId(req) != s3_constants.AccountAnonymousId {
  53. t.Fatal("expect accountId: anonymous")
  54. }
  55. }
  56. func TestExtractAcl(t *testing.T) {
  57. type Case struct {
  58. id int
  59. resultErrCode, expectErrCode s3err.ErrorCode
  60. resultGrants, expectGrants []*s3.Grant
  61. }
  62. testCases := make([]*Case, 0)
  63. accountAdminId := "admin"
  64. {
  65. //case1 (good case)
  66. //parse acp from request body
  67. req := &http.Request{
  68. Header: make(map[string][]string),
  69. }
  70. req.Body = io.NopCloser(bytes.NewReader([]byte(`
  71. <AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  72. <Owner>
  73. <ID>admin</ID>
  74. <DisplayName>admin</DisplayName>
  75. </Owner>
  76. <AccessControlList>
  77. <Grant>
  78. <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
  79. <ID>admin</ID>
  80. </Grantee>
  81. <Permission>FULL_CONTROL</Permission>
  82. </Grant>
  83. <Grant>
  84. <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
  85. <URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
  86. </Grantee>
  87. <Permission>FULL_CONTROL</Permission>
  88. </Grant>
  89. </AccessControlList>
  90. </AccessControlPolicy>
  91. `)))
  92. objectWriter := "accountA"
  93. grants, errCode := ExtractAcl(req, accountManager, s3_constants.OwnershipObjectWriter, accountAdminId, accountAdminId, objectWriter)
  94. testCases = append(testCases, &Case{
  95. 1,
  96. errCode, s3err.ErrNone,
  97. grants, []*s3.Grant{
  98. {
  99. Grantee: &s3.Grantee{
  100. Type: &s3_constants.GrantTypeCanonicalUser,
  101. ID: &accountAdminId,
  102. },
  103. Permission: &s3_constants.PermissionFullControl,
  104. },
  105. {
  106. Grantee: &s3.Grantee{
  107. Type: &s3_constants.GrantTypeGroup,
  108. URI: &s3_constants.GranteeGroupAllUsers,
  109. },
  110. Permission: &s3_constants.PermissionFullControl,
  111. },
  112. },
  113. })
  114. }
  115. {
  116. //case2 (good case)
  117. //parse acp from header (cannedAcl)
  118. req := &http.Request{
  119. Header: make(map[string][]string),
  120. }
  121. req.Body = nil
  122. req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclPrivate)
  123. objectWriter := "accountA"
  124. grants, errCode := ExtractAcl(req, accountManager, s3_constants.OwnershipObjectWriter, accountAdminId, accountAdminId, objectWriter)
  125. testCases = append(testCases, &Case{
  126. 2,
  127. errCode, s3err.ErrNone,
  128. grants, []*s3.Grant{
  129. {
  130. Grantee: &s3.Grantee{
  131. Type: &s3_constants.GrantTypeCanonicalUser,
  132. ID: &objectWriter,
  133. },
  134. Permission: &s3_constants.PermissionFullControl,
  135. },
  136. },
  137. })
  138. }
  139. {
  140. //case3 (bad case)
  141. //parse acp from request body (content is invalid)
  142. req := &http.Request{
  143. Header: make(map[string][]string),
  144. }
  145. req.Body = io.NopCloser(bytes.NewReader([]byte("zdfsaf")))
  146. req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclPrivate)
  147. objectWriter := "accountA"
  148. _, errCode := ExtractAcl(req, accountManager, s3_constants.OwnershipObjectWriter, accountAdminId, accountAdminId, objectWriter)
  149. testCases = append(testCases, &Case{
  150. id: 3,
  151. resultErrCode: errCode, expectErrCode: s3err.ErrInvalidRequest,
  152. })
  153. }
  154. //case4 (bad case)
  155. //parse acp from header (cannedAcl is invalid)
  156. req := &http.Request{
  157. Header: make(map[string][]string),
  158. }
  159. req.Body = nil
  160. req.Header.Set(s3_constants.AmzCannedAcl, "dfaksjfk")
  161. objectWriter := "accountA"
  162. _, errCode := ExtractAcl(req, accountManager, s3_constants.OwnershipObjectWriter, accountAdminId, "", objectWriter)
  163. testCases = append(testCases, &Case{
  164. id: 4,
  165. resultErrCode: errCode, expectErrCode: s3err.ErrInvalidRequest,
  166. })
  167. {
  168. //case5 (bad case)
  169. //parse acp from request body: owner is inconsistent
  170. req.Body = io.NopCloser(bytes.NewReader([]byte(`
  171. <AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  172. <Owner>
  173. <ID>admin</ID>
  174. <DisplayName>admin</DisplayName>
  175. </Owner>
  176. <AccessControlList>
  177. <Grant>
  178. <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
  179. <ID>admin</ID>
  180. </Grantee>
  181. <Permission>FULL_CONTROL</Permission>
  182. </Grant>
  183. <Grant>
  184. <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
  185. <URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
  186. </Grantee>
  187. <Permission>FULL_CONTROL</Permission>
  188. </Grant>
  189. </AccessControlList>
  190. </AccessControlPolicy>
  191. `)))
  192. objectWriter = "accountA"
  193. _, errCode := ExtractAcl(req, accountManager, s3_constants.OwnershipObjectWriter, accountAdminId, objectWriter, objectWriter)
  194. testCases = append(testCases, &Case{
  195. id: 5,
  196. resultErrCode: errCode, expectErrCode: s3err.ErrAccessDenied,
  197. })
  198. }
  199. for _, tc := range testCases {
  200. if tc.resultErrCode != tc.expectErrCode {
  201. t.Fatalf("case[%d]: errorCode not expect", tc.id)
  202. }
  203. if !grantsEquals(tc.resultGrants, tc.expectGrants) {
  204. t.Fatalf("case[%d]: grants not expect", tc.id)
  205. }
  206. }
  207. }
  208. func TestParseAndValidateAclHeaders(t *testing.T) {
  209. type Case struct {
  210. id int
  211. resultOwner, expectOwner string
  212. resultErrCode, expectErrCode s3err.ErrorCode
  213. resultGrants, expectGrants []*s3.Grant
  214. }
  215. testCases := make([]*Case, 0)
  216. bucketOwner := "admin"
  217. {
  218. //case1 (good case)
  219. //parse custom acl
  220. req := &http.Request{
  221. Header: make(map[string][]string),
  222. }
  223. objectWriter := "accountA"
  224. req.Header.Set(s3_constants.AmzAclFullControl, `uri="http://acs.amazonaws.com/groups/global/AllUsers", id="anonymous", emailAddress="admin@example.com"`)
  225. ownerId, grants, errCode := ParseAndValidateAclHeaders(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwner, objectWriter, false)
  226. testCases = append(testCases, &Case{
  227. 1,
  228. ownerId, objectWriter,
  229. errCode, s3err.ErrNone,
  230. grants, []*s3.Grant{
  231. {
  232. Grantee: &s3.Grantee{
  233. Type: &s3_constants.GrantTypeGroup,
  234. URI: &s3_constants.GranteeGroupAllUsers,
  235. },
  236. Permission: &s3_constants.PermissionFullControl,
  237. },
  238. {
  239. Grantee: &s3.Grantee{
  240. Type: &s3_constants.GrantTypeCanonicalUser,
  241. ID: aws.String(s3_constants.AccountAnonymousId),
  242. },
  243. Permission: &s3_constants.PermissionFullControl,
  244. },
  245. {
  246. Grantee: &s3.Grantee{
  247. Type: &s3_constants.GrantTypeCanonicalUser,
  248. ID: aws.String(s3_constants.AccountAdminId),
  249. },
  250. Permission: &s3_constants.PermissionFullControl,
  251. },
  252. },
  253. })
  254. }
  255. {
  256. //case2 (good case)
  257. //parse canned acl (ownership=ObjectWriter)
  258. req := &http.Request{
  259. Header: make(map[string][]string),
  260. }
  261. objectWriter := "accountA"
  262. req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl)
  263. ownerId, grants, errCode := ParseAndValidateAclHeaders(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwner, objectWriter, false)
  264. testCases = append(testCases, &Case{
  265. 2,
  266. ownerId, objectWriter,
  267. errCode, s3err.ErrNone,
  268. grants, []*s3.Grant{
  269. {
  270. Grantee: &s3.Grantee{
  271. Type: &s3_constants.GrantTypeCanonicalUser,
  272. ID: &objectWriter,
  273. },
  274. Permission: &s3_constants.PermissionFullControl,
  275. },
  276. {
  277. Grantee: &s3.Grantee{
  278. Type: &s3_constants.GrantTypeCanonicalUser,
  279. ID: &bucketOwner,
  280. },
  281. Permission: &s3_constants.PermissionFullControl,
  282. },
  283. },
  284. })
  285. }
  286. {
  287. //case3 (good case)
  288. //parse canned acl (ownership=OwnershipBucketOwnerPreferred)
  289. req := &http.Request{
  290. Header: make(map[string][]string),
  291. }
  292. objectWriter := "accountA"
  293. req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl)
  294. ownerId, grants, errCode := ParseAndValidateAclHeaders(req, accountManager, s3_constants.OwnershipBucketOwnerPreferred, bucketOwner, objectWriter, false)
  295. testCases = append(testCases, &Case{
  296. 3,
  297. ownerId, bucketOwner,
  298. errCode, s3err.ErrNone,
  299. grants, []*s3.Grant{
  300. {
  301. Grantee: &s3.Grantee{
  302. Type: &s3_constants.GrantTypeCanonicalUser,
  303. ID: &bucketOwner,
  304. },
  305. Permission: &s3_constants.PermissionFullControl,
  306. },
  307. },
  308. })
  309. }
  310. {
  311. //case4 (bad case)
  312. //parse custom acl (grantee id not exists)
  313. req := &http.Request{
  314. Header: make(map[string][]string),
  315. }
  316. objectWriter := "accountA"
  317. req.Header.Set(s3_constants.AmzAclFullControl, `uri="http://acs.amazonaws.com/groups/global/AllUsers", id="notExistsAccount", emailAddress="admin@example.com"`)
  318. _, _, errCode := ParseAndValidateAclHeaders(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwner, objectWriter, false)
  319. testCases = append(testCases, &Case{
  320. id: 4,
  321. resultErrCode: errCode, expectErrCode: s3err.ErrInvalidRequest,
  322. })
  323. }
  324. {
  325. //case5 (bad case)
  326. //parse custom acl (invalid format)
  327. req := &http.Request{
  328. Header: make(map[string][]string),
  329. }
  330. objectWriter := "accountA"
  331. req.Header.Set(s3_constants.AmzAclFullControl, `uri="http:sfasf"`)
  332. _, _, errCode := ParseAndValidateAclHeaders(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwner, objectWriter, false)
  333. testCases = append(testCases, &Case{
  334. id: 5,
  335. resultErrCode: errCode, expectErrCode: s3err.ErrInvalidRequest,
  336. })
  337. }
  338. {
  339. //case6 (bad case)
  340. //parse canned acl (invalid value)
  341. req := &http.Request{
  342. Header: make(map[string][]string),
  343. }
  344. objectWriter := "accountA"
  345. req.Header.Set(s3_constants.AmzCannedAcl, `uri="http:sfasf"`)
  346. _, _, errCode := ParseAndValidateAclHeaders(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwner, objectWriter, false)
  347. testCases = append(testCases, &Case{
  348. id: 5,
  349. resultErrCode: errCode, expectErrCode: s3err.ErrInvalidRequest,
  350. })
  351. }
  352. for _, tc := range testCases {
  353. if tc.expectErrCode != tc.resultErrCode {
  354. t.Errorf("case[%d]: errCode unexpect", tc.id)
  355. }
  356. if tc.resultOwner != tc.expectOwner {
  357. t.Errorf("case[%d]: ownerId unexpect", tc.id)
  358. }
  359. if !grantsEquals(tc.resultGrants, tc.expectGrants) {
  360. t.Fatalf("case[%d]: grants not expect", tc.id)
  361. }
  362. }
  363. }
  364. func grantsEquals(a, b []*s3.Grant) bool {
  365. if len(a) != len(b) {
  366. return false
  367. }
  368. for i, grant := range a {
  369. if !GrantEquals(grant, b[i]) {
  370. return false
  371. }
  372. }
  373. return true
  374. }
  375. func TestDetermineReqGrants(t *testing.T) {
  376. {
  377. //case1: request account is anonymous
  378. accountId := s3_constants.AccountAnonymousId
  379. reqPermission := s3_constants.PermissionRead
  380. resultGrants := DetermineRequiredGrants(accountId, reqPermission)
  381. expectGrants := []*s3.Grant{
  382. {
  383. Grantee: &s3.Grantee{
  384. Type: &s3_constants.GrantTypeGroup,
  385. URI: &s3_constants.GranteeGroupAllUsers,
  386. },
  387. Permission: &reqPermission,
  388. },
  389. {
  390. Grantee: &s3.Grantee{
  391. Type: &s3_constants.GrantTypeGroup,
  392. URI: &s3_constants.GranteeGroupAllUsers,
  393. },
  394. Permission: &s3_constants.PermissionFullControl,
  395. },
  396. {
  397. Grantee: &s3.Grantee{
  398. Type: &s3_constants.GrantTypeCanonicalUser,
  399. ID: &accountId,
  400. },
  401. Permission: &reqPermission,
  402. },
  403. {
  404. Grantee: &s3.Grantee{
  405. Type: &s3_constants.GrantTypeCanonicalUser,
  406. ID: &accountId,
  407. },
  408. Permission: &s3_constants.PermissionFullControl,
  409. },
  410. }
  411. if !grantsEquals(resultGrants, expectGrants) {
  412. t.Fatalf("grants not expect")
  413. }
  414. }
  415. {
  416. //case2: request account is not anonymous (Iam authed)
  417. accountId := "accountX"
  418. reqPermission := s3_constants.PermissionRead
  419. resultGrants := DetermineRequiredGrants(accountId, reqPermission)
  420. expectGrants := []*s3.Grant{
  421. {
  422. Grantee: &s3.Grantee{
  423. Type: &s3_constants.GrantTypeGroup,
  424. URI: &s3_constants.GranteeGroupAllUsers,
  425. },
  426. Permission: &reqPermission,
  427. },
  428. {
  429. Grantee: &s3.Grantee{
  430. Type: &s3_constants.GrantTypeGroup,
  431. URI: &s3_constants.GranteeGroupAllUsers,
  432. },
  433. Permission: &s3_constants.PermissionFullControl,
  434. },
  435. {
  436. Grantee: &s3.Grantee{
  437. Type: &s3_constants.GrantTypeCanonicalUser,
  438. ID: &accountId,
  439. },
  440. Permission: &reqPermission,
  441. },
  442. {
  443. Grantee: &s3.Grantee{
  444. Type: &s3_constants.GrantTypeCanonicalUser,
  445. ID: &accountId,
  446. },
  447. Permission: &s3_constants.PermissionFullControl,
  448. },
  449. {
  450. Grantee: &s3.Grantee{
  451. Type: &s3_constants.GrantTypeGroup,
  452. URI: &s3_constants.GranteeGroupAuthenticatedUsers,
  453. },
  454. Permission: &reqPermission,
  455. },
  456. {
  457. Grantee: &s3.Grantee{
  458. Type: &s3_constants.GrantTypeGroup,
  459. URI: &s3_constants.GranteeGroupAuthenticatedUsers,
  460. },
  461. Permission: &s3_constants.PermissionFullControl,
  462. },
  463. }
  464. if !grantsEquals(resultGrants, expectGrants) {
  465. t.Fatalf("grants not expect")
  466. }
  467. }
  468. }
  469. func TestAssembleEntryWithAcp(t *testing.T) {
  470. defaultOwner := "admin"
  471. //case1
  472. //assemble with non-empty grants
  473. expectOwner := "accountS"
  474. expectGrants := []*s3.Grant{
  475. {
  476. Permission: &s3_constants.PermissionRead,
  477. Grantee: &s3.Grantee{
  478. Type: &s3_constants.GrantTypeGroup,
  479. ID: aws.String(s3_constants.AccountAdminId),
  480. URI: &s3_constants.GranteeGroupAllUsers,
  481. },
  482. },
  483. }
  484. entry := &filer_pb.Entry{}
  485. AssembleEntryWithAcp(entry, expectOwner, expectGrants)
  486. resultOwner := GetAcpOwner(entry.Extended, defaultOwner)
  487. if resultOwner != expectOwner {
  488. t.Fatalf("owner not expect")
  489. }
  490. resultGrants := GetAcpGrants(nil, entry.Extended)
  491. if !grantsEquals(resultGrants, expectGrants) {
  492. t.Fatal("grants not expect")
  493. }
  494. //case2
  495. //assemble with empty grants (override)
  496. AssembleEntryWithAcp(entry, "", nil)
  497. resultOwner = GetAcpOwner(entry.Extended, defaultOwner)
  498. if resultOwner != defaultOwner {
  499. t.Fatalf("owner not expect")
  500. }
  501. resultGrants = GetAcpGrants(nil, entry.Extended)
  502. if len(resultGrants) != 0 {
  503. t.Fatal("grants not expect")
  504. }
  505. }
  506. func TestGrantEquals(t *testing.T) {
  507. testCases := map[bool]bool{
  508. GrantEquals(nil, nil): true,
  509. GrantEquals(&s3.Grant{}, nil): false,
  510. GrantEquals(&s3.Grant{}, &s3.Grant{}): true,
  511. GrantEquals(&s3.Grant{
  512. Permission: &s3_constants.PermissionRead,
  513. }, &s3.Grant{}): false,
  514. GrantEquals(&s3.Grant{
  515. Permission: &s3_constants.PermissionRead,
  516. }, &s3.Grant{
  517. Permission: &s3_constants.PermissionRead,
  518. }): true,
  519. GrantEquals(&s3.Grant{
  520. Permission: &s3_constants.PermissionRead,
  521. Grantee: &s3.Grantee{},
  522. }, &s3.Grant{
  523. Permission: &s3_constants.PermissionRead,
  524. Grantee: &s3.Grantee{},
  525. }): true,
  526. GrantEquals(&s3.Grant{
  527. Permission: &s3_constants.PermissionRead,
  528. Grantee: &s3.Grantee{
  529. Type: &s3_constants.GrantTypeGroup,
  530. },
  531. }, &s3.Grant{
  532. Permission: &s3_constants.PermissionRead,
  533. Grantee: &s3.Grantee{},
  534. }): false,
  535. //type not present, compare other fields of grant is meaningless
  536. GrantEquals(&s3.Grant{
  537. Permission: &s3_constants.PermissionRead,
  538. Grantee: &s3.Grantee{
  539. ID: aws.String(s3_constants.AccountAdminId),
  540. //EmailAddress: &s3account.AccountAdmin.EmailAddress,
  541. },
  542. }, &s3.Grant{
  543. Permission: &s3_constants.PermissionRead,
  544. Grantee: &s3.Grantee{
  545. ID: aws.String(s3_constants.AccountAdminId),
  546. },
  547. }): true,
  548. GrantEquals(&s3.Grant{
  549. Permission: &s3_constants.PermissionRead,
  550. Grantee: &s3.Grantee{
  551. Type: &s3_constants.GrantTypeGroup,
  552. },
  553. }, &s3.Grant{
  554. Permission: &s3_constants.PermissionRead,
  555. Grantee: &s3.Grantee{
  556. Type: &s3_constants.GrantTypeGroup,
  557. },
  558. }): true,
  559. GrantEquals(&s3.Grant{
  560. Permission: &s3_constants.PermissionRead,
  561. Grantee: &s3.Grantee{
  562. Type: &s3_constants.GrantTypeGroup,
  563. URI: &s3_constants.GranteeGroupAllUsers,
  564. },
  565. }, &s3.Grant{
  566. Permission: &s3_constants.PermissionRead,
  567. Grantee: &s3.Grantee{
  568. Type: &s3_constants.GrantTypeGroup,
  569. URI: &s3_constants.GranteeGroupAllUsers,
  570. },
  571. }): true,
  572. GrantEquals(&s3.Grant{
  573. Permission: &s3_constants.PermissionWrite,
  574. Grantee: &s3.Grantee{
  575. Type: &s3_constants.GrantTypeGroup,
  576. URI: &s3_constants.GranteeGroupAllUsers,
  577. },
  578. }, &s3.Grant{
  579. Permission: &s3_constants.PermissionRead,
  580. Grantee: &s3.Grantee{
  581. Type: &s3_constants.GrantTypeGroup,
  582. URI: &s3_constants.GranteeGroupAllUsers,
  583. },
  584. }): false,
  585. GrantEquals(&s3.Grant{
  586. Permission: &s3_constants.PermissionRead,
  587. Grantee: &s3.Grantee{
  588. Type: &s3_constants.GrantTypeGroup,
  589. ID: aws.String(s3_constants.AccountAdminId),
  590. },
  591. }, &s3.Grant{
  592. Permission: &s3_constants.PermissionRead,
  593. Grantee: &s3.Grantee{
  594. Type: &s3_constants.GrantTypeGroup,
  595. ID: aws.String(s3_constants.AccountAdminId),
  596. },
  597. }): true,
  598. GrantEquals(&s3.Grant{
  599. Permission: &s3_constants.PermissionRead,
  600. Grantee: &s3.Grantee{
  601. Type: &s3_constants.GrantTypeGroup,
  602. ID: aws.String(s3_constants.AccountAdminId),
  603. URI: &s3_constants.GranteeGroupAllUsers,
  604. },
  605. }, &s3.Grant{
  606. Permission: &s3_constants.PermissionRead,
  607. Grantee: &s3.Grantee{
  608. Type: &s3_constants.GrantTypeGroup,
  609. ID: aws.String(s3_constants.AccountAdminId),
  610. },
  611. }): false,
  612. GrantEquals(&s3.Grant{
  613. Permission: &s3_constants.PermissionRead,
  614. Grantee: &s3.Grantee{
  615. Type: &s3_constants.GrantTypeGroup,
  616. ID: aws.String(s3_constants.AccountAdminId),
  617. URI: &s3_constants.GranteeGroupAllUsers,
  618. },
  619. }, &s3.Grant{
  620. Permission: &s3_constants.PermissionRead,
  621. Grantee: &s3.Grantee{
  622. Type: &s3_constants.GrantTypeGroup,
  623. URI: &s3_constants.GranteeGroupAllUsers,
  624. },
  625. }): true,
  626. }
  627. for tc, expect := range testCases {
  628. if tc != expect {
  629. t.Fatal("TestGrantEquals not expect!")
  630. }
  631. }
  632. }
  633. func TestSetAcpOwnerHeader(t *testing.T) {
  634. ownerId := "accountZ"
  635. req := &http.Request{
  636. Header: make(map[string][]string),
  637. }
  638. SetAcpOwnerHeader(req, ownerId)
  639. if req.Header.Get(s3_constants.ExtAmzOwnerKey) != ownerId {
  640. t.Fatalf("owner unexpect")
  641. }
  642. }
  643. func TestSetAcpGrantsHeader(t *testing.T) {
  644. req := &http.Request{
  645. Header: make(map[string][]string),
  646. }
  647. grants := []*s3.Grant{
  648. {
  649. Permission: &s3_constants.PermissionRead,
  650. Grantee: &s3.Grantee{
  651. Type: &s3_constants.GrantTypeGroup,
  652. ID: aws.String(s3_constants.AccountAdminId),
  653. URI: &s3_constants.GranteeGroupAllUsers,
  654. },
  655. },
  656. }
  657. SetAcpGrantsHeader(req, grants)
  658. grantsJson, _ := json.Marshal(grants)
  659. if req.Header.Get(s3_constants.ExtAmzAclKey) != string(grantsJson) {
  660. t.Fatalf("owner unexpect")
  661. }
  662. }
  663. func TestGrantWithFullControl(t *testing.T) {
  664. accountId := "Accountaskdfj"
  665. expect := &s3.Grant{
  666. Permission: &s3_constants.PermissionFullControl,
  667. Grantee: &s3.Grantee{
  668. Type: &s3_constants.GrantTypeCanonicalUser,
  669. ID: &accountId,
  670. },
  671. }
  672. result := GrantWithFullControl(accountId)
  673. if !GrantEquals(result, expect) {
  674. t.Fatal("GrantWithFullControl not expect")
  675. }
  676. }
  677. func TestExtractObjectAcl(t *testing.T) {
  678. type Case struct {
  679. id string
  680. resultErrCode, expectErrCode s3err.ErrorCode
  681. resultGrants, expectGrants []*s3.Grant
  682. resultOwnerId, expectOwnerId string
  683. }
  684. testCases := make([]*Case, 0)
  685. accountAdminId := "admin"
  686. //Request body to specify AccessControlList
  687. {
  688. //ownership: ObjectWriter
  689. //s3:PutObjectAcl('createObject' is set to false), config acl through request body
  690. req := &http.Request{
  691. Header: make(map[string][]string),
  692. }
  693. req.Body = io.NopCloser(bytes.NewReader([]byte(`
  694. <AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  695. <Owner>
  696. <ID>admin</ID>
  697. <DisplayName>admin</DisplayName>
  698. </Owner>
  699. <AccessControlList>
  700. <Grant>
  701. <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
  702. <ID>admin</ID>
  703. </Grantee>
  704. <Permission>FULL_CONTROL</Permission>
  705. </Grant>
  706. <Grant>
  707. <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
  708. <URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
  709. </Grantee>
  710. <Permission>FULL_CONTROL</Permission>
  711. </Grant>
  712. </AccessControlList>
  713. </AccessControlPolicy>
  714. `)))
  715. requestAccountId := "accountA"
  716. ownerId, grants, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipObjectWriter, accountAdminId, requestAccountId, false)
  717. testCases = append(testCases, &Case{
  718. "TestExtractObjectAcl: ownership-ObjectWriter, createObject-false, acl-requestBody",
  719. errCode, s3err.ErrNone,
  720. grants, []*s3.Grant{
  721. {
  722. Grantee: &s3.Grantee{
  723. Type: &s3_constants.GrantTypeCanonicalUser,
  724. ID: &accountAdminId,
  725. },
  726. Permission: &s3_constants.PermissionFullControl,
  727. },
  728. {
  729. Grantee: &s3.Grantee{
  730. Type: &s3_constants.GrantTypeGroup,
  731. URI: &s3_constants.GranteeGroupAllUsers,
  732. },
  733. Permission: &s3_constants.PermissionFullControl,
  734. },
  735. },
  736. ownerId, accountAdminId,
  737. })
  738. }
  739. {
  740. //ownership: BucketOwnerEnforced (extra acl is not allowed)
  741. //s3:PutObjectAcl('createObject' is set to false), config acl through request body
  742. req := &http.Request{
  743. Header: make(map[string][]string),
  744. }
  745. req.Body = io.NopCloser(bytes.NewReader([]byte(`
  746. <AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  747. <Owner>
  748. <ID>admin</ID>
  749. <DisplayName>admin</DisplayName>
  750. </Owner>
  751. <AccessControlList>
  752. <Grant>
  753. <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
  754. <ID>admin</ID>
  755. </Grantee>
  756. <Permission>FULL_CONTROL</Permission>
  757. </Grant>
  758. <Grant>
  759. <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
  760. <URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
  761. </Grantee>
  762. <Permission>FULL_CONTROL</Permission>
  763. </Grant>
  764. </AccessControlList>
  765. </AccessControlPolicy>
  766. `)))
  767. requestAccountId := "accountA"
  768. _, _, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipBucketOwnerEnforced, accountAdminId, requestAccountId, false)
  769. testCases = append(testCases, &Case{
  770. id: "TestExtractObjectAcl: ownership-BucketOwnerEnforced, createObject-false, acl-requestBody",
  771. resultErrCode: errCode, expectErrCode: s3err.AccessControlListNotSupported,
  772. })
  773. }
  774. {
  775. //ownership: ObjectWriter
  776. //s3:PutObject('createObject' is set to false), request body will be ignored when parse acl
  777. req := &http.Request{
  778. Header: make(map[string][]string),
  779. }
  780. req.Body = io.NopCloser(bytes.NewReader([]byte(`
  781. <AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  782. <Owner>
  783. <ID>admin</ID>
  784. <DisplayName>admin</DisplayName>
  785. </Owner>
  786. <AccessControlList>
  787. <Grant>
  788. <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
  789. <ID>admin</ID>
  790. </Grantee>
  791. <Permission>FULL_CONTROL</Permission>
  792. </Grant>
  793. <Grant>
  794. <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
  795. <URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
  796. </Grantee>
  797. <Permission>FULL_CONTROL</Permission>
  798. </Grant>
  799. </AccessControlList>
  800. </AccessControlPolicy>
  801. `)))
  802. requestAccountId := "accountA"
  803. ownerId, grants, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipObjectWriter, accountAdminId, requestAccountId, true)
  804. testCases = append(testCases, &Case{
  805. "TestExtractObjectAcl: ownership-ObjectWriter, createObject-true, acl-requestBody",
  806. errCode, s3err.ErrNone,
  807. grants, []*s3.Grant{},
  808. ownerId, "",
  809. })
  810. }
  811. {
  812. //ownership: BucketOwnerEnforced (extra acl is not allowed)
  813. //s3:PutObject('createObject' is set to true), request body will be ignored when parse acl
  814. req := &http.Request{
  815. Header: make(map[string][]string),
  816. }
  817. req.Body = io.NopCloser(bytes.NewReader([]byte(`
  818. <AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  819. <Owner>
  820. <ID>admin</ID>
  821. <DisplayName>admin</DisplayName>
  822. </Owner>
  823. <AccessControlList>
  824. <Grant>
  825. <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
  826. <ID>admin</ID>
  827. </Grantee>
  828. <Permission>FULL_CONTROL</Permission>
  829. </Grant>
  830. <Grant>
  831. <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
  832. <URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
  833. </Grantee>
  834. <Permission>FULL_CONTROL</Permission>
  835. </Grant>
  836. </AccessControlList>
  837. </AccessControlPolicy>
  838. `)))
  839. requestAccountId := "accountA"
  840. ownerId, grants, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipBucketOwnerEnforced, accountAdminId, requestAccountId, true)
  841. testCases = append(testCases, &Case{
  842. "TestExtractObjectAcl: ownership-BucketOwnerEnforced, createObject-true, acl-requestBody",
  843. errCode, s3err.ErrNone,
  844. grants, []*s3.Grant{},
  845. ownerId, "",
  846. })
  847. }
  848. //CannedAcl Header to specify ACL
  849. //cannedAcl, putObjectACL
  850. {
  851. //ownership: ObjectWriter
  852. //s3:PutObjectACL('createObject' is set to false), parse cannedACL header
  853. req := &http.Request{
  854. Header: make(map[string][]string),
  855. }
  856. req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl)
  857. bucketOwnerId := "admin"
  858. requestAccountId := "accountA"
  859. ownerId, grants, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwnerId, requestAccountId, false)
  860. testCases = append(testCases, &Case{
  861. "TestExtractObjectAcl: ownership-ObjectWriter, createObject-false, acl-CannedAcl",
  862. errCode, s3err.ErrNone,
  863. grants, []*s3.Grant{
  864. {
  865. Grantee: &s3.Grantee{
  866. Type: &s3_constants.GrantTypeCanonicalUser,
  867. ID: &requestAccountId,
  868. },
  869. Permission: &s3_constants.PermissionFullControl,
  870. },
  871. {
  872. Grantee: &s3.Grantee{
  873. Type: &s3_constants.GrantTypeCanonicalUser,
  874. ID: &bucketOwnerId,
  875. },
  876. Permission: &s3_constants.PermissionFullControl,
  877. },
  878. },
  879. ownerId, "",
  880. })
  881. }
  882. {
  883. //ownership: BucketOwnerPreferred
  884. //s3:PutObjectACL('createObject' is set to false), parse cannedACL header
  885. req := &http.Request{
  886. Header: make(map[string][]string),
  887. }
  888. req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl)
  889. bucketOwnerId := "admin"
  890. requestAccountId := "accountA"
  891. ownerId, grants, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipBucketOwnerPreferred, bucketOwnerId, requestAccountId, false)
  892. testCases = append(testCases, &Case{
  893. "TestExtractObjectAcl: ownership-BucketOwnerPreferred, createObject-false, acl-CannedAcl",
  894. errCode, s3err.ErrNone,
  895. grants, []*s3.Grant{
  896. {
  897. Grantee: &s3.Grantee{
  898. Type: &s3_constants.GrantTypeCanonicalUser,
  899. ID: &requestAccountId,
  900. },
  901. Permission: &s3_constants.PermissionFullControl,
  902. },
  903. {
  904. Grantee: &s3.Grantee{
  905. Type: &s3_constants.GrantTypeCanonicalUser,
  906. ID: &bucketOwnerId,
  907. },
  908. Permission: &s3_constants.PermissionFullControl,
  909. },
  910. },
  911. ownerId, "",
  912. })
  913. }
  914. {
  915. //ownership: BucketOwnerEnforced
  916. //s3:PutObjectACL('createObject' is set to false), parse cannedACL header
  917. req := &http.Request{
  918. Header: make(map[string][]string),
  919. }
  920. req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl)
  921. bucketOwnerId := "admin"
  922. requestAccountId := "accountA"
  923. _, _, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipBucketOwnerEnforced, bucketOwnerId, requestAccountId, false)
  924. testCases = append(testCases, &Case{
  925. id: "TestExtractObjectAcl: ownership-BucketOwnerEnforced, createObject-false, acl-CannedAcl",
  926. resultErrCode: errCode, expectErrCode: s3err.AccessControlListNotSupported,
  927. })
  928. }
  929. //cannedACL, putObject
  930. {
  931. //ownership: ObjectWriter
  932. //s3:PutObject('createObject' is set to true), parse cannedACL header
  933. req := &http.Request{
  934. Header: make(map[string][]string),
  935. }
  936. req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl)
  937. bucketOwnerId := "admin"
  938. requestAccountId := "accountA"
  939. ownerId, grants, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwnerId, requestAccountId, true)
  940. testCases = append(testCases, &Case{
  941. "TestExtractObjectAcl: ownership-ObjectWriter, createObject-true, acl-CannedAcl",
  942. errCode, s3err.ErrNone,
  943. grants, []*s3.Grant{
  944. {
  945. Grantee: &s3.Grantee{
  946. Type: &s3_constants.GrantTypeCanonicalUser,
  947. ID: &requestAccountId,
  948. },
  949. Permission: &s3_constants.PermissionFullControl,
  950. },
  951. {
  952. Grantee: &s3.Grantee{
  953. Type: &s3_constants.GrantTypeCanonicalUser,
  954. ID: &bucketOwnerId,
  955. },
  956. Permission: &s3_constants.PermissionFullControl,
  957. },
  958. },
  959. ownerId, "",
  960. })
  961. }
  962. {
  963. //ownership: BucketOwnerPreferred
  964. //s3:PutObject('createObject' is set to true), parse cannedACL header
  965. req := &http.Request{
  966. Header: make(map[string][]string),
  967. }
  968. req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl)
  969. bucketOwnerId := "admin"
  970. requestAccountId := "accountA"
  971. ownerId, grants, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipBucketOwnerPreferred, bucketOwnerId, requestAccountId, true)
  972. testCases = append(testCases, &Case{
  973. "TestExtractObjectAcl: ownership-BucketOwnerPreferred, createObject-true, acl-CannedAcl",
  974. errCode, s3err.ErrNone,
  975. grants, []*s3.Grant{
  976. {
  977. Grantee: &s3.Grantee{
  978. Type: &s3_constants.GrantTypeCanonicalUser,
  979. ID: &bucketOwnerId,
  980. },
  981. Permission: &s3_constants.PermissionFullControl,
  982. },
  983. },
  984. ownerId, "",
  985. })
  986. }
  987. {
  988. //ownership: BucketOwnerEnforced
  989. //s3:PutObject('createObject' is set to true), parse cannedACL header
  990. req := &http.Request{
  991. Header: make(map[string][]string),
  992. }
  993. req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl)
  994. bucketOwnerId := "admin"
  995. requestAccountId := "accountA"
  996. _, _, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipBucketOwnerEnforced, bucketOwnerId, requestAccountId, true)
  997. testCases = append(testCases, &Case{
  998. id: "TestExtractObjectAcl: ownership-BucketOwnerEnforced, createObject-true, acl-CannedAcl",
  999. resultErrCode: errCode, expectErrCode: s3err.AccessControlListNotSupported,
  1000. })
  1001. }
  1002. //cannedAcl, putObjectACL
  1003. {
  1004. //ownership: ObjectWriter
  1005. //s3:PutObjectACL('createObject' is set to false), parse customAcl header
  1006. req := &http.Request{
  1007. Header: make(map[string][]string),
  1008. }
  1009. req.Header.Set(s3_constants.AmzAclFullControl, "id=accountA,id=\"admin\"")
  1010. bucketOwnerId := "admin"
  1011. requestAccountId := "accountA"
  1012. ownerId, grants, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwnerId, requestAccountId, false)
  1013. testCases = append(testCases, &Case{
  1014. "TestExtractObjectAcl: ownership-ObjectWriter, createObject-false, acl-customAcl",
  1015. errCode, s3err.ErrNone,
  1016. grants, []*s3.Grant{
  1017. {
  1018. Grantee: &s3.Grantee{
  1019. Type: &s3_constants.GrantTypeCanonicalUser,
  1020. ID: &requestAccountId,
  1021. },
  1022. Permission: &s3_constants.PermissionFullControl,
  1023. },
  1024. {
  1025. Grantee: &s3.Grantee{
  1026. Type: &s3_constants.GrantTypeCanonicalUser,
  1027. ID: &bucketOwnerId,
  1028. },
  1029. Permission: &s3_constants.PermissionFullControl,
  1030. },
  1031. },
  1032. ownerId, "",
  1033. })
  1034. }
  1035. {
  1036. //ownership: BucketOwnerPreferred
  1037. //s3:PutObjectACL('createObject' is set to false), parse customAcl header
  1038. req := &http.Request{
  1039. Header: make(map[string][]string),
  1040. }
  1041. req.Header.Set(s3_constants.AmzAclFullControl, "id=accountA,id=\"admin\"")
  1042. bucketOwnerId := "admin"
  1043. requestAccountId := "accountA"
  1044. ownerId, grants, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipBucketOwnerPreferred, bucketOwnerId, requestAccountId, false)
  1045. testCases = append(testCases, &Case{
  1046. "TestExtractObjectAcl: ownership-BucketOwnerPreferred, createObject-false, acl-customAcl",
  1047. errCode, s3err.ErrNone,
  1048. grants, []*s3.Grant{
  1049. {
  1050. Grantee: &s3.Grantee{
  1051. Type: &s3_constants.GrantTypeCanonicalUser,
  1052. ID: &requestAccountId,
  1053. },
  1054. Permission: &s3_constants.PermissionFullControl,
  1055. },
  1056. {
  1057. Grantee: &s3.Grantee{
  1058. Type: &s3_constants.GrantTypeCanonicalUser,
  1059. ID: &bucketOwnerId,
  1060. },
  1061. Permission: &s3_constants.PermissionFullControl,
  1062. },
  1063. },
  1064. ownerId, "",
  1065. })
  1066. }
  1067. {
  1068. //ownership: BucketOwnerEnforced
  1069. //s3:PutObjectACL('createObject' is set to false), parse customAcl header
  1070. req := &http.Request{
  1071. Header: make(map[string][]string),
  1072. }
  1073. req.Header.Set(s3_constants.AmzAclFullControl, "id=accountA,id=\"admin\"")
  1074. bucketOwnerId := "admin"
  1075. requestAccountId := "accountA"
  1076. _, _, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipBucketOwnerEnforced, bucketOwnerId, requestAccountId, false)
  1077. testCases = append(testCases, &Case{
  1078. id: "TestExtractObjectAcl: ownership-BucketOwnerEnforced, createObject-false, acl-customAcl",
  1079. resultErrCode: errCode, expectErrCode: s3err.AccessControlListNotSupported,
  1080. })
  1081. }
  1082. //customAcl, putObject
  1083. {
  1084. //ownership: ObjectWriter
  1085. //s3:PutObject('createObject' is set to true), parse customAcl header
  1086. req := &http.Request{
  1087. Header: make(map[string][]string),
  1088. }
  1089. req.Header.Set(s3_constants.AmzAclFullControl, "id=accountA,id=\"admin\"")
  1090. bucketOwnerId := "admin"
  1091. requestAccountId := "accountA"
  1092. ownerId, grants, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwnerId, requestAccountId, true)
  1093. testCases = append(testCases, &Case{
  1094. "TestExtractObjectAcl: ownership-ObjectWriter, createObject-true, acl-customAcl",
  1095. errCode, s3err.ErrNone,
  1096. grants, []*s3.Grant{
  1097. {
  1098. Grantee: &s3.Grantee{
  1099. Type: &s3_constants.GrantTypeCanonicalUser,
  1100. ID: &requestAccountId,
  1101. },
  1102. Permission: &s3_constants.PermissionFullControl,
  1103. },
  1104. {
  1105. Grantee: &s3.Grantee{
  1106. Type: &s3_constants.GrantTypeCanonicalUser,
  1107. ID: &bucketOwnerId,
  1108. },
  1109. Permission: &s3_constants.PermissionFullControl,
  1110. },
  1111. },
  1112. ownerId, "",
  1113. })
  1114. }
  1115. {
  1116. //ownership: BucketOwnerPreferred
  1117. //s3:PutObject('createObject' is set to true), parse customAcl header
  1118. req := &http.Request{
  1119. Header: make(map[string][]string),
  1120. }
  1121. req.Header.Set(s3_constants.AmzAclFullControl, "id=\"admin\"")
  1122. bucketOwnerId := "admin"
  1123. requestAccountId := "accountA"
  1124. ownerId, grants, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipBucketOwnerPreferred, bucketOwnerId, requestAccountId, true)
  1125. testCases = append(testCases, &Case{
  1126. "TestExtractObjectAcl: ownership-BucketOwnerPreferred, createObject-true, acl-customAcl",
  1127. errCode, s3err.ErrNone,
  1128. grants, []*s3.Grant{
  1129. {
  1130. Grantee: &s3.Grantee{
  1131. Type: &s3_constants.GrantTypeCanonicalUser,
  1132. ID: &bucketOwnerId,
  1133. },
  1134. Permission: &s3_constants.PermissionFullControl,
  1135. },
  1136. },
  1137. ownerId, "",
  1138. })
  1139. }
  1140. {
  1141. //ownership: BucketOwnerEnforced
  1142. //s3:PutObject('createObject' is set to true), parse customAcl header
  1143. req := &http.Request{
  1144. Header: make(map[string][]string),
  1145. }
  1146. req.Header.Set(s3_constants.AmzAclFullControl, "id=accountA,id=\"admin\"")
  1147. bucketOwnerId := "admin"
  1148. requestAccountId := "accountA"
  1149. _, _, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipBucketOwnerEnforced, bucketOwnerId, requestAccountId, true)
  1150. testCases = append(testCases, &Case{
  1151. id: "TestExtractObjectAcl: ownership-BucketOwnerEnforced, createObject-true, acl-customAcl",
  1152. resultErrCode: errCode, expectErrCode: s3err.AccessControlListNotSupported,
  1153. })
  1154. }
  1155. {
  1156. //parse acp from request header: both canned acl and custom acl not allowed
  1157. req := &http.Request{
  1158. Header: make(map[string][]string),
  1159. }
  1160. req.Header.Set(s3_constants.AmzAclFullControl, "id=admin, id=\"accountA\"")
  1161. req.Header.Set(s3_constants.AmzCannedAcl, "private")
  1162. bucketOwnerId := "admin"
  1163. requestAccountId := "accountA"
  1164. _, _, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwnerId, requestAccountId, false)
  1165. testCases = append(testCases, &Case{
  1166. id: "Only one of cannedAcl, customAcl is allowed",
  1167. resultErrCode: errCode, expectErrCode: s3err.ErrInvalidRequest,
  1168. })
  1169. }
  1170. {
  1171. //Acl can only be specified in one of requestBody, cannedAcl, customAcl, simultaneous use is not allowed
  1172. req := &http.Request{
  1173. Header: make(map[string][]string),
  1174. }
  1175. req.Header.Set(s3_constants.AmzAclFullControl, "id=admin, id=\"accountA\"")
  1176. req.Header.Set(s3_constants.AmzCannedAcl, "private")
  1177. req.Body = io.NopCloser(bytes.NewReader([]byte(`
  1178. <AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  1179. <Owner>
  1180. <ID>admin</ID>
  1181. <DisplayName>admin</DisplayName>
  1182. </Owner>
  1183. <AccessControlList>
  1184. <Grant>
  1185. <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
  1186. <ID>admin</ID>
  1187. </Grantee>
  1188. <Permission>FULL_CONTROL</Permission>
  1189. </Grant>
  1190. <Grant>
  1191. <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
  1192. <URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
  1193. </Grantee>
  1194. <Permission>FULL_CONTROL</Permission>
  1195. </Grant>
  1196. </AccessControlList>
  1197. </AccessControlPolicy>
  1198. `)))
  1199. requestAccountId := "accountA"
  1200. _, _, errCode := ExtractObjectAcl(req, accountManager, s3_constants.OwnershipObjectWriter, accountAdminId, requestAccountId, false)
  1201. testCases = append(testCases, &Case{
  1202. id: "Only one of requestBody, cannedAcl, customAcl is allowed",
  1203. resultErrCode: errCode, expectErrCode: s3err.ErrUnexpectedContent,
  1204. })
  1205. }
  1206. for _, tc := range testCases {
  1207. if tc.resultErrCode != tc.expectErrCode {
  1208. t.Fatalf("case[%s]: errorCode[%v] not expect[%v]", tc.id, s3err.GetAPIError(tc.resultErrCode).Code, s3err.GetAPIError(tc.expectErrCode).Code)
  1209. }
  1210. if !grantsEquals(tc.resultGrants, tc.expectGrants) {
  1211. t.Fatalf("case[%s]: grants not expect", tc.id)
  1212. }
  1213. }
  1214. }
  1215. func TestBucketObjectAcl(t *testing.T) {
  1216. type Case struct {
  1217. id string
  1218. resultErrCode, expectErrCode s3err.ErrorCode
  1219. resultGrants, expectGrants []*s3.Grant
  1220. }
  1221. testCases := make([]*Case, 0)
  1222. accountAdminId := "admin"
  1223. //Request body to specify AccessControlList
  1224. {
  1225. //ownership: ObjectWriter
  1226. //s3:PutBucketAcl('createObject' is set to false), config acl through request body
  1227. req := &http.Request{
  1228. Header: make(map[string][]string),
  1229. }
  1230. req.Body = io.NopCloser(bytes.NewReader([]byte(`
  1231. <AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  1232. <Owner>
  1233. <ID>admin</ID>
  1234. <DisplayName>admin</DisplayName>
  1235. </Owner>
  1236. <AccessControlList>
  1237. <Grant>
  1238. <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
  1239. <ID>admin</ID>
  1240. </Grantee>
  1241. <Permission>FULL_CONTROL</Permission>
  1242. </Grant>
  1243. <Grant>
  1244. <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
  1245. <URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
  1246. </Grantee>
  1247. <Permission>FULL_CONTROL</Permission>
  1248. </Grant>
  1249. </AccessControlList>
  1250. </AccessControlPolicy>
  1251. `)))
  1252. bucketOwnerId := "admin"
  1253. requestAccountId := "accountA"
  1254. grants, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwnerId, requestAccountId, false)
  1255. testCases = append(testCases, &Case{
  1256. "TestExtractBucketAcl: ownership-ObjectWriter, createObject-false, acl-requestBody",
  1257. errCode, s3err.ErrNone,
  1258. grants, []*s3.Grant{
  1259. {
  1260. Grantee: &s3.Grantee{
  1261. Type: &s3_constants.GrantTypeCanonicalUser,
  1262. ID: &accountAdminId,
  1263. },
  1264. Permission: &s3_constants.PermissionFullControl,
  1265. },
  1266. {
  1267. Grantee: &s3.Grantee{
  1268. Type: &s3_constants.GrantTypeGroup,
  1269. URI: &s3_constants.GranteeGroupAllUsers,
  1270. },
  1271. Permission: &s3_constants.PermissionFullControl,
  1272. },
  1273. },
  1274. })
  1275. }
  1276. {
  1277. //ownership: BucketOwnerEnforced (extra acl is not allowed)
  1278. //s3:PutBucketAcl('createObject' is set to false), config acl through request body
  1279. req := &http.Request{
  1280. Header: make(map[string][]string),
  1281. }
  1282. req.Body = io.NopCloser(bytes.NewReader([]byte(`
  1283. <AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  1284. <Owner>
  1285. <ID>admin</ID>
  1286. <DisplayName>admin</DisplayName>
  1287. </Owner>
  1288. <AccessControlList>
  1289. <Grant>
  1290. <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
  1291. <ID>admin</ID>
  1292. </Grantee>
  1293. <Permission>FULL_CONTROL</Permission>
  1294. </Grant>
  1295. <Grant>
  1296. <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
  1297. <URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
  1298. </Grantee>
  1299. <Permission>FULL_CONTROL</Permission>
  1300. </Grant>
  1301. </AccessControlList>
  1302. </AccessControlPolicy>
  1303. `)))
  1304. requestAccountId := "accountA"
  1305. _, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipBucketOwnerEnforced, accountAdminId, requestAccountId, false)
  1306. testCases = append(testCases, &Case{
  1307. id: "TestExtractBucketAcl: ownership-BucketOwnerEnforced, createObject-false, acl-requestBody",
  1308. resultErrCode: errCode, expectErrCode: s3err.AccessControlListNotSupported,
  1309. })
  1310. }
  1311. {
  1312. //ownership: ObjectWriter
  1313. //s3:PutObject('createObject' is set to false), request body will be ignored when parse acl
  1314. req := &http.Request{
  1315. Header: make(map[string][]string),
  1316. }
  1317. req.Body = io.NopCloser(bytes.NewReader([]byte(`
  1318. <AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  1319. <Owner>
  1320. <ID>admin</ID>
  1321. <DisplayName>admin</DisplayName>
  1322. </Owner>
  1323. <AccessControlList>
  1324. <Grant>
  1325. <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
  1326. <ID>admin</ID>
  1327. </Grantee>
  1328. <Permission>FULL_CONTROL</Permission>
  1329. </Grant>
  1330. <Grant>
  1331. <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
  1332. <URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
  1333. </Grantee>
  1334. <Permission>FULL_CONTROL</Permission>
  1335. </Grant>
  1336. </AccessControlList>
  1337. </AccessControlPolicy>
  1338. `)))
  1339. requestAccountId := "accountA"
  1340. grants, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipObjectWriter, accountAdminId, requestAccountId, true)
  1341. testCases = append(testCases, &Case{
  1342. "TestExtractBucketAcl: ownership-ObjectWriter, createObject-true, acl-requestBody",
  1343. errCode, s3err.ErrNone,
  1344. grants, []*s3.Grant{},
  1345. })
  1346. }
  1347. {
  1348. //ownership: BucketOwnerEnforced (extra acl is not allowed)
  1349. //s3:PutObject('createObject' is set to true), request body will be ignored when parse acl
  1350. req := &http.Request{
  1351. Header: make(map[string][]string),
  1352. }
  1353. req.Body = io.NopCloser(bytes.NewReader([]byte(`
  1354. <AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  1355. <Owner>
  1356. <ID>admin</ID>
  1357. <DisplayName>admin</DisplayName>
  1358. </Owner>
  1359. <AccessControlList>
  1360. <Grant>
  1361. <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
  1362. <ID>admin</ID>
  1363. </Grantee>
  1364. <Permission>FULL_CONTROL</Permission>
  1365. </Grant>
  1366. <Grant>
  1367. <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
  1368. <URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
  1369. </Grantee>
  1370. <Permission>FULL_CONTROL</Permission>
  1371. </Grant>
  1372. </AccessControlList>
  1373. </AccessControlPolicy>
  1374. `)))
  1375. requestAccountId := "accountA"
  1376. grants, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipBucketOwnerEnforced, accountAdminId, requestAccountId, true)
  1377. testCases = append(testCases, &Case{
  1378. "TestExtractBucketAcl: ownership-BucketOwnerEnforced, createObject-true, acl-requestBody",
  1379. errCode, s3err.ErrNone,
  1380. grants, []*s3.Grant{},
  1381. })
  1382. }
  1383. //CannedAcl Header to specify ACL
  1384. //cannedAcl, PutBucketAcl
  1385. {
  1386. //ownership: ObjectWriter
  1387. //s3:PutBucketAcl('createObject' is set to false), parse cannedACL header
  1388. req := &http.Request{
  1389. Header: make(map[string][]string),
  1390. }
  1391. req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl)
  1392. bucketOwnerId := "admin"
  1393. requestAccountId := "accountA"
  1394. _, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwnerId, requestAccountId, false)
  1395. testCases = append(testCases, &Case{
  1396. id: "TestExtractBucketAcl: ownership-ObjectWriter, createObject-false, acl-CannedAcl",
  1397. resultErrCode: errCode, expectErrCode: s3err.ErrInvalidAclArgument,
  1398. })
  1399. }
  1400. {
  1401. //ownership: BucketOwnerPreferred
  1402. //s3:PutBucketAcl('createObject' is set to false), parse cannedACL header
  1403. req := &http.Request{
  1404. Header: make(map[string][]string),
  1405. }
  1406. req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl)
  1407. bucketOwnerId := "admin"
  1408. requestAccountId := "accountA"
  1409. _, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipBucketOwnerPreferred, bucketOwnerId, requestAccountId, false)
  1410. testCases = append(testCases, &Case{
  1411. id: "TestExtractBucketAcl: ownership-BucketOwnerPreferred, createObject-false, acl-CannedAcl",
  1412. resultErrCode: errCode, expectErrCode: s3err.ErrInvalidAclArgument,
  1413. })
  1414. }
  1415. {
  1416. //ownership: BucketOwnerEnforced
  1417. //s3:PutBucketAcl('createObject' is set to false), parse cannedACL header
  1418. req := &http.Request{
  1419. Header: make(map[string][]string),
  1420. }
  1421. req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl)
  1422. bucketOwnerId := "admin"
  1423. requestAccountId := "accountA"
  1424. _, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipBucketOwnerEnforced, bucketOwnerId, requestAccountId, false)
  1425. testCases = append(testCases, &Case{
  1426. id: "TestExtractBucketAcl: ownership-BucketOwnerEnforced, createObject-false, acl-CannedAcl",
  1427. resultErrCode: errCode, expectErrCode: s3err.ErrInvalidAclArgument,
  1428. })
  1429. }
  1430. //cannedACL, createBucket
  1431. {
  1432. //ownership: ObjectWriter
  1433. //s3:PutObject('createObject' is set to true), parse cannedACL header
  1434. req := &http.Request{
  1435. Header: make(map[string][]string),
  1436. }
  1437. req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl)
  1438. bucketOwnerId := "admin"
  1439. requestAccountId := "accountA"
  1440. _, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwnerId, requestAccountId, true)
  1441. testCases = append(testCases, &Case{
  1442. id: "TestExtractBucketAcl: ownership-BucketOwnerEnforced, createObject-true, acl-CannedAcl",
  1443. resultErrCode: errCode, expectErrCode: s3err.ErrInvalidAclArgument,
  1444. })
  1445. }
  1446. {
  1447. //ownership: BucketOwnerPreferred
  1448. //s3:PutObject('createObject' is set to true), parse cannedACL header
  1449. req := &http.Request{
  1450. Header: make(map[string][]string),
  1451. }
  1452. req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl)
  1453. bucketOwnerId := "admin"
  1454. requestAccountId := "accountA"
  1455. _, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipBucketOwnerPreferred, bucketOwnerId, requestAccountId, true)
  1456. testCases = append(testCases, &Case{
  1457. id: "TestExtractBucketAcl: ownership-BucketOwnerPreferred, createObject-true, acl-CannedAcl",
  1458. resultErrCode: errCode, expectErrCode: s3err.ErrInvalidAclArgument,
  1459. })
  1460. }
  1461. {
  1462. //ownership: BucketOwnerEnforced
  1463. //s3:PutObject('createObject' is set to true), parse cannedACL header
  1464. req := &http.Request{
  1465. Header: make(map[string][]string),
  1466. }
  1467. req.Header.Set(s3_constants.AmzCannedAcl, s3_constants.CannedAclBucketOwnerFullControl)
  1468. bucketOwnerId := "admin"
  1469. requestAccountId := "accountA"
  1470. _, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipBucketOwnerEnforced, bucketOwnerId, requestAccountId, true)
  1471. testCases = append(testCases, &Case{
  1472. id: "TestExtractBucketAcl: ownership-BucketOwnerEnforced, createObject-true, acl-CannedAcl",
  1473. resultErrCode: errCode, expectErrCode: s3err.ErrInvalidAclArgument,
  1474. })
  1475. }
  1476. //customAcl, PutBucketAcl
  1477. {
  1478. //ownership: ObjectWriter
  1479. //s3:PutBucketAcl('createObject' is set to false), parse customAcl header
  1480. req := &http.Request{
  1481. Header: make(map[string][]string),
  1482. }
  1483. req.Header.Set(s3_constants.AmzAclFullControl, "id=accountA,id=\"admin\"")
  1484. bucketOwnerId := "admin"
  1485. requestAccountId := "accountA"
  1486. grants, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwnerId, requestAccountId, false)
  1487. testCases = append(testCases, &Case{
  1488. "TestExtractBucketAcl: ownership-ObjectWriter, createObject-false, acl-customAcl",
  1489. errCode, s3err.ErrNone,
  1490. grants, []*s3.Grant{
  1491. {
  1492. Grantee: &s3.Grantee{
  1493. Type: &s3_constants.GrantTypeCanonicalUser,
  1494. ID: &requestAccountId,
  1495. },
  1496. Permission: &s3_constants.PermissionFullControl,
  1497. },
  1498. {
  1499. Grantee: &s3.Grantee{
  1500. Type: &s3_constants.GrantTypeCanonicalUser,
  1501. ID: &bucketOwnerId,
  1502. },
  1503. Permission: &s3_constants.PermissionFullControl,
  1504. },
  1505. },
  1506. })
  1507. }
  1508. {
  1509. //ownership: BucketOwnerPreferred
  1510. //s3:PutBucketAcl('createObject' is set to false), parse customAcl header
  1511. req := &http.Request{
  1512. Header: make(map[string][]string),
  1513. }
  1514. req.Header.Set(s3_constants.AmzAclFullControl, "id=accountA,id=\"admin\"")
  1515. bucketOwnerId := "admin"
  1516. requestAccountId := "accountA"
  1517. grants, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipBucketOwnerPreferred, bucketOwnerId, requestAccountId, false)
  1518. testCases = append(testCases, &Case{
  1519. "TestExtractBucketAcl: ownership-BucketOwnerPreferred, createObject-false, acl-customAcl",
  1520. errCode, s3err.ErrNone,
  1521. grants, []*s3.Grant{
  1522. {
  1523. Grantee: &s3.Grantee{
  1524. Type: &s3_constants.GrantTypeCanonicalUser,
  1525. ID: &requestAccountId,
  1526. },
  1527. Permission: &s3_constants.PermissionFullControl,
  1528. },
  1529. {
  1530. Grantee: &s3.Grantee{
  1531. Type: &s3_constants.GrantTypeCanonicalUser,
  1532. ID: &bucketOwnerId,
  1533. },
  1534. Permission: &s3_constants.PermissionFullControl,
  1535. },
  1536. },
  1537. })
  1538. }
  1539. {
  1540. //ownership: BucketOwnerEnforced
  1541. //s3:PutBucketAcl('createObject' is set to false), parse customAcl header
  1542. req := &http.Request{
  1543. Header: make(map[string][]string),
  1544. }
  1545. req.Header.Set(s3_constants.AmzAclFullControl, "id=accountA,id=\"admin\"")
  1546. bucketOwnerId := "admin"
  1547. requestAccountId := "accountA"
  1548. _, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipBucketOwnerEnforced, bucketOwnerId, requestAccountId, false)
  1549. testCases = append(testCases, &Case{
  1550. id: "TestExtractBucketAcl: ownership-BucketOwnerEnforced, createObject-false, acl-customAcl",
  1551. resultErrCode: errCode, expectErrCode: s3err.AccessControlListNotSupported,
  1552. })
  1553. }
  1554. //customAcl, putObject
  1555. {
  1556. //ownership: ObjectWriter
  1557. //s3:PutObject('createObject' is set to true), parse customAcl header
  1558. req := &http.Request{
  1559. Header: make(map[string][]string),
  1560. }
  1561. req.Header.Set(s3_constants.AmzAclFullControl, "id=accountA,id=\"admin\"")
  1562. bucketOwnerId := "admin"
  1563. requestAccountId := "accountA"
  1564. grants, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwnerId, requestAccountId, true)
  1565. testCases = append(testCases, &Case{
  1566. "TestExtractBucketAcl: ownership-ObjectWriter, createObject-true, acl-customAcl",
  1567. errCode, s3err.ErrNone,
  1568. grants, []*s3.Grant{
  1569. {
  1570. Grantee: &s3.Grantee{
  1571. Type: &s3_constants.GrantTypeCanonicalUser,
  1572. ID: &requestAccountId,
  1573. },
  1574. Permission: &s3_constants.PermissionFullControl,
  1575. },
  1576. {
  1577. Grantee: &s3.Grantee{
  1578. Type: &s3_constants.GrantTypeCanonicalUser,
  1579. ID: &bucketOwnerId,
  1580. },
  1581. Permission: &s3_constants.PermissionFullControl,
  1582. },
  1583. },
  1584. })
  1585. }
  1586. {
  1587. //ownership: BucketOwnerPreferred
  1588. //s3:PutObject('createObject' is set to true), parse customAcl header
  1589. req := &http.Request{
  1590. Header: make(map[string][]string),
  1591. }
  1592. req.Header.Set(s3_constants.AmzAclFullControl, "id=\"admin\"")
  1593. bucketOwnerId := "admin"
  1594. requestAccountId := "accountA"
  1595. grants, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipBucketOwnerPreferred, bucketOwnerId, requestAccountId, true)
  1596. testCases = append(testCases, &Case{
  1597. "TestExtractBucketAcl: ownership-BucketOwnerPreferred, createObject-true, acl-customAcl",
  1598. errCode, s3err.ErrNone,
  1599. grants, []*s3.Grant{
  1600. {
  1601. Grantee: &s3.Grantee{
  1602. Type: &s3_constants.GrantTypeCanonicalUser,
  1603. ID: &bucketOwnerId,
  1604. },
  1605. Permission: &s3_constants.PermissionFullControl,
  1606. },
  1607. },
  1608. })
  1609. }
  1610. {
  1611. //ownership: BucketOwnerEnforced
  1612. //s3:PutObject('createObject' is set to true), parse customAcl header
  1613. req := &http.Request{
  1614. Header: make(map[string][]string),
  1615. }
  1616. req.Header.Set(s3_constants.AmzAclFullControl, "id=accountA,id=\"admin\"")
  1617. bucketOwnerId := "admin"
  1618. requestAccountId := "accountA"
  1619. _, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipBucketOwnerEnforced, bucketOwnerId, requestAccountId, true)
  1620. testCases = append(testCases, &Case{
  1621. id: "TestExtractBucketAcl: ownership-BucketOwnerEnforced, createObject-true, acl-customAcl",
  1622. resultErrCode: errCode, expectErrCode: s3err.AccessControlListNotSupported,
  1623. })
  1624. }
  1625. {
  1626. //parse acp from request header: both canned acl and custom acl not allowed
  1627. req := &http.Request{
  1628. Header: make(map[string][]string),
  1629. }
  1630. req.Header.Set(s3_constants.AmzAclFullControl, "id=admin, id=\"accountA\"")
  1631. req.Header.Set(s3_constants.AmzCannedAcl, "private")
  1632. bucketOwnerId := "admin"
  1633. requestAccountId := "accountA"
  1634. _, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipObjectWriter, bucketOwnerId, requestAccountId, false)
  1635. testCases = append(testCases, &Case{
  1636. id: "Only one of cannedAcl, customAcl is allowed",
  1637. resultErrCode: errCode, expectErrCode: s3err.ErrInvalidRequest,
  1638. })
  1639. }
  1640. {
  1641. //Acl can only be specified in one of requestBody, cannedAcl, customAcl, simultaneous use is not allowed
  1642. req := &http.Request{
  1643. Header: make(map[string][]string),
  1644. }
  1645. req.Header.Set(s3_constants.AmzAclFullControl, "id=admin, id=\"accountA\"")
  1646. req.Header.Set(s3_constants.AmzCannedAcl, "private")
  1647. req.Body = io.NopCloser(bytes.NewReader([]byte(`
  1648. <AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  1649. <Owner>
  1650. <ID>admin</ID>
  1651. <DisplayName>admin</DisplayName>
  1652. </Owner>
  1653. <AccessControlList>
  1654. <Grant>
  1655. <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
  1656. <ID>admin</ID>
  1657. </Grantee>
  1658. <Permission>FULL_CONTROL</Permission>
  1659. </Grant>
  1660. <Grant>
  1661. <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
  1662. <URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
  1663. </Grantee>
  1664. <Permission>FULL_CONTROL</Permission>
  1665. </Grant>
  1666. </AccessControlList>
  1667. </AccessControlPolicy>
  1668. `)))
  1669. requestAccountId := "accountA"
  1670. _, errCode := ExtractBucketAcl(req, accountManager, s3_constants.OwnershipObjectWriter, accountAdminId, requestAccountId, false)
  1671. testCases = append(testCases, &Case{
  1672. id: "Only one of requestBody, cannedAcl, customAcl is allowed",
  1673. resultErrCode: errCode, expectErrCode: s3err.ErrUnexpectedContent,
  1674. })
  1675. }
  1676. for _, tc := range testCases {
  1677. if tc.resultErrCode != tc.expectErrCode {
  1678. t.Fatalf("case[%s]: errorCode[%v] not expect[%v]", tc.id, s3err.GetAPIError(tc.resultErrCode).Code, s3err.GetAPIError(tc.expectErrCode).Code)
  1679. }
  1680. if !grantsEquals(tc.resultGrants, tc.expectGrants) {
  1681. t.Fatalf("case[%s]: grants not expect", tc.id)
  1682. }
  1683. }
  1684. }
  1685. func TestMarshalGrantsToJson(t *testing.T) {
  1686. //ok
  1687. bucketOwnerId := "admin"
  1688. requestAccountId := "accountA"
  1689. grants := []*s3.Grant{
  1690. {
  1691. Grantee: &s3.Grantee{
  1692. Type: &s3_constants.GrantTypeCanonicalUser,
  1693. ID: &requestAccountId,
  1694. },
  1695. Permission: &s3_constants.PermissionFullControl,
  1696. },
  1697. {
  1698. Grantee: &s3.Grantee{
  1699. Type: &s3_constants.GrantTypeCanonicalUser,
  1700. ID: &bucketOwnerId,
  1701. },
  1702. Permission: &s3_constants.PermissionFullControl,
  1703. },
  1704. }
  1705. result, err := MarshalGrantsToJson(grants)
  1706. if err != nil {
  1707. t.Error(err)
  1708. }
  1709. var grants2 []*s3.Grant
  1710. err = json.Unmarshal(result, &grants2)
  1711. if err != nil {
  1712. t.Error(err)
  1713. }
  1714. print(string(result))
  1715. if !grantsEquals(grants, grants2) {
  1716. t.Fatal("grants not equal", grants, grants2)
  1717. }
  1718. //ok
  1719. result, err = MarshalGrantsToJson(nil)
  1720. if result != nil && err != nil {
  1721. t.Fatal("error: result, err = MarshalGrantsToJson(nil)")
  1722. }
  1723. }