Google App Engine : Consistently identifying the logged-in user – over Http or Https!

So, you have a secured application on Google App Engine and use its UserService to find out the currently logged-on user is.

It all generally seems to work, except that sometimes users reports hint that UserService.getCurrentUser() returns null, and you are caught wondering “why!”.

A slightly deeper look into one such report couldn’t be avoided today. It turns out that UserService’s identification of the user seems to depend on the presence of cookies “ACSID” or “SACSID” – depending on whether the it was an “http” or “https” URL that triggered the user authentication, and these cookies are not interchangeable. If user authentication gets triggered over HTTPS (and a “SACSID” cookie is issued by Google App Engine), and the user then switches to a “HTTP” application URL in the same session, then this cookie is not sent to the server as it is created with “Secure” attribute, which is supposed to ensure that the cookie is transmitted only over HTTPS connections and not HTTP. Vice-versa, if the user authentication started on HTTP (and a “ACSID” cookie was issued), then upon switching to HTTPS, although the cookie is sent to the server, it’s probably ignored because then the server looks for an SACSID cookie (which looks encrypted / longer). In any case, sending of a “ACSID” cookie over HTTPS doesn’t seem sufficient for UserService to identify the user.

Yes, as an aside, I didn’t also know that just a difference of HTTP vs HTTPS also makes a request cross-origin! 🙂

Coming back a bit, such a HTTP / HTTPS switch within a session is the cause of these sudden occurances of UserService.getCurrentUser() returning null and user authorization breaking at such times.

I have been looking for it but haven’t found any app engine specific configuration that comes to help here. In the meantime, just wanted to capture this bit about UserService when a switch between HTTP / HTTPS happens!

Android : Removing Raw Contacts When Using Read-Only Sync Adapters

So, for your favorite Android application, you have written a nice Read-Only Sync Adapter that allows you to create application-specific contacts in user’s address book.

Some time passes and now you need the ability to clean them up – perhaps to allow repeated rounds of testing around this “custom contacts” stuff. If you try to remove such a app-specific contact, you are prevented by Android with the following message:

Removing_Raw_Contacts

When you try to do it programmatically, you still run into the same situation, with the difference being that this time you don’t get explicitly reminded of this restriction. It’s when you start to see the unwanted side-effects, you realize that the “raw contacts” are not really being deleted – they are being hidden!

So, what do you do? You need to pass some extra information to Android – “CALLER_IS_SYNCADAPTER = true”, so that it allows your application to “really” delete the raw contact.

So, instead of the usual RawContacts uri

ContactsContract.RawContacts.CONTENT_URI

you need to use

ContactsContract.RawContacts.CONTENT_URI.buildUpon().appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true").build()

Voila, with this little modification in the contact URI, the contact is now really deleted and not hidden!

Got caught in this trap today. Hope it helps someone avoid it!