A Ruby GData access lib for Marketplace Vendor Apps

Frustrated by oauth, the outdated gdata-ruby library, and experiencing general malaise about trying to plug your rails app into Google Enterprise Marketplace?

We’ve whipped up a small, simple convenience library to pull your Marketplace client’s data using oauth.

It’s released on Google Code as gdata-marketplace.

All you need to get started is:

  1. A Marketplace vendor account
  2. A test listing on Marketplace (you can use a “un-published” listing for testing)
  3. The Oauth consumer key and secret for the listed app (retrieved from the view listings page)
  4. An Google Apps account to test with

The library layers filters on the return data itself, so you can get raw stream access if you already have an XML solution, or you can use the included parse-to-OpenStruct layer. Finally, it implements a Memcache layer around the OpenStruct results.

The library does not have all the data hooks yet, but we will add to it as our integration expands (or until gdata-ruby is good alternative). Currently it is ideal for user and group provisioning (signup flow kinds of things). It also has calendar access. All access is currently pull (read-only).

Here’s an example:

# Example cached openstruct use:
# you can turn off cache by setting class var to nil, or
# by skipping the cache layer this way:
# m.data.users # basically, just insert .data in any request

require 'lib/gdata_marketplace'
m = GDataMarketplace::Client.new GOOGLE_CONSUMER_KEY, GOOGLE_CONSUMER_SECRET, 'you@appsclient.com'
# or, if you don't care about default user identity:
# m = GDataMarketplace::Client.new GOOGLE_CONSUMER_KEY, GOOGLE_CONSUMER_SECRET, 'appsclient.com'

allusers = m.users
allgroups = m.groups
auser = m.user "someone"
agroup = m.group "agroupid"
agroup = m.group m.groups.first.groupId
agroupsmembers = m.group_members m.groups.first.groupId

# Example raw XML string access:
# turn off auto response parse

m.response_format = :net_http # will return the actual response object
# get request body
xmlstring = (m.request_user_provision :all).body # for all users
xmlstring = (m.request_user_provision "username").body # for a user
# etc

Let us know what you think!

2 Comments on “A Ruby GData access lib for Marketplace Vendor Apps”

  1. Greg DeVore says:

    Thanks for posting this. I have had quite a headache in trying to get the list of users from a Google Apps site. I tried using your library but keep getting the following error:

    Net::HTTPUnauthorized 401 Unknown authorization header readbody=true>

    My code is:

    key = “the key I got from the marketplace”
    secret = “the secret I got from the marketplace”
    email = “the email address for the admin of the Google Apps domain I want to get data from”
    m = GDataMarketplace::Client.new(key, secret, email)
    @users = m.users

    Any ideas? Did you run into this at all?

    • Mark Wolgemuth says:

      Hi Greg,

      I certainly did. Unfortunately, the error messages are pretty opaque. I think Google is using these RESTful queries for simpler security policy enforcement at the URL level. Furthermore, they’ve chosen the strategy that any error message other than “not authorized” effectively leaks information (ie, allowing probing of what names are valid on a domain). So it’s hard to know what the problem is from the error message. Everything is either “bad request” or “not authorized”.

      In your example, though, there should really only be 2 possible issues:

      1) wrong key and secret. maybe you have multiple test listings? if I remember though, this generates “bad request” (could be mistaken) UPDATED: this actually returns “not authorized”, just tested.
      2) no domain privilege from google apps domain you want to access (definitely is “not authorized”)

      If your app is not “published” and the domain admin has not had the chance to approve your access, you will get this error.

      If you are in test mode, you need to “edit” your marketplace listing, then click preview, then click “add it now”, which will allow you to test by adding the privilege to any domain you might have access to, so you can grant access to yourself using the single sign on flow.

      My guess is your problem is number 2. Are you confident you (or the admin) has been trough the “grant access to” wizard for your app?

      The alternate possibility is that you have done the grant access flow successfully, but in your manifest you are missing the user provision api entry.

      So, plug in to the appropriate manixest.xml:

        <!-- Need access to the user provisioning -->
        <Scope id="usersProvisionFeed">
          <Reason>This provides a user list for synchronizing account users</Reason>