There’s a lot of documentation on the Google Admin SDK API for both Java and Python, but since the PHP code is still in beta, it’s a bit harder to find details about it.  Here’s a compilation of all the steps I found necessary to get up and running with the Admin SDK using the PHP library.  All of the documentation can be found using a decent Google search, but I thought I’d compile them into one post in order to save someone a few searches.

Step 1 – Set Up API Service and Projects in Google’s API Console

I won’t go into too much detail here, since this is all well documented over at Google.  But this is the first step.  (If you don’t have Google Apps for Education, Business or Government, you won’t have all this available.)  API Console Link: https://console.developers.google.com Make sure to log in with your Administrator account, and then toggle the “Admin SDK” API from the list in the “APIs & auth” section in your new Project.

Admin SDK API

Step 2 – Set Up a Service Account

Once you’ve set up your project and enabled the Admin SDK API, you’ll need to set up a service account, which is also nicely documented here.  For clarity, I’ve added some screen shots.

Credentials > OAuth 2.0 > Client ID:

Selection_084

Create a “Service Account”:

Service Account

Now just follow the instructions for retrieving your P12 key and installing it to your server.

Step 3 – Delegate Domain Wide Authority

This one is also nicely documented at Google, but if you’re speed reader, you might overlook that this is actually happening in the Admin Console, and not anywhere in the API/Developer Console.  While the Google Documentation has the steps, here are a few screen shots for clarity.

Security > Advanced Settings > Manage:

Selection_094

Credentials entered here are the Client Name (e.g. xxxxxx-123xyzMiB.apps.googleusercontent.com) and not the Client ID – nor will it be a URL, as the form suggests.   Also, the scopes you’ll want here are https://www.googleapis.com/auth/admin.directory.user, https://www.googleapis.com/auth/admin.directory.group.  Separate them by commas, and add as many scopes as you need for each of the APIs you have enabled.

Selection_095

Step 3.5 – Wait

Seriously.  When I set this up, I already had downloaded the PHP API classes and had pulled out the “service example” for testing, but hadn’t pushed the delegation through – because I overlooked that bit of documentation at first.  So I added the steps above and hit refresh on my Service Example test, but kept getting an invalid credentials error – or a “Not authorized to use this API” error – and so I thought I had done something wrong.  I finally decided to take a break and do something else.  When I came back to it several hours later, I ran the script so that I could see the error and start debugging again, and it just worked.  So, there’s some lag time between setting up the delegation to your service account, and being able to actually authenticate with it using the code, but I’m unsure what the time frame is, since my break from working on this was a few hours.

Step 4 – Search for a User with PHP

Now that all the other settings are taken care of, set up the PHP Google Admin SDK API on your server, and make a copy of the “service-account.php” script in the /examples/ directory and call it “user-retrieve.php”  The standard Google_Auth_AssertionCredentials() need to be changed here, because we are using a delegated account.  Here’s Google’s documentation on that, and here’s a snippet of code for impersonating your admin user on __construct, rather than setting the “sub”:


$user_to_impersonate = 'adminaccount@example.com';
$scopes = array('https://www.googleapis.com/auth/admin.directory.user');
$cred = new Google_Auth_AssertionCredentials(
     $service_account_name,
     $scopes,
     $key,
     'notasecret', // Default P12 password
     'http://oauth.net/grant_type/jwt/1.0/bearer', // Default grant type
     $user_to_impersonate
);

Once you’ve gotten the connector set up, you can search for a user by creating a Google_Service_Directory object.  Since the object returned is a JSON object, you can directly access the user attributes listed in the User API Documentation for retrieiving a user:


$dir = new Google_Service_Directory($client);
$email = "possiblities@example.com";
$r = $dir->users->get($email);
if($r) {
     echo "Name: ".$r->name->fullName."<br/>";
     echo "Suspended?: ".(($r->suspended === true) ? 'Yes' : 'No')."<br/>";
     echo "Org/Unit/Path: ".$r->orgUnitPath."<br/>";
} else {
     echo "User does not exist: $email<br/>";
     // if the user doesn't exist, it's safe to create the new user
}

Step 5 – Create a Directory User Object and Push to Google

Creating a user is almost the same as retrieving the user.  Everything related to the Admin SDK is in the Directory class file, and in the instance of creating a user, we need to set several attributes that Google expects in the request.   Take a look at the JSON object in the Google Documentation, because that will help you setting the attributes in your code.  Looking at the Directory class, we can see that creating a user (line #2240 (users.insert)) requires the Google_Service_Directory_User object (defined on line #4406), and that setting a person’s name (setName ( line #4616)) requires the Google_Service_Directory_UserName object.  So, we can generate our user data and push to Google in the following manner.  If successful, Google returns a JSON object of the new user (essentially the same thing you would get for a user search request), which we can either display, or use in any other calls.  If you’re not checking for user existence before pushing, you’ll want to wrap the users->insert() method in try catch block.


$dir = new Google_Service_Directory($client);
// SET UP THE USER/USERNAME OBJECTS
$user = new Google_Service_Directory_User();
$name = new Google_Service_Directory_UserName();
$new_person = array();
// SET THE ATTRIBUTES
$name->setGivenName('Tester');
$name->setFamilyName('Testerton');
$user->setName($name);
$user->setHashFunction("SHA-1");
$user->setPrimaryEmail("testy.testerton@example.com");
$user->setPassword(hash("sha1","Testing123"));
// the JSON object shows us that externalIds is an array, so that's how we set it here
$user->setExternalIds(array("value"=>28790,"type"=>"custom","customType"=>"EmployeeID"));
result = $dir->users->insert($user);
echo "New user ".$result->primaryEmail." created successfully."

Thoughts

This was far easier to set up than I thought it would be (this write up took me longer than creating a user with the PHP Client).  In fact, the most difficult thing was not reading the documentation and thereby not realizing that I needed to delegate authority to my Service Account.  If I’d done that, and if I’d been a bit patient after setting up the delegated authority, this might have been a zero frustration set up.

At this point, my only frustration is that the Google autoloader doesn’t follow the PSR-0 format, which I am using in a FIG compliant framework, so at the present, I can do all I need, but only inside my automated scripts.  I’m going to do some noodling – and most likely some rewritng – to make these classes available from the framework’s own API layer so that our administrative users can create an account in our Account Management Interface, and have the locally created account also push to Google.

5 thoughts on “Google Admin SDK API with PHP

  1. Thanks so much.
    I did make the mistake of reading the documentation and trying to follow it. I was extremely frustrated. You threw me the couple bones I needed to get it working.
    The only thing I found was that I needed to use my Client ID in step 3.

    Once again THANK-YOU.

  2. Nevermind, Just had to make sure $r was declared with $r = new Google_Service_Directory_User(); set the unique_google_id like you did in your other article, and actually call the update function. Thanks so much for this article and feel free to remove all of my comments. 🙂

  3. Thanks for this information, Michael. I’m redeveloping an application in PHP that I originally put together in ColdFusion before the PHP client libraries were released, and this information is exactly what I needed. Much appreciated!

  4. It seems that, at least for me, the externalIds won’t add properly on creation of users. I can however later on update each user with the correct id. So in other words it errors, but silently.

  5. This is really helpful. I was able to create a backend API to add students to on the fly right from within our SIS. The only think lacking is the ability to add aliases to the user, which uses a different scope. I think I can figure it out, but would be helpful to see the actual calls needed to “set” the parameters, etc. Thanks, again!

Leave a Reply

Your email address will not be published. Required fields are marked *