Friday, December 12, 2008

One Down, One Up

I finished up one client task today but I realized I have an extra Permissions task. I've decided to make a slight architectural change to the way I've been handling users. I haven't figured it all out, but a discussion late this afternoon with Damon Cortesi (who had stopped by StartPad and just happened to be there when I wanted to think about it) helped solidify my thoughts that it was a change I ought to make -- and the time to do it is now because it'll be more painful later.

When you give permissions to someone else in Groupthink Projects, you provide their email address. A lot of the time, it's an email address that the system's never seen before, so I cannot associate the email address with an actual user. But, later, when the person signs in, I can. And that's exactly what I have been doing, partially because of advice from Google -- they advise that apps shouldn't store users' email addresses because they might change (although there appears to be no current way that they could). So, as soon as a I know the user for the email address, I switch to referencing the user. But, this means that, in all my permission code, I have to constantly check if a permitted person is a user or an email address. That's a pain and leads to problems, some of which I was dealing with.

So, I've decided, even though it's late, to change this and switch to only using email addresses. I'm also considering an additional change, which would also go against the normal way of doing things on Google App Engine. I'm less sure about this change, but it would allow me to simplify the logic in dealing with item-level permissions. The tradeoff is larger data storage, and a slight redundancy in one place, but I think that's an ok tradeoff to make. I'll ruminate on it this weekend.

At the STS talk on tuesday, Rajiv Goel asked me when I was going to launch and I said I didn't know yet. The correct answer would have been to say "when I can guarantee I won't lose your data." That's not the only criteria, but it's the most inportant one. Although this change needn't cause data loss, it woudl be a good thing if I'm confident I won't need any more changes like it when I launch.


Anonymous said...

Why not just create a new user when you see a new email address? You can fill in the details later when that person desides to sign in.

Roy Leban said...

That's a good question. I simplified the situation a bit in the blog post. The actual user model objects are owned by GAE, not me (because I'm using Google ID for auth). I can't create them and I can't look up a user by email address (or any other way). The only way to get one is to have a signed-in user. Once I have that, I can save a reference to the user and use it when they're not signed in.

Because I can't add anything to the user model, I have a Member table that contains extra information about the user. The Member table maps 1-1 to users and the permissions actually point to Member records, not to users.

I could create a Member record the first time that I see an email address, but that would basically mean that I have the same problem -- I've just moved it. Rather than the permissions having either a Member or an email address, permissions would always point to a Member, but now Members would either point to a user or have an email address.

With the change, I always have an email address, Member records have an email address, and I can look them up that way. When you give permissions, you are giving them to an email address. If Google ever provides a way to change the email address associated with a Google ID, then I might have some extra work to do, but that may never happen.

Mike Koss said...

The user management system I just finished uses a "nickname/username" as the unique key for a user. While I use nicknames for anonymous users, I create a Profile (I like your model name, Member, better) when the user authenticates (currently, the only authentication method is Google account).

But I would NOT tie a user to a unique email address - it can change. I like getting a non-email nickname as the identifier for a user. You can enforce that they can't change and is globally unique.

You then have the option to decide if email address are unique to one user, or if they can have several, or even if several accounts can use the same email address.

I made the simplification that one GAE account maps to one user - but at first I allowed multiple users to be mapped to one GAE user - e.g., I have multiple twitter accounts for different "personae".

Roy Leban said...

@Mike: I had wanted to talk with you about this on Friday (because I know is doing it differently), but then I forgot.

I think my needs are different from both and Puzzazz because of the sharing aspect and the fact that I'm targeting small companies. I want people to trust that when they share with someone, it's exactly the person they think it is, because they have the right email address. I also don't want to show nicknames instead of email address because I think that will look sloppy, security-wise. I could see showing "real names" when I add company-specific features.

To describe my new design simply -- when you share with someone, you share with their email address. And the way that the person proves that they own that email address is to sign in with the corresponding Google ID.

Anonymous said...

There might be enough information here for me to prove to myself that you're not doing what I'm about to complain about, but I'll complain anyway.

I hate it when I receive a sharing invitation sent to one of my email addresses and then can't migrate the object that I was invited to share to be accessed by my preferred account. Google Docs and Windows Live's freshly shipped social network application both do this.

Does your sharing model handle this the right way (for inspiration, see Live Mesh), or the wrong way?

Anonymous said...

Now that I read more closely, I see that you're defending doing it the wrong way.

The "sharing with exactly who they think it is" part is hooey. If they trust me (the person) enough to share it with me, it shouldn't matter which of my accounts I ultimately sign in to access the resource. I'm fine with you continuing to display the email address that they originally invited, but I do _not_ want to have to sign out of my favorite Google account just because someone used one of my less preferred email addresses for a sharing invitation.

Security-wise, your model already trusts the recipient email account to be used as the primary vehicle for re-keying the underlying Google account (think "I forgot my password"), so it's not like a long URL that can be bound to exactly one arbitrary email address is weakening any of your security assumptions.

Roy Leban said...

@Scott: There are two issues here. One is transferability of permissions and the other is whether I refer to people by email addresses instead of GAE user key. I can support one without the other, but I'm not sure that I want to, particularly in the company case

Transferability of permissions seems like a security problem in general. In the company case, it would mean that users who transfer their permissions (and are not using an email address) get treated differently.

Even if I allow you to transfer permissions from one Google ID to another, you'd still have to sign in at least once with the Google ID that was given permissions. The reason for this is that email notification of permission changes are just that -- notifications. They're not invite links or codes.

Basically, it sucks that you can only be signed into one Google ID at a time and it sucks that signing into Groupthink Projects with a new Google ID signs you out of the previous Google ID on every other site that uses Google Auth. Well, sort of. Some sites, like Puzzazz, remember the fact that you're logged in, even if the current Google Auth login changes. If every site did that, the problem would go away.

Groupthink does do that, so once you login once, provided you don't sign out, it will remember you. But you can't currently be signed in as more than one email address at a time. I can look into changing that.

Anonymous said...

@Roy, what about allowing users to link multiple account identifiers into a single account/identity? Allow them to sign in with any associated email address and view/manage the union of sets of objects shared with any of the linked addresses.

I'll stop pleading my case from here. I recognize that I might be in the whiny minority of your potential users, and don't want to earn the "whiny" part.

Post a Comment