views:

102

answers:

1

I'm trying to get a sense of how to implement the user/role relationships for an application I'm writing. The persistence layer is Google App Engine's datastore, which places some interesting (but generally beneficial) constraints on what can be done. Any thoughts are appreciated.

It might be helpful to keep things very concrete. I would like there to be organizations, users, test content and test administrations (records of tests that have been taken). A user can have the role of participant (test-taker), contributor of test material or both. A user can also be a member of zero or more organizations. In the role of participant, the user can see the previous administrations of tests he or she has taken. The user can also see a test administration of another participant if that participant has given the user authorization. The user can see test material that has been made public, and he or she can see restricted content as a participant during a specific administration of a test for which that user has been authorized by an organization. As a member of an organization, the user can see restricted content in the role of contributor, and he or she might or might not also be able to edit the content. Each organization should have one or more administrators that can determine whether a member can see and edit content and determine who has admin privileges. There should also be one or more application-wide superusers that can troubleshoot and solve problems. Members of organizations can see the administrations of tests that the participants concerned have authorized them to see, and they can see anonymous data if no authorization has been given. A user cannot see the test results of another user in any other circumstances.

Since there are no joins in the App Engine datastore, it might be necessary to have things less normalized than usual for the typical SQL database in order to ensure that queries that check permissions are fast (e.g., ones that determine whether a link is to be displayed).

My questions are:

  1. How do I move forward on this? Should I spend a lot of time up front in order to get the model right, or can I iterate several times and gradually roll in additional complexity?
  2. Does anyone have some general ideas about how to break things up in this instance?
  3. Are there any GAE libraries that handle roles in a way that is compatible with this arrangement?
A: 

I'm not quite sure I'm understanding your questions correctly, but I'll try my best to answer:

  1. I always find iterative programming easier to test and write, so that's my recommendation.
  2. I think you have the necessary entities already divided correctly, but I think you need an additional entity: Permission, that defines what each role can do, each Role having zero or more Permission links. Just remember that for each many-to-many relationship in GAE you need to either define a list of keys, or a separate entity to be the intermediary.
  3. Not that I know of, but you may want to investigate Django-based role systems and try to adapt a Django-based solution (since Django's been around longer). You can hack Django onto GAE rather nicely with App Engine Patch.
Quartz
Thanks for the helpful answers. Re 1, I definitely prefer an iterative approach to the alternatives. But with databases my experience has been a little different, and my sense is that it might be good to put more thought up front. And I've noticed that the GAE datastore is even more difficult to refactor than a SQL database. So I was hoping to get a sense of whether anyone out there who has done something similar might know what balance to strike.Re 3, I'm using app-engine-patch, but I don't think Django has a concept of intermediate organizations (or accounts).
Eric W.
You're right, GAE (and databases in general) make refactoring difficult. Usually the path to choose is only do data refactors that add columns, never remove. This may be a bit easier since GAE now has data uploading, but this kind of problem was one of the reasons I left GAE for paid server space.
Quartz