Search code examples
c#asp.netoauthgdata-apigoogle-docs

Accessing Google Docs with GData


Working Platform: ASP.NET 4.0 C# ( Framework Agnostic )

Google GData is my dependency

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

I have two pages Auth and List.

Auth redirects to Google Server like this

public ActionResult Auth()
{
    var target = Request.Url.ToString().ToLowerInvariant().Replace("auth", "list");
    var scope = "https://docs.google.com/feeds/";
    bool secure = false, session = true;

    var authSubUrl = AuthSubUtil.getRequestUrl(target, scope, secure, session);
    return new RedirectResult(authSubUrl);
}

Now it reaches the List Page if Authentication is successful.

public ActionResult List()
{
    if (Request.QueryString["token"] != null)
    {
        String singleUseToken = Request.QueryString["token"];

        string consumerKey = "www.blahblah.net";
        string consumerSecret = "my_key";
        string sessionToken = AuthSubUtil.exchangeForSessionToken(singleUseToken, null).ToString(); 

        var authFactory = new GOAuthRequestFactory("writely", "qwd-asd-01");
        authFactory.Token = sessionToken;
        authFactory.ConsumerKey = consumerKey;
        authFactory.ConsumerSecret = consumerSecret;
        //authFactory.TokenSecret = "";
        try
        {
            var service = new DocumentsService(authFactory.ApplicationName) { RequestFactory = authFactory };

            var query = new DocumentsListQuery();
            query.Title = "project";

            var feed = service.Query(query);
            var result = feed.Entries.ToList().ConvertAll(a => a.Title.Text);
            return View(result);
        }
        catch (GDataRequestException gdre)
        {
            throw;
        }
    }
}

This fails at the line var feed = service.Query(query); with the error

Execution of request failed: https://docs.google.com/feeds/default/private/full?title=project

The HttpStatusCode recieved on the catch block is HttpStatusCode.Unauthorized

What is wrong with this code? Do I need to get TokenSecret? If so how?


Solution

  • Used the 3-legged OAuth in the Google Data Protocol Client Libraries

    Sample Code

    string CONSUMER_KEY = "www.bherila.net";
    string CONSUMER_SECRET = "RpKF7ykWt8C6At74TR4_wyIb";
    string APPLICATION_NAME = "bwh-wssearch-01";
    
    string SCOPE = "https://docs.google.com/feeds/";
    
    public ActionResult Auth()
    {
        string callbackURL = String.Format("{0}{1}", Request.Url.ToString(), "List");
        OAuthParameters parameters = new OAuthParameters()
        {
            ConsumerKey = CONSUMER_KEY,
            ConsumerSecret = CONSUMER_SECRET,
            Scope = SCOPE,
            Callback = callbackURL,
            SignatureMethod = "HMAC-SHA1"
        };
    
        OAuthUtil.GetUnauthorizedRequestToken(parameters);
        string authorizationUrl = OAuthUtil.CreateUserAuthorizationUrl(parameters);
        Session["parameters"] = parameters;
        ViewBag.AuthUrl = authorizationUrl;
        return View();
    }
    
    public ActionResult List()
    {
        if (Session["parameters"] != null)
        {
            OAuthParameters parameters = Session["parameters"] as OAuthParameters;
            OAuthUtil.UpdateOAuthParametersFromCallback(Request.Url.Query, parameters);
    
            try
            {
                OAuthUtil.GetAccessToken(parameters);
    
                GOAuthRequestFactory authFactory = new GOAuthRequestFactory("writely", APPLICATION_NAME, parameters);
    
                var service = new DocumentsService(authFactory.ApplicationName);
                service.RequestFactory = authFactory;
    
                var query = new DocumentsListQuery();
                //query.Title = "recipe";
    
                var feed = service.Query(query);
                var docs = new List<string>();
                foreach (DocumentEntry entry in feed.Entries)
                {
                    docs.Add(entry.Title.Text);
                }
                //var result = feed.Entries.ToList().ConvertAll(a => a.Title.Text);
                return View(docs);
            }
            catch (GDataRequestException gdre)
            {
                HttpWebResponse response = (HttpWebResponse)gdre.Response;
    
                //bad auth token, clear session and refresh the page
                if (response.StatusCode == HttpStatusCode.Unauthorized)
                {
                    Session.Clear();
                    Response.Write(gdre.Message);
                }
                else
                {
                    Response.Write("Error processing request: " + gdre.ToString());
                }
                throw;
            }
        }
        else
        {
            return RedirectToAction("Index");
        }
    }
    

    This 2-legged sample never worked for me for google docs.