Search code examples
service-accountsgoogle-classroom

Google Classroom using Service Account with domain-wide-delegation


Should a service account created and given domain-wide-delegation be able to access all courses and assignments in my doamin? I am the domain admin and created the service account. However, when I execute the code it does not return any results. When I run the same request directly from Reference page, it returns data.

    <?php
/*
 * Copyright 2013 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
include_once __DIR__ . '/../vendor/autoload.php';
include_once "templates/base.php";
echo pageHeader("Service Account Access");

//putenv('/GOOGLE_APPLICATION_CREDENTIALS = service-account-credentials.json');

/************************************************
  Make an API request authenticated with a service
  account.
 ************************************************/
$client = new Google_Client();
/************************************************
  ATTENTION: Fill in these values, or make sure you
  have set the GOOGLE_APPLICATION_CREDENTIALS
  environment variable. You can get these credentials
  by creating a new Service Account in the
  API console. Be sure to store the key file
  somewhere you can get to it - though in real
  operations you'd want to make sure it wasn't
  accessible from the webserver!
  Make sure the Books API is enabled on this
  account as well, or the call will fail.
 ************************************************/
putenv('GOOGLE_APPLICATION_CREDENTIALS= ../../../public/service-account-credentials.json');
$client->useApplicationDefaultCredentials();


if ($credentials_file = checkServiceAccountCredentialsFile()) {
  // set the location manually
  $client->setAuthConfig($credentials_file);
} elseif (getenv('GOOGLE_APPLICATION_CREDENTIALS')) {
  // use the application default credentials
  $client->useApplicationDefaultCredentials();
} else {
  echo missingServiceAccountDetailsWarning();
  return;
}
$client->setApplicationName("Google-Classroom");
$client->setScopes(['https://www.googleapis.com/auth/classroom.courses.readonly']);
$service = new Google_Service_Classroom($client);
/************************************************
  We're just going to make the same call as in the
  simple query as an example.
 ************************************************/
$optParams = array('pageSize' => 10,'studentId'=>'[email protected]');
$results = $service->courses->listCourses($optParams);


if (count($results->getCourses()) == 0) {
  print "No courses found.\n";
} else {

echo "<h3>Results Of Call:</h3>";
 foreach ($results as $course){
  echo $course->getName();
  echo"<br />";
 }
}

 pageFooter(__FILE__); 
 ?>

Solution

  • Domain-wide delegation requires you to specify the domain user you wish to act-as. It also does not work with application default credentials (the service accounts builtin to your AppEngine and Compute Engine services), you need to manually create the SA in your project. Assuming you're using a SA you created (the credentials file), try adding:

    $user_to_impersonate = "[email protected]";
    $client->setSubject($user_to_impersonate);