api-get-object-acl.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*
  2. * MinIO Go Library for Amazon S3 Compatible Cloud Storage
  3. * Copyright 2018 MinIO, Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package s3cli
  18. import (
  19. "context"
  20. "net/http"
  21. "net/url"
  22. "encoding/xml"
  23. )
  24. const (
  25. CANNED_ACL_PRIVATE = "private"
  26. CANNED_ACL_AUTH_READ = "authenticated-read"
  27. CANNED_ACL_PUBLIC_READ = "public-read"
  28. CANNED_ACL_PUBLIC_READ_WRITE = "public-read-write"
  29. )
  30. type AccessControlPolicy struct {
  31. XMLName xml.Name `xml:"AccessControlPolicy"`
  32. Owner struct {
  33. ID string `xml:"ID"`
  34. DisplayName string `xml:"DisplayName"`
  35. } `xml:"Owner"`
  36. AccessControlList struct {
  37. Grant []Grant `xml:"Grant"`
  38. } `xml:"AccessControlList"`
  39. }
  40. //GetObjectACL get object ACLs
  41. func (c Client) GetObjectACL(bucketName, objectName string) (*AccessControlPolicy, error) {
  42. resp, err := c.executeMethod(context.Background(), "GET", requestMetadata{
  43. bucketName: bucketName,
  44. objectName: objectName,
  45. queryValues: url.Values{
  46. "acl": []string{""},
  47. },
  48. })
  49. if err != nil {
  50. return nil, err
  51. }
  52. defer closeResponse(resp)
  53. if resp.StatusCode != http.StatusOK {
  54. return nil, httpRespToErrorResponse(resp, bucketName, objectName)
  55. }
  56. res := &AccessControlPolicy{}
  57. if err := xmlDecoder(resp.Body, res); err != nil {
  58. return nil, err
  59. }
  60. return res, nil
  61. }
  62. func CannedAcl(ownerId string, ownerName string, acl string) AccessControlPolicy {
  63. owner := Owner{ID: ownerId, DisplayName: ownerName}
  64. switch acl {
  65. case CANNED_ACL_PRIVATE:
  66. return PrivateAcl(owner)
  67. case CANNED_ACL_AUTH_READ:
  68. return AuthReadAcl(owner)
  69. case CANNED_ACL_PUBLIC_READ:
  70. return PublicReadAcl(owner)
  71. case CANNED_ACL_PUBLIC_READ_WRITE:
  72. return PublicReadWriteAcl(owner)
  73. default:
  74. return PrivateAcl(owner)
  75. }
  76. }
  77. func PrivateAcl(owner Owner) AccessControlPolicy {
  78. policy := AccessControlPolicy{}
  79. policy.Owner.ID = owner.ID
  80. policy.Owner.DisplayName = owner.DisplayName
  81. policy.AccessControlList.Grant = make([]Grant, 1)
  82. policy.AccessControlList.Grant[0].Grantee.Type = GRANTEE_TYPE_USER
  83. policy.AccessControlList.Grant[0].Grantee.ID = owner.ID
  84. policy.AccessControlList.Grant[0].Grantee.DisplayName = owner.DisplayName
  85. policy.AccessControlList.Grant[0].Permission = PERMISSION_FULL_CONTROL
  86. return policy
  87. }
  88. func AuthReadAcl(owner Owner) AccessControlPolicy {
  89. policy := PrivateAcl(owner)
  90. authRead := Grant{}
  91. authRead.Permission = PERMISSION_READ
  92. authRead.Grantee.Type = GRANTEE_TYPE_GROUP
  93. authRead.Grantee.URI = GRANTEE_GROUP_URI_AUTH_USERS
  94. policy.AccessControlList.Grant = append(policy.AccessControlList.Grant, authRead)
  95. return policy
  96. }
  97. func PublicReadAcl(owner Owner) AccessControlPolicy {
  98. policy := PrivateAcl(owner)
  99. publicRead := Grant{}
  100. publicRead.Permission = PERMISSION_READ
  101. publicRead.Grantee.Type = GRANTEE_TYPE_GROUP
  102. publicRead.Grantee.URI = GRANTEE_GROUP_URI_ALL_USERS
  103. policy.AccessControlList.Grant = append(policy.AccessControlList.Grant, publicRead)
  104. return policy
  105. }
  106. func PublicReadWriteAcl(owner Owner) AccessControlPolicy {
  107. policy := PublicReadAcl(owner)
  108. publicWrite := Grant{}
  109. publicWrite.Permission = PERMISSION_WRITE
  110. publicWrite.Grantee.Type = GRANTEE_TYPE_GROUP
  111. publicWrite.Grantee.URI = GRANTEE_GROUP_URI_ALL_USERS
  112. policy.AccessControlList.Grant = append(policy.AccessControlList.Grant, publicWrite)
  113. return policy
  114. }
  115. func (aCPolicy *AccessControlPolicy) GetCannedACL() string {
  116. grants := aCPolicy.AccessControlList.Grant
  117. switch {
  118. case len(grants) == 1:
  119. if grants[0].Grantee.URI == "" && grants[0].Permission == PERMISSION_FULL_CONTROL {
  120. return CANNED_ACL_PRIVATE
  121. }
  122. case len(grants) == 2:
  123. for _, g := range grants {
  124. if g.Grantee.URI == GRANTEE_GROUP_URI_AUTH_USERS && g.Permission == PERMISSION_READ {
  125. return CANNED_ACL_AUTH_READ
  126. }
  127. if g.Grantee.URI == GRANTEE_GROUP_URI_ALL_USERS && g.Permission == PERMISSION_READ {
  128. return CANNED_ACL_PUBLIC_READ
  129. }
  130. if g.Permission == "READ" && g.Grantee.ID == aCPolicy.Owner.ID {
  131. return "bucket-owner-read"
  132. }
  133. }
  134. case len(grants) == 3:
  135. for _, g := range grants {
  136. if g.Grantee.URI == GRANTEE_GROUP_URI_ALL_USERS && g.Permission == PERMISSION_WRITE {
  137. return CANNED_ACL_PUBLIC_READ_WRITE
  138. }
  139. }
  140. }
  141. return ""
  142. }
  143. func (aCPolicy *AccessControlPolicy) GetAmzGrantACL() map[string][]string {
  144. grants := aCPolicy.AccessControlList.Grant
  145. res := map[string][]string{}
  146. for _, g := range grants {
  147. switch {
  148. case g.Permission == "READ":
  149. res["X-Amz-Grant-Read"] = append(res["X-Amz-Grant-Read"], "id="+g.Grantee.ID)
  150. case g.Permission == "WRITE":
  151. res["X-Amz-Grant-Write"] = append(res["X-Amz-Grant-Write"], "id="+g.Grantee.ID)
  152. case g.Permission == "READ_ACP":
  153. res["X-Amz-Grant-Read-Acp"] = append(res["X-Amz-Grant-Read-Acp"], "id="+g.Grantee.ID)
  154. case g.Permission == "WRITE_ACP":
  155. res["X-Amz-Grant-Write-Acp"] = append(res["X-Amz-Grant-Write-Acp"], "id="+g.Grantee.ID)
  156. case g.Permission == "FULL_CONTROL":
  157. res["X-Amz-Grant-Full-Control"] = append(res["X-Amz-Grant-Full-Control"], "id="+g.Grantee.ID)
  158. }
  159. }
  160. return res
  161. }