jyoung
jyoung

Reputation: 322

Google Cloud Storage setting permissions gives bad request errors Java JSON API

I'm using the JSON API Java library to upload objects to Google Cloud Storage. I've figured out how to add the entity allUsers with role READER to get public access, but any other entity/role entries I try to add to my list of ObjectAccessControl produce some generic errors like

com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad Request

"code" : 400,
"errors" : [ {
    "domain" : "global",
    "message" : "Invalid Value",
    "reason" : "invalid"
  }

...for each ACL entry I have, except the allUsers READER one which seems to work

I'm not sure what it's complaining about here. I'm trying to reproduce the default permissions I see in the Developers Console, i.e. when I don't specify any ACL on the metadata. owners-projectId owner, editors-projectId owner, viewers-projectId reader, and user Id owner (I am guessing this is the service account ID)

I'm adding these to the ACL list the same way as the allUsers entity. I've searched for hours trying to find some documentation or similar issues to this, but only found the one regarding allUsers. I've tried escaping these ids, thinking the JSON library might not be doing so for me, but get the same errors.

Here's my relevant Java code:

// Set permissions and content type on StorageObject metadata       
StorageObject objectMetadata = new StorageObject();

// set access control
List<ObjectAccessControl> acl = Lists.newArrayList();
acl.add(new ObjectAccessControl().setEntity("allUsers").setRole("READER"));
// this one allows upload to work without error if it is the only access specified,
// but prevents me from modifying publicly available status or editing permissions
// via the developers console (I think this is to be expected)

// attempt to replicating bucket defaults...
// adding any of these will cause the error
acl.add(new ObjectAccessControl().setEntity("owners-projectId").setRole("OWNER"));
acl.add(new ObjectAccessControl().setEntityId("editors-projectId").setRole("OWNER"));
acl.add(new ObjectAccessControl().setEntityId("viewers-projectId").setRole("READER"));

objectMetadata.setAcl(acl);

where projectId is my project ID copied from the Developer's console site.

Upvotes: 1

Views: 1728

Answers (2)

Guruputra K M
Guruputra K M

Reputation: 11

You can set the access control permission by using "predefinedAcl" the code is as follows.

Storage.Objects.Insert insertObject =client.objects().insert(, ,);

    insertObject.setPredefinedAcl("publicRead");

This will work fine

Upvotes: 0

jyoung
jyoung

Reputation: 322

Finally figured this out.

I first suspected my storage scope of DEVSTORAGE_READ_WRITE was not sufficient, and tried DEVSTORAGE_FULL_CONTROL, but that was not the reason.

Also ignore my use of setEntityId(...) in my original post, although this was something I also tried to no avail.

The problem was simply incorrect syntax in the entity argument. The document you need is this: https://cloud.google.com/storage/docs/json_api/v1/defaultObjectAccessControls

Then you will see that the proper method looks something like:

acl.add(new ObjectAccessControl().setEntity("project-owners-projectId").setRole("OWNER"));

Oddly enough, this did NOT work:

acl.add(new ObjectAccessControl().setProjectTeam(new ProjectTeam().setProjectNumber("projectId").setTeam("owners")).setRole("OWNER"));

I suspect that method of setting the project team entity is a bug in the Java library, but I'm not sure.

The error message for incorrect entities that keeps saying Domain global required, or Domain global invalid value, is simply not very instructive. Setting domain is not required for this case. Also see the discussion at: What domain is Google Cloud Storage expecting in the ACL definitions when inserting an object?

Hope this helps someone else out!

Upvotes: 1

Related Questions