3
votes

I've been hitting my head to the wall for a few hours now, and I've tried to search all over the internet without success. My problem is I can't get the domain-wide delegation to work using Google API PHP Client (downloaded from GitHub). I assume authentication is working, because I'm able to read a calendar if the calendar has been shared to the service account's email (xxx@@developer.gserviceaccount.com).

I want to be able to read and write to all users calendars in our domain (Google Apps for Business) without having to share individual calendars to the service account. I'm able to read the calendars if I share my (or a somebody else's) calendar to the service account's email (xxx@@developer.gserviceaccount.com).

This is what I've done:

  1. I created a project in Developer Console.
  2. I created a service account and downloaded the .p12 file.
  3. I went to admin.google.com and added the newly created Client ID to Security --> Advanced settings --> Manage OAuth Client Access - and I added the newly created Client ID as the Cliend Name and added https://www.google.com/calendar/feeds/ as the Scope. After that I clicked "Authorize".
  4. Downloaded the latest Google API PHP Client.
  5. Modified the included example (service-account.php) to match what I wanted.
  6. When I run the script, I get a "404 Not found".
  7. After I share the calendar (via Gmail --> calendar) to the service account's email, it starts to work. <-- This is the step I don't want all users to do.

Here's the code:

<?php

session_start();
include_once "templates/base.php";

set_include_path("../src/" . PATH_SEPARATOR . get_include_path());
require_once 'Google/Client.php';
require_once 'Google/Service/Calendar.php';


$client_id = 'xxxx.apps.googleusercontent.com';
$service_account_name = '[email protected]';
$key_file_location = '/home/LALALA/public_html/xxxx-privatekey.p12';

echo pageHeader("Service Account Access");
if ($client_id == '<CLIENT_ID>'
    || !strlen($service_account_name)
    || !strlen($key_file_location)) {
  echo missingServiceAccountDetailsWarning();
}

$client = new Google_Client();

$client->setApplicationName("Calendar");
$client->setClientId($client_id);
$client->setClientSecret("notasecret");
//$bookService = new Google_Service_Books($client);
$service = new Google_Service_Calendar($client);

if (isset($_SESSION['service_token'])) {
  $client->setAccessToken($_SESSION['service_token']);
}
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
    $service_account_name,
    array('https://www.googleapis.com/auth/calendar'),
    $key
);

$client->setAssertionCredentials($cred);

if($client->getAuth()->isAccessTokenExpired()) {
  $client->getAuth()->refreshTokenWithAssertion($cred);
}
$_SESSION['service_token'] = $client->getAccessToken();

$events = $service->events->listEvents('[email protected]');

while(true) {
  foreach ($events->getItems() as $event) {
    echo $event->getSummary()."<br />";
  }
  $pageToken = $events->getNextPageToken();
  if ($pageToken) {
    $optParams = array('pageToken' => $pageToken);
    $events = $service->events->listEvents('primary', $optParams);
  } else {
    break;
  }
}


?>

So now I'm looking for some genius who could help me out with this. I'd be most grateful and even willing to make a small donation for someone who could get this to work.

1
I understand you would prefer not going through the sharing code path but would it be an option to get OAuth2 token for each individual and then update the data that way?luc
Hi Luc! Unfortunately that's something I'd rather not do. If I'm unable to find a better solution, then I have to bend in, but hopefully somebody knows how to figure this out, because I'd like to make the calendar management as straightforward as possible for the users.user3691661
I am interested in what can happen here , I too need to create one calendar to share with all the rest or write to all calendars certain events.Curious to know if someone has a solution to this, btw I cant use Google Apps for Businessv0d1ch

1 Answers

0
votes

Try this:

$cred = new Google_Auth_AssertionCredentials(
  $service_account_name,,
  array('https://www.googleapis.com/auth/calendar'),
  $key,
  'notasecret',
  'http://oauth.net/grant_type/jwt/1.0/bearer',
  '[email protected]'
);

Tell Google who is the person you want to impersonate, and then you will be able to operate everything of google calendar for this user.