using 0.1.8 with domains?

Help
2008-04-15
2013-05-21
  • Jim Carroll

    Jim Carroll - 2008-04-15

    Hi, I'm having trouble using domain="mydomain.com" with gmail.

    I'm not getting the cookies that libgmail needs, especially GMAIL_AT

    Running a simple example with LG_DEBUG=1 gives me:

    >pythonw -u "SslMailClient.py"
    Extracted cookie `GALX`
    Stored cookie `GALX` value `DOLmiVjJA8g`
    No messages found
    Traceback (most recent call last):
      File "SslMailClient.py", line 57, in <module>
        genericEmail("myusername@gmail.com", "Testing Apps", "If you're reading this, it's working")
      File "SslMailClient.py", line 50, in genericEmail
        ga.sendMessage(gmsg)
      File "C:\jimc\anl\PLUS\CyberBully\WebSite\cgi-bin\libgmail_anl.py", line 588, in sendMessage
        U_ACTION_TOKEN: self._getActionToken(),
      File "C:\jimc\anl\PLUS\CyberBully\WebSite\cgi-bin\libgmail_anl.py", line 563, in _getActionToken
        at = self._cookieJar._cookies[ACTION_TOKEN_COOKIE]          
    KeyError: 'GMAIL_AT'
    >Exit code: 1

    I mirrored the ?ui=1 fix in the GmailAccount _init_ like so:

            if self.domain:
                URL_LOGIN = "https://www.google.com/a/" + self.domain + "/LoginAction"
                URL_GMAIL = "https://mail.google.com/a/" + self.domain + "/?ui=1"

    But no luck...

     
    • Marina Zhurakhinskaya

      I created a patch do get the GMAIL_AT cookie and the page content with the e-mails for the domain accounts. However, this is a dead end, since the format of the page content is different, and needs to be parsed differently.

      It seems that it is much better to use IMAP to interact with Google Mail. One of the libgmail maintainers seems to be working on the new library called gmailimap, which even provides the same API as libgmail (though you don't need this if you were not using libgmail heavily in the first place). The project is here:
      http://gmailimap.wikidot.com
      It includes a link to the SourceForge project page. Also, here is a relevant discussion on the subject:
      http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=469331

      This library works just as well for the domain accounts. You just need to specify the full e-mail, and keep the same servers and ports ('imap_server' : 'imap.gmail.com', 'imap_port' : 993, 'smtp_server' : 'smtp.gmail.com', 'smtp_port' : 587). Yes, gmail.com servers work for the Google Apps For Your Domain accounts. In either case, the users might need to enable IMAP in their account settings.

      Feel free to take a look at
      http://svn.gnome.org/viewvc/bigboard/trunk/bigboard/gmailimap/
      for our local modifications of the gmailimap and for how we use it in the Mail widget for the GNOME Online Desktop:
      http://svn.gnome.org/viewvc/bigboard/trunk/bigboard/stocks/mail/MailStock.py

      Hope this helps.
      Marina

      Below is the patch for getting the GMAIL_AT cookie and the page content for the domain accounts, in case someone will decide to try to parse it:

      --- trunk/bigboard/stocks/mail/libgmail_patched.py    (original)
      +++ trunk/bigboard/stocks/mail/libgmail_patched.py    Wed May  7 19:51:55 2008
      @@ -84,6 +84,10 @@
           the embedded Javascript.
          
           """
      +    if LG_DEBUG:
      +        # This will print the page content we are about to parse to get the e-mails.
      +        # The current parsing does not work for what is returned for Google Apps For Your Domain accounts. 
      +        print "pageContent %s" % pageContent
           lines = pageContent.splitlines()
           data = '\n'.join([x for x in lines if x and x[0] in ['D', ')', ',', ']']])
           #data = data.replace(',,',',').replace(',,',',')
      @@ -141,8 +145,9 @@
           return result

      class SmartRedirectHandler(urllib2.HTTPRedirectHandler):
      -    def __init__(self, cookiejar):
      +    def __init__(self, cookiejar, extractCookies = False):
               self.cookiejar = cookiejar
      +        self.extractCookies = extractCookies

           def http_error_302(self, req, fp, code, msg, headers):
               # The location redirect doesn't seem to change
      @@ -152,6 +157,8 @@
                                   headers.getheader('Location'))
               if new_host:
                   req.add_header("Host", new_host.groups()[0])
      +        if self.extractCookies:
      +            self.cookiejar.extractCookies(headers)
               result = urllib2.HTTPRedirectHandler.http_error_302(
                   self, req, fp, code, msg, headers)             
               return result
      @@ -179,10 +186,15 @@
               # TODO: Do this all more nicely?
               for cookie in headers.getheaders('Set-Cookie'):
                   name, value = (cookie.split("=", 1) + [""])[:2]
      -            if LG_DEBUG: print "Extracted cookie `%s`" % (name)
      +            if LG_DEBUG:
      +                print "Extracted cookie `%s`" % (name)
                   if not nameFilter or name in nameFilter:
      -                self._cookies[name] = value.split(";")[0]
      -                if LG_DEBUG: print "Stored cookie `%s` value `%s`" % (name, self._cookies[name])
      +                cookie_value = value.split(";")[0]
      +                # do not overwrite the HID cookie when we get information that it is expired
      +                if not (name == "HID" and cookie_value == "EXPIRED"):
      +                   self._cookies[name] = cookie_value
      +                if LG_DEBUG: 
      +                    print "Stored cookie `%s` value `%s`" % (name, self._cookies[name])
                       if self._cookies[name] == "EXPIRED":
                           if LG_DEBUG:
                               print "We got an expired cookie: %s:%s, deleting." % (name, self._cookies[name])
      @@ -289,7 +301,7 @@
               """
               self.domain = domain
               if self.domain:
      -            URL_LOGIN = "https://www.google.com/a/" + self.domain + "/LoginAction"
      +            URL_LOGIN = "https://www.google.com/a/" + self.domain + "/LoginAction2"
                   URL_GMAIL = "http://mail.google.com/a/" + self.domain + "/?"
               else:
                   URL_LOGIN = GMAIL_URL_LOGIN
      @@ -306,10 +318,13 @@
                                         gmail_transport.ConnectHTTPSHandler(proxy = PROXY_URL),
                                         SmartRedirectHandler(self._cookieJar))
                   else:
      +                # processing of the Google Apps For Your Domain login requires extracting cookies
      +                # before redirects, so we pass self.domain for the extractCookies flag to the
      +                # SmartRedirectHandler
                       self.opener = urllib2.build_opener(
                                       urllib2.HTTPHandler(debuglevel=0),
                                       urllib2.HTTPSHandler(debuglevel=0),
      -                                SmartRedirectHandler(self._cookieJar))
      +                                SmartRedirectHandler(self._cookieJar, self.domain))
               elif state:
                   # TODO: Check for stale state cookies?
                   self.name, self._cookieJar = state.state
      @@ -331,8 +346,8 @@
                   data = urllib.urlencode({'continue': URL_GMAIL,
                                            'at'      : 'null',
                                            'service' : 'mail',
      -                                     'userName': self.name,
      -                                     'password': self.password,
      +                                     'Email': self.name,
      +                                     'Passwd': self.password,
                                            })
               else:
                   data = urllib.urlencode({'continue': URL_GMAIL,
      @@ -363,6 +378,14 @@
                   # We aren't concerned with the actual content of this page,
                   # just the cookie that is returned with it.
                   pageData = self._retrievePage(redirectURL)
      +        else:
      +            if LG_DEBUG:
      +                print "cookie jar has HID cookie: %s" % (self._cookieJar._cookies.has_key('HID')) 
      +            if self._cookieJar._cookies.has_key('HID'):
      +                req2 = urllib2.Request("https://mail.google.com/a/" + self.domain + "/?auth=" + self._cookieJar._cookies['HID'] + "husr=" + self.name + "@" + self.domain)
      +                pageData2 = self._retrievePage(req2)
      +            else:
      +                raise GmailLoginFailure("Login failed. (Wrong username/password?)")             

           def _retrievePage(self, urlOrRequest):
               """

       
    • Marina Zhurakhinskaya

       
    • Marina Zhurakhinskaya

      The latest libgmail (from CVS) works for Google Apps For Your Domain accounts. It was resolved in
      http://sourceforge.net/tracker/index.php?func=detail&aid=1937377&group_id=113492&atid=665330

       

Log in to post a comment.