github.com/minio/minio-go/v6@v6.0.57/api-get-object-acl-context.go (about) 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 18 package minio 19 20 import ( 21 "context" 22 "net/http" 23 "net/url" 24 ) 25 26 type accessControlPolicy struct { 27 Owner struct { 28 ID string `xml:"ID"` 29 DisplayName string `xml:"DisplayName"` 30 } `xml:"Owner"` 31 AccessControlList struct { 32 Grant []struct { 33 Grantee struct { 34 ID string `xml:"ID"` 35 DisplayName string `xml:"DisplayName"` 36 URI string `xml:"URI"` 37 } `xml:"Grantee"` 38 Permission string `xml:"Permission"` 39 } `xml:"Grant"` 40 } `xml:"AccessControlList"` 41 } 42 43 //GetObjectACLWithContext get object ACLs 44 func (c Client) GetObjectACLWithContext(ctx context.Context, bucketName, objectName string) (*ObjectInfo, error) { 45 resp, err := c.executeMethod(ctx, "GET", requestMetadata{ 46 bucketName: bucketName, 47 objectName: objectName, 48 queryValues: url.Values{ 49 "acl": []string{""}, 50 }, 51 }) 52 if err != nil { 53 return nil, err 54 } 55 defer closeResponse(resp) 56 57 if resp.StatusCode != http.StatusOK { 58 return nil, httpRespToErrorResponse(resp, bucketName, objectName) 59 } 60 61 res := &accessControlPolicy{} 62 63 if err := xmlDecoder(resp.Body, res); err != nil { 64 return nil, err 65 } 66 67 objInfo, err := c.statObject(ctx, bucketName, objectName, StatObjectOptions{}) 68 if err != nil { 69 return nil, err 70 } 71 72 objInfo.Owner.DisplayName = res.Owner.DisplayName 73 objInfo.Owner.ID = res.Owner.ID 74 75 objInfo.Grant = append(objInfo.Grant, res.AccessControlList.Grant...) 76 77 cannedACL := getCannedACL(res) 78 if cannedACL != "" { 79 objInfo.Metadata.Add("X-Amz-Acl", cannedACL) 80 return &objInfo, nil 81 } 82 83 grantACL := getAmzGrantACL(res) 84 for k, v := range grantACL { 85 objInfo.Metadata[k] = v 86 } 87 88 return &objInfo, nil 89 } 90 91 func getCannedACL(aCPolicy *accessControlPolicy) string { 92 grants := aCPolicy.AccessControlList.Grant 93 94 switch { 95 case len(grants) == 1: 96 if grants[0].Grantee.URI == "" && grants[0].Permission == "FULL_CONTROL" { 97 return "private" 98 } 99 case len(grants) == 2: 100 for _, g := range grants { 101 if g.Grantee.URI == "http://acs.amazonaws.com/groups/global/AuthenticatedUsers" && g.Permission == "READ" { 102 return "authenticated-read" 103 } 104 if g.Grantee.URI == "http://acs.amazonaws.com/groups/global/AllUsers" && g.Permission == "READ" { 105 return "public-read" 106 } 107 if g.Permission == "READ" && g.Grantee.ID == aCPolicy.Owner.ID { 108 return "bucket-owner-read" 109 } 110 } 111 case len(grants) == 3: 112 for _, g := range grants { 113 if g.Grantee.URI == "http://acs.amazonaws.com/groups/global/AllUsers" && g.Permission == "WRITE" { 114 return "public-read-write" 115 } 116 } 117 } 118 return "" 119 } 120 121 func getAmzGrantACL(aCPolicy *accessControlPolicy) map[string][]string { 122 grants := aCPolicy.AccessControlList.Grant 123 res := map[string][]string{} 124 125 for _, g := range grants { 126 switch { 127 case g.Permission == "READ": 128 res["X-Amz-Grant-Read"] = append(res["X-Amz-Grant-Read"], "id="+g.Grantee.ID) 129 case g.Permission == "WRITE": 130 res["X-Amz-Grant-Write"] = append(res["X-Amz-Grant-Write"], "id="+g.Grantee.ID) 131 case g.Permission == "READ_ACP": 132 res["X-Amz-Grant-Read-Acp"] = append(res["X-Amz-Grant-Read-Acp"], "id="+g.Grantee.ID) 133 case g.Permission == "WRITE_ACP": 134 res["X-Amz-Grant-Write-Acp"] = append(res["X-Amz-Grant-Write-Acp"], "id="+g.Grantee.ID) 135 case g.Permission == "FULL_CONTROL": 136 res["X-Amz-Grant-Full-Control"] = append(res["X-Amz-Grant-Full-Control"], "id="+g.Grantee.ID) 137 } 138 } 139 return res 140 }