3

I've been having trouble over the past few days using the Google Directory API in the Admin SDK for Google Apps. The documentation leaves a lot to be desired and when I contacted Google Apps Enterprise support they indicated they do not support the API. I am using the most recent Python API client library provided by Google as they suggest this is the best way to go. I've logged in to the Google API Console and created a Service Account and downloaded the OAuth2 key. I've also turned on the Admin SDK in the console. Here is my code:

f = file("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-privatekey.p12", "rb")
key = f.read()
f.close()

credentials = SignedJwtAssertionCredentials(
    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx@developer.gserviceaccount.com",
    key,
    scope = "https://www.googleapis.com/auth/admin.directory.orgunit"
)

http = httplib2.Http()
http = credentials.authorize(http)

directoryservice = build("admin", "directory_v1", http=http)

orgunits = directoryservice.orgunits().list(customerId='XXXXXXX').execute(http=http)
pprint.pprint(orgunits)

Note that customerId is our Google Apps customer ID. I tried it with "my_customer" as Google seems to indicate should work when using an account that is super admin, but I receive the return "invalid customerId" when I try it that way. So I hardcoded our actual customerId.

When harcoded always receive the return "Login Required" but it seems as if the authentication process is working as the directory object gets created via the build command. Am I doing something wrong?

Note, I also read somewhere that sometimes the request needs to come from a domain account rather than the Service Account and to do this you need to add:

sub = "domain_account_superadmin@example.com"

In the SignedJwtAssertionCredentials call... which I tried, but then receive the message "access_denied"

Thanks in advance for suggestions.

Tyler
  • 1,291
  • 1
  • 13
  • 20

1 Answers1

3

See the google drive example here: https://developers.google.com/drive/delegation Don't forget to delegate domain wide authority for the service account and scopes. Here is an example for listing organization units via service account:

import sys
import apiclient.discovery
import oauth2client.client
import httplib2
import pprint

# see example for using service account here: 
#   https://developers.google.com/drive/delegation
def main (argv):
    scopes = ('https://www.googleapis.com/auth/admin.directory.orgunit')
    service_account_email = 'xxx@developer.gserviceaccount.com'
    acting_as_user = 'yyy@zzz' # must have the privileges to view the org units
    f = file('key.p12', 'rb')
    key = f.read()
    f.close()
    credentials = oauth2client.client.SignedJwtAssertionCredentials(
        service_account_email,
        key,
        scope=scopes,
        sub=acting_as_user
        )
    http = httplib2.Http()
    http = credentials.authorize(http)
    directoryservice = apiclient.discovery.build('admin', 'directory_v1', http=http)
    response = directoryservice.orgunits().list(customerId='my_customer').execute(http=http)
    pprint.pprint(response)

if __name__ == '__main__':
    main(sys.argv)
CTy
  • 169
  • 3
  • Thanks for the response. This is fairly identical to my code and I receive the same message using this code "access_denied" when I try to add "sub=xxx@zzz" ... When you say "Don't forget to delegate domain wide authority for the service account and scopes" what do you mean by this? Currently I am of "superadmin" role for the Google Apps domain I am testing this on... is there something I am missing the Apps console that is giving me grief on access permissions? – Tyler Nov 11 '13 at 19:33
  • 1
    Nevermind... I finally found it in the Admin Console when switching to the old view. The entire time was because I hadn't delegated the appropriate permissions there. Very simple problem, but had it not been for your simple reminder in the beginning I would not have gotten this. Thanks again! – Tyler Nov 11 '13 at 19:40
  • @Tyler I'm facing nearly the same problem -- when you say "old view" of the Admin Console, are you talking about the old Cloud Console or an older version of the Apps Admin Console? (I've only seen the new version.) Where can permissions be delegated? – Eric Walker Nov 13 '13 at 17:53
  • 1
    @EricWalker By "old view" i do mean the Apps Admin Console. This is because at my university we have two domains, one we're using for testing the migration process and another that is our "production" domain on Google Apps. What is funny, our production domain uses the new Admin Console, but we don't have available the new console on the test domain. It simply doesn't let us use it. In the OLD Admin Console I found what I needed in "Advanced Tools" tab -> "Manage Third Party OAuth Client access" – Tyler Nov 13 '13 at 21:40
  • 1
    @EricWalker This screenshot shows you where you enter the client ID and the scopes that you want that client to be able to access. http://i.tylerwhitney.com/image/2I3y39270z29 Note that the client ID is the domain, not the email address. Which is somewhat confusing. Lastly, for what its worth, I also chose to use the old API Console too (which is now called Cloud Console). Mainly because I was getting grief trying to add a new OAuth2 Service Account... and its much more intuitive in the older API console. – Tyler Nov 13 '13 at 21:51
  • @EricWalker Just as a reference, here is what my Cloud Console looks like vs. the "old view" they give me the option of using... http://i.tylerwhitney.com/image/0l2z0F1A040l and this is the old view: http://i.tylerwhitney.com/image/2f3U1I42371m ... the new view doesn't show you the Client ID url... so I got confused on multiple levels. The documentation on Google's API pages is pretty terrible, and a lot of deadlinks. I'm not sure what it looks like where you add third-party OAuth2 access in the new Apps Admin console. I imagine I'll figure it out in a few weeks when I make this project live. – Tyler Nov 13 '13 at 21:53