Search code examples
google-docs-apigoogle-drive-api

AclRole for Commenter


I have an issue updating the Acl for a Google Document. I want to share the document with some users but only allow COMMENTER privileges. This is the code: AclEntry newAclEntry = getDservice().insert(new URL(aclFeedUrl), new AclScope( AclScope.Type.USER, "user1@domain.com"), AclRole.COMMENTER);

Now Eclipse tells me AclRole.COMMENTER is a valid type but when I run the code I get the following exception: Service Exception: The posted entry has an invalid value for the field(s): role

If I change this to AclRole.READER it works fine.

So I thought I'd do a bit of investigation. You can set COMMENTER access from a Google Doc via 'share'. So I did that and then read the ACL's for the doc via:

AclFeed feed = getDservice().getFeed(new URL(doc.getAclFeedLink().getHref()),AclFeed.class);

        if (feed == null) 
            System.out.println("Feed is null");
        else {

            for (AclEntry a: feed.getEntries()) {
                System.out.println("acl role:" + a.getRole().getValue());
                System.out.println("acl scope:" + a.getScope().getValue());
            }
        }

The output for user1 with COMMENTER access, and user2 with READER access was:

acl role:reader acl scope:user1@domain.com

acl role:reader acl scope:user2@domain.com

So even when user1 is explicitly a COMMENTER, it's being reported as a 'reader'

If I access the online documentation for AclRole there is no COMMENTER enumeration (https://developers.google.com/gdata/javadoc/com/google/gdata/data/acl/AclRole).

So, how do I set an ACL for Comment only privileges? Clearly it's supported in Google Docs, and Eclipse is picking it up from the GData jars I'm using.

What am I missing?


Solution

  • The thing missing here is checking the additionalRole field of the ACL entry. The user is a reader and a commenter. Check out this raw XML response from the Documents List API:

    <entry gd:etag='W/&quot;D0UFQH4_eCt7ImAe9WhJREEk.&quot;'>
      <id>https://docs.google.com/feeds/id/user%3Aa%40b.com</id>
      <updated>2012-07-11T22:20:11.040Z</updated>
      <app:edited xmlns:app='http://www.w3.org/2007/app'>2012-07-11T22:20:11.040Z</app:edited>
      <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/acl/2007#accessRule'/>
      <title>Document Permission - a@b.com</title>
      <link rel='self' type='application/atom+xml' href='https://docs.google.com/feeds/default/private/expandAcl/document%3A1lD_aQPqe33JI4mObm2zc7FADUH-ypXcGekwAovPY2OpMw/acl/user%3Aa%40b.com'/>
      <link rel='edit' type='application/atom+xml' href='https://docs.google.com/feeds/default/private/expandAcl/document%3A1lD_aQPqe33JI4mObm2zc7FADUH-ypXcGekwAovPY2OpMw/acl/user%3Aa%40b.com'/>
      <gAcl:role xmlns:gAcl='http://schemas.google.com/acl/2007' value='reader'/>
      <gAcl:scope xmlns:gAcl='http://schemas.google.com/acl/2007' type='user' value='a@b.com' name='Anderson Jones'/>
      <gAcl:additionalRole xmlns:gAcl='http://schemas.google.com/acl/2007' value='commenter'/>
    </entry>
    

    Note the value of gAcl:additionalRole is commenter.

    Try this code to create a commenter entry:

    AclEntry aclEntry = new AclEntry();
    aclEntry.setScope(new AclScope("user", "user1@domain.com"));
    aclEntry.setRole(AclRole.READER);
    aclEntry.addAdditionalRole(AdditionalRole.COMMENTER);
    

    And to determine if an entry has the commenter additionalRole, do this:

    if (aclEntry.getAdditionalRoles().contains(AdditionalRole.COMMENTER)) {
      // Do something knowing this user is a commenter
    }
    

    However, you really should upgrade to the Drive API v2, which makes this easier. The following code sample is for the Drive API:

    Permission permission = new Permission();
    permission.setType("user");
    permission.setValue("user1@domain.com");
    permission.setRole("reader");
    permission.setAdditionalRoles(Arrays.asList("commenter"));
    

    Thanks to Alain Vongsouvanh for providing parts of this answer!