Google Admin SDK Directory Service API Implementation (see attachment)

3,475 views
Skip to first unread message

Aapo Talvensaari

unread,
Jun 5, 2013, 2:59:02 PM6/5/13
to google-api...@googlegroups.com
Hi Everyone,

I created Google Admin SDK Directory Service API implementation (see the attached code). This is related to issue 326 (https://code.google.com/p/google-api-php-client/issues/detail?id=326).

I have not thoroughly tested the code, and it isn't documented yet. But I like to start discussion about it. What do you think? I have read "Becoming A Contributor" article, and I did sign invidual CLA (but I have not gotten any mail yet).


Regards
Aapo
Google_DirectoryService.php

Jørund Fagerjord

unread,
Jun 10, 2013, 7:49:28 AM6/10/13
to google-api...@googlegroups.com
Hi!

I've been struggling with this for 3 and a half full days now! Finally, I'm getting som closure to the nature of the problem.

I've seen some examples, but I'm a newbie to PHP; Could you provide a simple example of how you could get all groups for a domain or something similar? I.e. how you could do this API-call; https://www.googleapis.com/admin/directory/v1/groups?domain=example.com ; with the framework?
That would be of great help for a now tired spirit.

Like something along the lines of [1] or [2]?

Anyways, the information that it isn't working with Service Account and that it does with Web Application is enormously helpful. Thanks!

Aapo Talvensaari

unread,
Jun 11, 2013, 5:35:55 AM6/11/13
to google-api...@googlegroups.com
I mistakenly replied directly to Jørund, so here is our conversation to this group too (including Jørund's followup):

By Aapo Talvensaari:

Here is example of retrieving Groups from "yourdomain.com":

<?php
require DIR . 'lib/vendor/google/Google_Client.php';
require DIR . 'lib/vendor/google/contrib/Google_DirectoryService.php';

const GOOGLE_API_CLIENT_ID = '{your-api-client-id}';
const GOOGLE_API_CLIENT_SECRET = '{your-api-client-secret}';
const GOOGLE_API_ACCESS_TOKEN = '{your-api-access-token}';

$client = new Google_Client();
$client->setClientId(GOOGLE_API_CLIENT_ID);
$client->setClientSecret(GOOGLE_API_CLIENT_SECRET);
$client->setAccessToken(GOOGLE_API_ACCESS_TOKEN);
$client->setUseObjects(true);
$service = new Google_DirectoryService($client);
$groups = $service->groups->listGroups(array('domain' => 'yourdomain.com'));
var_dump($groups);

I'm pretty sure the problems you are having are related to OAuth2 dancing that you have failed to do prior using this library. And the service accounts doesn't work, and that's why you have to do the dance (I have given my app access to these: MyApplication — Admin Group Management API (read only), Admin Group Members Management API, Admin Group Members Management API (read only), Admin Group Management API). Also this user needs to have premissions to these objects. So how does this work?

1. you give access to some application to use your account to make certain things on objects hosted at google apps
2. this account does need to have permissions to those objects
3. if you successfully authorize the application you will get access token (GOOGLE_API_ACCESS_TOKEN).

The example of this dance is proviced at front page of this project:

The access token looks something like this:

const GOOGLE_API_ACCESS_TOKEN = '{"access_token":"blaablaablaa","token_type":"Bearer","expires_in":3600,"refresh_token":"blaablaablaa","created":616164}';


Regards
Aapo


By Jørund:

Thanks for the reply!

Actually, the nature of my problem was that I was struggelig to get the right access with certificate and tokens (that I actually got successfully) when using a Service Account, which, as you pointed out, just doesn't work.

I followed the instructions on Using OAuth 2.0 for Web Server Applications[3], and was successful in getting a token and a refresh token for my user. I created a new web app in project API Console, and used localhost as the redirect_uri in order to get the authorization code, which then gave me my tokens.

After I did that, your code worked like a charm! I'm a PHP newbie, so I hope to make to make up for some of my three days of struggling by using the Service you created. The example helped a lot. Thanks again for that and the example! :)

By the way: You should consider answering on the email-list[4] for internet fame and good karma! There's probably somebody else who can gain a lot from your answer and code example.






--
You received this message because you are subscribed to a topic in the Google Groups "google-api-php-client" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/google-api-php-client/LM-mwmuZe7I/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to google-api-php-c...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Aaron Montana

unread,
Jun 13, 2013, 3:17:32 PM6/13/13
to google-api...@googlegroups.com
Thanks a ton for this - I was hunting for exactly this after seeing that Google hadn't released a PHP library.

As a side note, it might be worth noting that the access token must be tied to a user who is also an Administrator of the Google Apps domain - it took me some time to figure that out.

 Jørund is definitely right, prepare for massive internet fame. I'll chime in if I find any bugs. 


Thanks again!

Aaron Montana

Aapo Talvensaari

unread,
Jun 13, 2013, 4:08:37 PM6/13/13
to google-api...@googlegroups.com
Thanks Aaron,

Please let me know if you hit any bugs. Meanwhile I try to find some time to add PHPDocs to the code. Your kind worlds encourages me to make it even better. Hopefully at some point it is good enough to be included in official package, but that is beyond me.


Regards
Aapo


--
You received this message because you are subscribed to a topic in the Google Groups "google-api-php-client" group.

Chak Ming Wong

unread,
Jun 18, 2013, 11:00:18 AM6/18/13
to google-api...@googlegroups.com
is "Service Account" doesn't work for Admin SDK? I try a lot of time but everything works fine with "Web Application" but not "Service Account".

Ming

Aapo Talvensaari於 2013年6月14日星期五UTC+8上午4時08分37秒寫道:

To unsubscribe from this group and all its topics, send an email to google-api-php-client+unsub...@googlegroups.com.

Chak Ming Wong

unread,
Jun 18, 2013, 11:29:32 AM6/18/13
to google-api...@googlegroups.com
And, when using "Web Application", if login with non-admin account, it's still not working for getting the member list of a group. Is this normal?

Aapo Talvensaari

unread,
Jun 18, 2013, 11:42:27 AM6/18/13
to google-api...@googlegroups.com
Yes, I tested service account with (if I know correctly) Prediction API, and it worked just fine. But it seems Google hasn't yet implemented Service Account support for Admin SDK's Directory Service. When they do that, I think it will work just fine, as all the code to handle authentication is outside of my contribution (in default download).

I have not extensively tested this using other than admin account. I think there should be a way to get list of members in a group if user has privileges for that. Have you checked gtoups permissions? There is in "Custom" category "View members list" permission that can be granted for Owners / Members / Domain users / Anyone. You will need to have permission to at least to this scope: https://www.googleapis.com/auth/admin.directory.group.readonly.

I have started to add API docs to code, but it's not yet ready. I will publish new version when it is.


Regards
Aapo


To unsubscribe from this group and all its topics, send an email to google-api-php-c...@googlegroups.com.

Chak Ming Wong

unread,
Jun 18, 2013, 12:42:22 PM6/18/13
to google-api...@googlegroups.com
Thanks for prompt reply and share the source code! 

I've checked the permission and it has https://www.googleapis.com/auth/admin.directory.group.readonly. It works well when I login as privileged user, but not working if I login as normal users(without admin privileges for that domain).

BR,
Ming

Aapo Talvensaari於 2013年6月18日星期二UTC+8下午11時42分27秒寫道:
Yes, I tested service account with (if I know correctly) Prediction API, and it worked just fine. But it seems Google hasn't yet implemented Service Account support for Admin SDK's Directory Service. When they do that, I think it will work just fine, as all the code to handle authentication is outside of my contribution (in default download).

I have not extensively tested this using other than admin account. I think there should be a way to get list of members in a group if user has privileges for that. Have you checked gtoups permissions? There is in "Custom" category "View members list" permission that can be granted for Owners / Members / Domain users / Anyone. You will need to have permission to at least to this scope: https://www.googleapis.com/auth/admin.directory.group.readonly.

I have started to add API docs to code, but it's not yet ready. I will publish new version when it is.


Regards
Aapo
On Tue, Jun 18, 2013 at 6:00 PM, Chak Ming Wong <chakm...@gmail.com> wrote:
is "Service Account" doesn't work for Admin SDK? I try a lot of time but everything works fine with "Web Application" but not "Service Account".

Ming

Aapo Talvensaari於 2013年6月14日星期五UTC+8上午4時08分37秒寫道:
Thanks Aaron,

Please let me know if you hit any bugs. Meanwhile I try to find some time to add PHPDocs to the code. Your kind worlds encourages me to make it even better. Hopefully at some point it is good enough to be included in official package, but that is beyond me.


Regards
Aapo
On Thu, Jun 13, 2013 at 10:17 PM, Aaron Montana <aaron....@atomicaxis.com> wrote:
Thanks a ton for this - I was hunting for exactly this after seeing that Google hadn't released a PHP library.

As a side note, it might be worth noting that the access token must be tied to a user who is also an Administrator of the Google Apps domain - it took me some time to figure that out.

 Jørund is definitely right, prepare for massive internet fame. I'll chime in if I find any bugs. 


Thanks again!

Aaron Montana

--
You received this message because you are subscribed to a topic in the Google Groups "google-api-php-client" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/google-api-php-client/LM-mwmuZe7I/unsubscribe.

To unsubscribe from this group and all its topics, send an email to google-api-php-client+unsubscri...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.
 
 

Aapo Talvensaari

unread,
Jun 18, 2013, 1:49:10 PM6/18/13
to google-api...@googlegroups.com

Ok. Thanks for the info. It would be nice if someone at Google could clarify this issue, and whether there is a problem in my code, or is admin account a requirement. If you get it working, please let us know.

Regards
Aapo

To unsubscribe from this group and all its topics, send an email to google-api-php-c...@googlegroups.com.
Message has been deleted

Aapo Talvensaari

unread,
Jul 11, 2013, 11:23:31 AM7/11/13
to google-api...@googlegroups.com
Just to let you all know Lluís Faja Costa sent me email about how to use Service Accounts succesfully. This is great stuff. Here is Lluis' mail:

---

Hi all

I confirm that Admin SDK works in OAut2 Services Account scenario. The trick is to add your google apps administrator or other domain account when instantiate Google_AssertionCredentials.

Here is the relevant piece of code

$key = file_get_contents(KEY_FILE);
$auth = new Google_AssertionCredentials(SERVICE_ACCOUNT_NAME, $scopes, $key, 'notasecret', 'http://oauth.net/grant_type/jwt/1.0/bearer', 'your-admin-account');

$client = new Google_Client();
$client->setApplicationName("Google Apps Sample");
$client->setUseObjects(true);
$client->setAssertionCredentials($auth);

$service = new Google_DirectoryService($client);
$results = $service->groups->listGroups(array('domain' => 'your-domain'));
print '<h2>Response Result:</h2><pre>' . print_r($results, true) . '</pre>';

Thanks a lot Aapo for your contribution
It will save me a lot of time

Regards, Lluís

---


Give respect to Lluis!!!

I'm half way through adding API documentation to source code. I will post it here when done.


Regards
Aapo

David Henner

unread,
Jul 11, 2013, 12:26:02 PM7/11/13
to google-api...@googlegroups.com
What does "your-admin-account" refer to?  I am trying to do this with the ruby-api.   https://github.com/google/google-api-ruby-client

Dave

Aaron Montana

unread,
Jul 11, 2013, 12:29:27 PM7/11/13
to google-api...@googlegroups.com
Awesome work guys! I'll be trying this out soon -

@David Henner - I think, correct me if I'm wrong, it really just means
Admin Account privileged user name...

Aapo Talvensaari

unread,
Jul 16, 2013, 12:15:32 PM7/16/13
to google-api...@googlegroups.com
Hi All,

Here is a new version of Directory Service API implementation in PHP. This time I have added API documentation, and also found our one missing property in on class. As always, please let me know if there are any errors in code.

A few things to consider:
- Google_DirectoryService.php has some naming conflicts with some other contrib libraries.
- UserPhotos does not currently encode the photoData (you have to do it on your own). This is because I didn't find an implementation in Google's PHP APIs to do that, and I would like the encoding utility to exists outside my implementation (there must be other uses for it for other implementers to benefit).

So here you are!

Regards
Aapo
Google_DirectoryService.php

Aapo Talvensaari

unread,
Jul 16, 2013, 6:51:53 PM7/16/13
to google-api...@googlegroups.com
It looks like Google has now included their own version of Directory Service API in their SVN repository:
and

Interesting piece from that code is:
/* array(Google_string) */

I'm not sure what that is. It seems wrong to me, but I don't know all the internals. They seemingly didn't reuse any of my code, which is sad considering this page:

But hey, there is an official (less documented) version of this same thing made by Google now.


Regards
Aapo


PS. Question to Google, why do you have this group if you are not following or contributing to it  (seriously, we want to talk to you!)?

Silvano Luciani

unread,
Jul 16, 2013, 7:30:46 PM7/16/13
to google-api...@googlegroups.com
Hi Aapo,

first of all thanks for your contributions, and sorry for not being able to reply sooner.

Regarding your question: why didn't we reuse any of your code? Well, when it comes to service classes, it's hard for us to do so.
This client library is based on the Google APIs Discovery Service (https://developers.google.com/discovery/), which means that we don't manually write each service class; instead, we run a script against the discovery document of a certain APIs, and the script generates the code for the service class. This process has several advantages (e.g. it makes easier to update the service classes); one disadvantage is that it makes hard for use to accept external contributions to a specific service class, because they would be overwritten the next time the script is executed to update the service class.

Thanks,
Silvano

Aapo Talvensaari

unread,
Jul 17, 2013, 12:25:41 AM7/17/13
to google-api...@googlegroups.com
Hi Silvano,

Thank you for explaining this. I thought that could be the case. I even tinkered about making automated script to do exactly that. I wasn't aware of this:

But I must have read something about that discovery service, but then probably just ignored it. Is this service class generating script included in the repository?

Is it so that not all of your APIs are part of this discovery service, or what was the reason not to include it before?


Regards
Aapo

Silvano Luciani

unread,
Jul 18, 2013, 6:17:52 PM7/18/13
to google-api...@googlegroups.com
Hi and sorry again! :D

The script is not included in the repository, but if you want to try to build your own client library you can find useful information here:

Some of our APIs are not part of the discovery service, basically the ones that you can find in this list:

The reason why Directory Service was not included before is a, well, a bug in my scripts :D

Silvano Luciani

unread,
Jul 19, 2013, 6:24:32 PM7/19/13
to google-api...@googlegroups.com
I've just found out that we have actually released that code. You can find it in this project:

Dan Englender

unread,
Jul 25, 2013, 5:07:37 PM7/25/13
to google-api...@googlegroups.com
I was trying to test out this code in this post with a services account but am consistently getting an error of:  Uncaught exception 'Google_AuthException' with message 'Error refreshing the OAuth2 token, message: '{  "error" : "invalid_grant" }

A quick Google search suggests resyncing with NTP time, but that doesn't cure the issue.

Has anyone encountered this or have any ideas?

Thanks,
-Dan

Lluís Faja Costa

unread,
Jul 26, 2013, 1:30:20 AM7/26/13
to google-api...@googlegroups.com
The code is extremely simple. Please revise the setups in both consoles: 

1) Google API console

2) Google Apps Admin console
API client: <Client ID> of above Google API console
API scopes: same scopes of your script

And in your code 
SERVICE_ACCOUNT_NAME = <Email address> of Google API console
KEY_FILE = ...

and try first with your Google apps domain administrator

Lluís

Dan Englender

unread,
Jul 26, 2013, 9:47:52 AM7/26/13
to google-api...@googlegroups.com
It seemed pretty simple, that's why I was surprised I couldn't get it to work.  I've verified all the components, but still receive the same error.  Here's what I have set up:

Google API Account
Service account

Google Apps API Settings:


PHP Code:
XXXXXXXX is the API ID
ZZZZZZZ.org is the google apps domain
YYY...@ZZZZZZ.org is a super admin of that domain


 <?php
  require_once '/PATH/TO/google-api-php-client/src/Google_Client.php';
  require_once '/PATH/TO/google-api-php-client/src/contrib/Google_DirectoryService.php';

$key = file_get_contents('/PATH/TO/private.key');
$auth = new Google_AssertionCredentials('13XXXXXXXXXXX.apps.googleusercontent.com', $scopes, $key, 'notasecret', 'http://oauth.net/grant_type/jwt/1.0/bearer', 'YYYY...@ZZZZZZZ.org');

$client = new Google_Client();
$client->setApplicationName("Application Name");
$client->setUseObjects(true);
$client->setAssertionCredentials($auth);

$service = new Google_DirectoryService($client);
$results = $service->groups->listGroups(array('domain' => 'ZZZZZZZ.org'));
print '<h2>Response Result:</h2><pre>' . print_r($results, true) . '</pre>';
?>

Lluís Faja Costa

unread,
Jul 26, 2013, 2:15:05 PM7/26/13
to google-api...@googlegroups.com
Hi Dan

The problem could be when instantiate the Google_AssertionCredentials
You are using the <Client ID> and you must use the <Email address>

Lluís

Dan Englender

unread,
Jul 26, 2013, 2:28:43 PM7/26/13
to google-api...@googlegroups.com
Lluís -

You're a life-saver.  That made the difference.  Thank you.

-Dan


Corey Jones

unread,
Jul 26, 2013, 2:33:01 PM7/26/13
to google-api...@googlegroups.com
Yay thanks Lluís and Dan you guys are the best. I've been trying to get this to work for weeks. Thank you soooooo much
Message has been deleted

Bettina Wagenknecht

unread,
Sep 6, 2013, 9:47:53 AM9/6/13
to google-api...@googlegroups.com
Thanks a lot. It works perfect displaying a list of groups and retrieving users from the admin account. How would be the code to insert a new user?

Regards, Bettina
Message has been deleted
Message has been deleted

Corey Jones

unread,
Sep 12, 2013, 10:02:10 AM9/12/13
to google-api...@googlegroups.com
$userInstance = new Google_User();
$nameInstance = new Google_UserName();

$nameInstance -> setGivenName($givenName);
$nameInstance -> setFamilyName($familyName);

$userInstance -> setName($nameInstance);
                $userInstance -> setHashFunction("MD5");
$userInstance -> setPrimaryEmail($userEmail);
$userInstance -> setPassword(hash_hmac("md5", $password, "secret"));
$createUserResult = $serviceInstance -> users -> insert($userInstance);


this is what im trying to do...but its not working either actually. anyone see what im doing wrong?

Corey Jones

unread,
Sep 12, 2013, 10:09:34 AM9/12/13
to google-api...@googlegroups.com
And i figured it out.....
change
$userInstance -> setPassword(hash_hmac("md5", $password, "secret"));
to
$userInstance -> setPassword(hash("md5", $password));

Victor Perez

unread,
Nov 9, 2013, 2:09:46 AM11/9/13
to google-api...@googlegroups.com
Mr. Aapo,

I consider myself a pretty good Googler when it comes to searching for things, but it took me months to find a proper way to use the new Admin SDK with my PHP webapp. I consider myself still very n00b when compared to you guys, but my webapp is pretty intricate. Being able to manipulate Google accounts from within my site has been a dream. Your code is so easy to follow and it actually worked.

The one thing I can't understand to do is how to use the code for automatic Admin functions; as in, server to server. So that the user doesn't have to log in, or the user doesn't have to be even part of the domain. Something like: I have a user agreement. Upon signing the agreement, your student's account is moved to another Suborg. Or a routing Cron job that runs on it's own and manipulates a accounts.

If there is somewhere I can follow a Step by step example, that would be great. I tried to download the p12 file that Google provides for Service accounts, but I couldn't find how to properly set that up on my Ubuntu server (AWS EC2). And really, even if I uploaded it there, not sure where I could have gone from there either.

Maybe I'm asking for way too much, but any helpful guide or helpful point in a direction, I'd appreciate it. If this isn't helpful to the discussion of the group, you can send me a message directly. It's a longshot to ask, but figured I'd try.

Again, great SDK file!

- Victor

ewa...@pagerduty.com

unread,
Nov 12, 2013, 11:29:41 PM11/12/13
to google-api...@googlegroups.com
@David Henner (or anyone else),

I'm curious if you got this working with the Ruby API client.  I'm specifically trying to use a service account (with a private key) to determine whether a user is a member of a group, using the Admin SDK API (a.k.a. Directory API).  I've succeeded using the Ruby client when doing the Web flow, but not yet with a service account.  When I try to pass a super-admin account as the "person" or "username" parameter to the Signet::OAuth2::Client constructor, it fails in different ways.

Eric

samuel lilleker

unread,
Nov 15, 2013, 11:54:24 AM11/15/13
to google-api...@googlegroups.com
@Victor Perez

I am also keen to find out about server to server functionality! We are looking at creating a provisioning service so users from our various websites can purchase access to our e-learning platform built with Google sites.

ewa...@pagerduty.com

unread,
Nov 15, 2013, 11:57:43 AM11/15/13
to google-api...@googlegroups.com
For anyone who is interested in the same problem in the context of Ruby, the solution was to modify the Google Signet client to accept a "sub" parameter.  The parameter should be set to the email address of a super-admin.  Once I did this, I was able to complete a query against the Directory API using a service account.


Eric
Reply all
Reply to author
Forward
0 new messages