From 483afd64b91fb1aea24b3810e910e4616721945d Mon Sep 17 00:00:00 2001 From: Andrew Gaul Date: Sat, 4 Jan 2025 06:50:50 +0900 Subject: [PATCH] Add support for getObjectACL and deleteObjectACL (#1832) --- fakestorage/object.go | 53 ++++++++++++++++++++++++++++++++++++++ fakestorage/object_test.go | 17 ++++++++++++ fakestorage/server.go | 2 ++ 3 files changed, 72 insertions(+) diff --git a/fakestorage/object.go b/fakestorage/object.go index b229a45233..bc23a61665 100644 --- a/fakestorage/object.go +++ b/fakestorage/object.go @@ -710,6 +710,59 @@ func (s *Server) listObjectACL(r *http.Request) jsonResponse { return jsonResponse{data: newACLListResponse(obj.ObjectAttrs)} } +func (s *Server) deleteObjectACL(r *http.Request) jsonResponse { + vars := unescapeMuxVars(mux.Vars(r)) + + obj, err := s.GetObjectStreaming(vars["bucketName"], vars["objectName"]) + if err != nil { + return jsonResponse{status: http.StatusNotFound} + } + defer obj.Close() + entity := vars["entity"] + + var newAcls []storage.ACLRule + for _, aclRule := range obj.ObjectAttrs.ACL { + if entity != string(aclRule.Entity) { + newAcls = append(newAcls, aclRule) + } + } + + obj.ACL = newAcls + obj, err = s.createObject(obj, backend.NoConditions{}) + if err != nil { + return errToJsonResponse(err) + } + defer obj.Close() + + return jsonResponse{status: http.StatusOK} +} + +func (s *Server) getObjectACL(r *http.Request) jsonResponse { + vars := unescapeMuxVars(mux.Vars(r)) + + obj, err := s.backend.GetObject(vars["bucketName"], vars["objectName"]) + if err != nil { + return jsonResponse{status: http.StatusNotFound} + } + defer obj.Close() + entity := vars["entity"] + + for _, aclRule := range obj.ObjectAttrs.ACL { + if entity == string(aclRule.Entity) { + oac := &objectAccessControl{ + Bucket: obj.BucketName, + Entity: string(aclRule.Entity), + Object: obj.Name, + Role: string(aclRule.Role), + Etag: "RVRhZw==", + Kind: "storage#objectAccessControl", + } + return jsonResponse{data: oac} + } + } + return jsonResponse{status: http.StatusNotFound} +} + func (s *Server) setObjectACL(r *http.Request) jsonResponse { vars := unescapeMuxVars(mux.Vars(r)) diff --git a/fakestorage/object_test.go b/fakestorage/object_test.go index 2fb33d02da..8cae0406d1 100644 --- a/fakestorage/object_test.go +++ b/fakestorage/object_test.go @@ -1676,6 +1676,23 @@ func TestServerClientObjectSetAclPrivate(t *testing.T) { t.Fatal("acl role not set to RoleReader") return } + + err = objHandle.ACL().Delete(ctx, storage.AllAuthenticatedUsers) + if err != nil { + t.Fatalf("unexpected error while deleting acl %+v", err) + return + } + + rules, err = objHandle.ACL().List(ctx) + if err != nil { + t.Fatalf("unexpected error while getting acl %+v", err) + return + } + + if len(rules) != 0 { + t.Fatalf("acl has unexpected rules: %+v", rules) + return + } }) }) } diff --git a/fakestorage/server.go b/fakestorage/server.go index 261a47df85..85792a8b4e 100644 --- a/fakestorage/server.go +++ b/fakestorage/server.go @@ -275,6 +275,8 @@ func (s *Server) buildMuxer() { r.Path("/b/{bucketName}/o/{objectName:.+}").Methods(http.MethodPost).Headers("X-HTTP-Method-Override", "PATCH").HandlerFunc(jsonToHTTPHandler(s.patchObject)) r.Path("/b/{bucketName}/o/{objectName:.+}/acl").Methods(http.MethodGet).HandlerFunc(jsonToHTTPHandler(s.listObjectACL)) r.Path("/b/{bucketName}/o/{objectName:.+}/acl").Methods(http.MethodPost).HandlerFunc(jsonToHTTPHandler(s.setObjectACL)) + r.Path("/b/{bucketName}/o/{objectName:.+}/acl/{entity}").Methods(http.MethodDelete).HandlerFunc(jsonToHTTPHandler(s.deleteObjectACL)) + r.Path("/b/{bucketName}/o/{objectName:.+}/acl/{entity}").Methods(http.MethodGet).HandlerFunc(jsonToHTTPHandler(s.getObjectACL)) r.Path("/b/{bucketName}/o/{objectName:.+}/acl/{entity}").Methods(http.MethodPut).HandlerFunc(jsonToHTTPHandler(s.setObjectACL)) r.Path("/b/{bucketName}/o/{objectName:.+}").Methods(http.MethodGet, http.MethodHead).HandlerFunc(s.getObject) r.Path("/b/{bucketName}/o/{objectName:.+}").Methods(http.MethodDelete).HandlerFunc(jsonToHTTPHandler(s.deleteObject))