0

I've been banging my head all day about this, did a ton of Google searches but to no avail. I am writing an application that downloads all of a user's Google Docs files to local disk. I have to do this for several users, and am only provided with an admin account (to be used via impersonation). The problem only applies to documents that the impersonated user has not authored/shared. In all cases, fetching title information works just fine (irrespective of the author & sharing settings). Downloading files authored by the impersonated account also works fine. However, downloading files authored by other users fails with HTTP 401 or 403 (permission denied). Can someone please tell me what I'm doing wrong? Below is a trimmed version of the code. Thanks!

    using System.IO;
using Google.GData.Documents;
using Google.GData.Client;
using Google.GData.Extensions;
using Google.Documents;


void impersonateAndGetAllUsersDocs()
{
    string applicationName = "myapp";
    string username = "admin@domain.com";
    string password = "adminPassword";
    string accountToImpersonate = "someOtherUser@domain.com";

    DocRequest = new DocumentsRequest(new RequestSettings(applicationName, username, password));

    DocumentsListQuery docQuery = new DocumentsListQuery();
    docQuery.Uri = new Uri(docQuery.Uri.ToString().Replace("/default/", "/" + accountToImpersonate + "/"));

    AtomFeed docFeed = DocRequest.Service.Query(query);
    //process every document in the feed
    foreach (AtomEntry docEntry in docFeed.Entries)
    {
        //this line works for all docs (irrespective of who the author is)
        string title = docEntry.Title.Text;

        Document doc = new Document()
        {
            AtomEntry = docEntry;
        };

        //the next line throws an exception with HTTP 401 or 403 (permission) if the author is not the impersonated account
        Stream queryStream = DocRequest.Download(doc, Document.DownloadType.html)

        //do something with the stream, such as write to local disk

        //all done, close the stream
        if (queryStream != null)
            queryStream.Close();
    }
}
Isa
  • 1

1 Answers1

0

The correct way to impersonate other users is to use 2-legged OAuth and add the xoauth_requestor_id parameter to the uri in order to specify the user to request data for.

This can be easily done with the .NET client library, as per the complete sample in the docs:

https://developers.google.com/gdata/docs/auth/oauth#2LeggedOAuth

Claudio Cherubino
  • 14,896
  • 1
  • 35
  • 42
  • Claudio - Thank you so much for your help. I am able to authenticate, but fetching the stream now returns an exception. Any idea? gDataRecirectException.message =Execution resulted in a redirect from https://www.google.com/accounts/ServiceLogin?service=wise&passive=1209600&continue=https://docs.google.com/feeds/download/spreadsheets/Export?key= at Google.GData.Client.GDataRequest.Execute() at Google.GData.Client.GDataGAuthRequest.Execute(Int32 retryCounter) at Google.GData.Client.GDataGAuthRequest.Execute() – Isa Jun 09 '12 at 23:13
  • PS, This is a spreadsheet, and I wrapped the DocumentService: GOAuthRequestFactory requestFactory = new GOAuthRequestFactory("writely", applicationName); requestFactory.ConsumerKey = CLIENT_ID; requestFactory.ConsumerSecret = CLIENT_SECRET; //1- Initialize the document DocRequest = new DocumentsRequest(new RequestSettings(applicationName)); DocRequest.Service = new DocumentsService(applicationName); DocRequest.Service.RequestFactory = requestFactory; – Isa Jun 09 '12 at 23:36
  • In order to download any kind of documents, including spreadsheets, you have to make sure the app is authorized for the following OAuth scopes: `https://docs.google.com/feeds/` `https://docs.googleusercontent.com/` `https://spreadsheets.google.com/feeds/` – Claudio Cherubino Jun 10 '12 at 04:04
  • Thanks Claudio. Unfortunately, I set the scope on the auth params but am still getting the redirect exception. Any idea how to handle this exception, or if there is something else that I need to do? Auth 1.0 doesn't seem to support a "Redirect URL". Not sure if that's the problem... Thanks! – Isa Jun 14 '12 at 21:07
  • You should explicitly authorize your app in the control panel to use 2-legged OAuth with the scopes you need. Check http://support.google.com/a/bin/answer.py?hl=en&answer=162106 for instructions – Claudio Cherubino Jun 14 '12 at 21:32