Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google Docs API - Impersonate User File Download

Using the Google Docs Java API with a Google Apps account, is it possible to impersonate a user and download a file?

When I run the program below, it is clearly logging on to the domain and impersonating the user because it retrieves the details of one of the files and prints out the file title. However, when it tries to download the file, a ServiceForbiddenException is thrown.

If it is not possible with the Java API, does anyone know if it is possible for my program to write an HTTP request to download the file using the Protocol API?

public class AuthExample {

private static DocsService docService = new DocsService("Auth Example");

public static void main(String[] args)
    throws Exception
{
    String adminUser = args[0];
    String adminPassword = args[1];
    String authToken = args[2];
    String impersonatedUser = args[3];

    loginToDomain(adminUser, adminPassword, authToken);

    URL url = new URL( "https://docs.google.com/feeds/" + impersonatedUser + "/private/full" );
    DocumentListFeed feed = docService.getFeed(url, DocumentListFeed.class);

    DocumentListEntry entry = feed.getEntries().get(0);

    String title = entry.getTitle().getPlainText();
    System.out.println( title );

    String type = entry.getType();
    if ( type.equals("document") )
    {
        String encodedAdminUser = URLEncoder.encode(adminUser);
        String resourceId = entry.getResourceId();
        String resourceIdNoPrefix = resourceId.substring( resourceId.indexOf(':')+1 );

        String downloadUrl =
                "https://docs.google.com/feeds/download/documents/Export" +
                "?xoauth_requestor=" + encodedAdminUser +
                "&docId=" + resourceIdNoPrefix +
                "&exportFormat=doc";

        downloadFile( downloadUrl, title + ".doc" );
    }
}

private static void loginToDomain(String adminUser, String adminPassword, String authToken)
        throws OAuthException, AuthenticationException
{
    String domain = adminUser.substring( adminUser.indexOf('@')+1 );

    GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters();
    oauthParameters.setOAuthConsumerKey(domain);
    oauthParameters.setOAuthConsumerSecret(authToken);
    oauthParameters.setOAuthType(OAuthType.TWO_LEGGED_OAUTH);
    oauthParameters.setScope("https://docs.google.com/feeds/ http://spreadsheets.google.com/feeds/ http://docs.googleusercontent.com/");

    docService.useSsl();
    docService.setOAuthCredentials(oauthParameters, new OAuthHmacSha1Signer());
    docService.setUserCredentials(adminUser, adminPassword);
}


// Method pasted directly from Google documentation
public static void downloadFile(String exportUrl, String filepath)
        throws IOException, MalformedURLException, ServiceException
{
    System.out.println("Exporting document from: " + exportUrl);

    MediaContent mc = new MediaContent();
    mc.setUri(exportUrl);
    MediaSource ms = docService.getMedia(mc);

    InputStream inStream = null;
    FileOutputStream outStream = null;

    try {
        inStream = ms.getInputStream();
        outStream = new FileOutputStream(filepath);

        int c;
        while ((c = inStream.read()) != -1) {
            outStream.write(c);
        }
    } finally {
        if (inStream != null) {
            inStream.close();
        }
        if (outStream != null) {
            outStream.flush();
            outStream.close();
        }
    }
}

}

like image 686
user1240714 Avatar asked Feb 29 '12 17:02

user1240714


1 Answers

Impersonation will work as intended if you use Oauth2 with ServiceAccounts

like image 197
Jerome Avatar answered Oct 17 '22 10:10

Jerome