Card Stories - Authentication and Users

Django Registration
The workflow of user information between the three components (django, webservice and client) is the following during registration:


 * On the homepage while anonymous, the browser requests the welcome page from django, containing the login/registration forms.
 * Django generates the forms directly, using the welcome view from website/cardstories/views.py, along with the website/templates/cardstories/welcome.html and website/templates/registration/ templates.

Manual account creation

 * When the user submits his account details to register a new account, the provided data is checked, and if correct a django User object is added to the database.
 * The user is automatically logged in on his new account.

Facebook account creation

 * When the user clicks on the Facebook connect button, he is redirected to the facebook oauth URL
 * Since it's the first time he uses Card Stories, the application is not authorized yet. Facebook prompts the user with a confirmation, allowing Card Stories certain privileges such as the access the the user email.
 * Upon acceptation, Facebook redirects the user to http:///facebook and passes an authorization code.
 * The facebook view then checks the authorization code on Facebook's oauth using the website.cardstories.backends.FacebookBackend.authenticate method (django tries to authenticate against all configured backends).
 * If it succeeds, authenticate will also add a new User object to its database, using the user details provided by Facebook.
 * The user is automatically logged in on his new account.

Login

 * Upon successful login (whether it was performed using the login form, the Facebook connect button, or automatically upon account creation), a sessionid is set by django, and contains a string which is used to verify the authenticated status of the user on every following request.
 * Once logged in, the user is either directed to the homepage or to the game he was trying to visit (in both cases on / which corresponds to the welcome view).
 * The welcome view shows the website/templates/cardstories/game.html template, which tells the browser to load the /static/js/* JS client libraries, along with the HTML content of the game itself from static/cardstories.html.

Django User object

 * id: auto-incremented
 * username: user email
 * email: user email
 * first_name: user name
 * password: user password

JS client user handling

 * The welcome view also passes the User.first_name to the JS client, or the first part of the User.email if User.first_name is blank/empty (ie toto for toto@toto.com). It becomes the player_id passed from function to function within the JS client.
 * The JS client doesn't check the authenticated status of the user, delegating this responsibility entirely to the webservice and django.

Webservice user handling

 * When the JS client needs to make a request from the webservice, the browser provides the sessionid cookie set upon login by django.
 * The webservice's plugins/djangoauth/djangoauth.py plugin checks the authentication of each request by retrieving the value of the sessionid cookie, and asking django to validate it through a request at /getloggedinuserid/ /. Django will return his internal User.id if the user is found.
 * The webservice then uses the django User.id internally to store references to users.
 * The djangoauth plugin also implements the conversion of player_id (string) into unique id (int) identifiers convenient for service.py. It is called before the query is given to the game logic and converts the player_id and owner_id fields. Before the result is returned, it is called again to convert the result of the game logic and substitute player numbers into their string counterpart. (See the plugin documentation for more details on the pre- and post-process mechanisms.)

Invitations

 * When a player is invited, the JS client passes his email to the webservice, which in turn send the invited player an email containing a link to the game he is invited to.
 * To keep track of games each player has been invited to, the webservice requests the User.id corresponding to the invited player email from django through /getuserid/ /. The corresponding getuserid view creates an empty account with an unusable password if there is no account corresponding to this email (the invited player need to recover his password to be able to login with this email).