Question

I'm attempting to use the Google Sites API to retrieve a list of all of my domain's sites, not just the sites that the currently authenticated user has read-write/owner access to. As far as I can tell, there is no facility to handle this in the current API.

However, according to the current API reference (https://developers.google.com/google-apps/sites/docs/1.0/reference/) I can use a parameter to include all sites that a user can at least 'view'. This combined with using a domain admin user seems like it would handle my requirements.

Unfortunately, I can't get this to work. I'm using a 2-legged oAuth approach, almost identical to the folllowing example here: http://gdatatips.blogspot.ca/search/label/oauth except that I'm using the sites feed.

I can successfully specify the xoauth_requestor_id=my.admin.user@domain.com and retrieve a list of sites. But if I add the 'include-all-sites' parameter to my feed url, ie:

https://sites.google.com/feeds/site/mydomain.com/?include-all-sites=true

I receive the following error:

Unknown authorization header Error 401

Is there another way to do this? I can't find any documentation or working examples that use the 'include-all-sites' parameter.

Update:

Here's the header output:

GET /feeds/site/mydomain.com/?include-all-sites=true HTTP/1.1
Host: sites.google.com
Accept: */*
Authorization: OAuth oauth_version="1.0", oauth_nonce="831c013d3d4c9c13b149dfd21e9b48bd", oauth_timestamp="1337274463", oauth_consumer_key="mydomain.com", xoauth_requestor_id="user%mydomain.com", oauth_signature_method="HMAC-SHA1", oauth_signature="%2Bq24MoAQJL4vCcz%2BLD1P1Cy4X48%3D"
Content-Type: application/atom+xml
GData-Version: 1.4

HTTP/1.1 401 Unknown authorization header
WWW-Authenticate: GoogleLogin realm="http://www.google.com/accounts/ClientLogin", service="jotspot"
Content-Type: text/html; charset=UTF-8
Date: Thu, 17 May 2012 17:07:43 GMT
Expires: Thu, 17 May 2012 17:07:43 GMT
Cache-Control: private, max-age=0
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Server: GSE
Transfer-Encoding: chunked
Was it helpful?

Solution

Turns out I had an issue with my implementation of the OAuth Libraries. This is all working as expected now. Below is my working code..

This example requires that you have the Google APIs Client Library for PHP: http://code.google.com/p/google-api-php-client/

$CONSUMER_KEY = "yourdomain.com";
$CONSUMER_SECRET = "yoursecret";
$consumer = new apiClientOAuthConsumer($CONSUMER_KEY, $CONSUMER_SECRET, NULL);

$user = 'admin.user@yourdomain.com';
$base_feed = "https://sites.google.com/feeds/site/$CONSUMER_KEY/";
$params = array('max-results' => 50, 'xoauth_requestor_id' => $user, 'include-all-sites' => 'true');  
$request = apiClientOAuthRequest::from_consumer_and_token($consumer, NULL, "GET", $base_feed, $params);

$request->sign_request(new apiClientOAuthSignatureMethod_HMAC_SHA1(), $consumer, NULL);

$url = $base_feed . '?' . implode_assoc('=', '&', $params); 

$result = send_request($request->get_normalized_http_method(), $url, $request->to_header());

The code above uses the below utility functions (from: http://gdatatips.blogspot.ca/search/label/oauth)

/** 
 * Makes an HTTP request to the specified URL 
 * @param string $http_method The HTTP method (GET, POST, PUT, DELETE) 
 * @param string $url Full URL of the resource to access 
 * @param string $auth_header (optional) Authorization header 
 * @param string $postData (optional) POST/PUT request body 
 * @return string Response body from the server 
 */  
function send_request($http_method, $url, $auth_header=null, $postData=null) {  
  $curl = curl_init($url);  
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);  
  curl_setopt($curl, CURLOPT_FAILONERROR, false);  
  curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);  

  switch($http_method) {  
    case 'GET':  
      if ($auth_header) {  
        curl_setopt($curl, CURLOPT_HTTPHEADER, array($auth_header));   
      }  
      break;  
    case 'POST':  
      curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/atom+xml',   
                                                   $auth_header));   
      curl_setopt($curl, CURLOPT_POST, 1);                                         
      curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);  
      break;  
    case 'PUT':  
      curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/atom+xml',   
                                                   $auth_header));   
      curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $http_method);  
      curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);  
      break;  
    case 'DELETE':  
      curl_setopt($curl, CURLOPT_HTTPHEADER, array($auth_header));   
      curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $http_method);   
      break;  
  }  
  $response = curl_exec($curl);  
  if (!$response) {  
    $response = curl_error($curl);  
  }  
  curl_close($curl);  
  return $response;  
}  

/** 
 * Joins key:value pairs by inner_glue and each pair together by outer_glue 
 * @param string $inner_glue The HTTP method (GET, POST, PUT, DELETE) 
 * @param string $outer_glue Full URL of the resource to access 
 * @param array $array Associative array of query parameters 
 * @return string Urlencoded string of query parameters 
 */  
function implode_assoc($inner_glue, $outer_glue, $array) {  
  $output = array();  
  foreach($array as $key => $item) {  
    $output[] = $key . $inner_glue . urlencode($item);  
  }  
  return implode($outer_glue, $output);  
}

I hope this helps anyone else who may need similar functionality!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top