SimpleSession() Class Introduction
This class provides simple but very powerful session handling code. By this, I mean the ability to have users log in and out of your site. How simple? Well, the example provided by JOTWeb requires 4 lines of Python code and 79 lines of HTML including registration, login, and logout pages (including error message display, and form validation).
It includes the ability to sign up new accounts disabled and generate an "acknowledgement key" which has to be entered by the user to activate their account. While SimpleSession doesn't include the sending of those messages, it makes it all awfully easy...
SimpleSession is the session-handling code only. It relies on a "Backend" (as defined in other sections of this manual) which integrates with a persistant store for holding the user and session information. For example, there are Backends for storing the data on the file-system or in a PostgreSQL database.
SimpleSession() General Usage
At it's most basic, the use of SimpleSession() involves creating a SimpleSession object by calling "SimpleSession(backend)", where "backend" is a Backend* object for persistant storage. You can then call the "getSession()" method to get an existing session details, "processLogin()" to process a login form, etc...
Session and user objects contain "payload" items which you can store arbitrary information in, as long as it can be pickled. The backends must be able to hold at least 1024 bytes of information in the pickle, but may not necessarily hold more than that (after pickling). Once you have updated the payload or other changable fields in the user or session data, you will need to call userSave() or sessionSave() to update persistent storage.
SimpleSession() Methods
__init__(backend, cookieName = 'sessionid', cookieComment = 'User Login Cookie', cookiePath = '/', useMd5Password = True)
Arguments:
- backend -- (Backend object) The persistant storage for user and session information.
- cookieName -- (string, optional) The name of the cookie which is stored on the user's browser for the session cookie.
- cookieComment -- (string, optional) A comment to be sent along with the cookie, describing it's use.
- cookiePath -- (string, optional) If not "/", will be used as the "path" element of the cookie.
- useMd5Password -- (boolean, optional) Specifies wether passwords encrypted in this module are encrypted using md5 or traditional Unix mechanisms.
Returns: None.
Side-effects: Loads cookie data and verifies session against persistant storage.
Exceptions: None.
Description: This routine should be called to load session data for use by the page. If True is returned, session data has been retrieved and user/session information is available.
getUserData()
Arguments: None
Returns: None if there is no valid session, a dictionary in the form of a Backend() object's "user data" for a valid session.
Side-effects: Initial call updates stored session data.
Exceptions: None.
Description: Returns an object containing information on the user that is currently logged in. See The auth.Sessions.Backend documentation for more information on what this object contains.
getSessionData()
Arguments: None
Returns: None if there is no valid session, a dictionary in the form of a Backend() object's "session data" for a valid session.
Side-effects: Initial call updates stored session data.
Exceptions: None.
Description: Returns an object containing information on the session that is currently logged in. See The auth.Sessions.Backend documentation for more information on what this object contains.
processAck(username = None, ackid = None, form = None)
Arguments:
- username -- (string or None) If a string, specifies the user name to log in. If None, "UserName" field of form is used.
- ackid -- (string or None) If a string, specifies the acknowledgement ID. If None, "AckId" field of form is used.
- form -- (Form Data or None) Form Data is expected to be a dictionary or SimpleForm.FormHandler() object. If None, a SimpleForm.FormHandler is instantiated and used.
Returns:
Side-effects: Updates persistant storage, on success "ackid" is no longer valid for enabling the (already enabled) account.
Exceptions: None.
Description: See processLogin() description for details of how username/password/form interact.
This routine will acknowledge an account enable request, enabling the account on success. Upon completion, the account can be logged in to.
processLogin(username = None, password = None, expireSecs = None, form = None)
Arguments:
- username -- (string or None) If a string, specifies the user name to log in. If None, "UserName" field of form is used.
- password -- (string or None) If a string, specifies the account password. If None, "Password" field of form is used.
- expireSecs -- (integer or None) Specifies the session timeout in seconds, or unlimited session length if None.
- form -- (Form Data or None) Form Data is expected to be a dictionary or SimpleForm.FormHandler() object. If None, a SimpleForm.FormHandler is instantiated and used.
Returns: None on success and a string indicating the reason for failure if login failed.
Side-effects: Modifies stored user/session. Writes output headers for setting the session cookie on success.
Exceptions: None.
Description: Implements the login logic. Note that you can specify a username and/or password, or allow it to be picked up from a form (provided by you or the SimpleForm.FormHandler() otherwise. In the event that a form is used, the fields must be named "UserName" and "Password", and should have already gone through validation before getting to this point. See the vdt_* functions below.
processLogout()
Arguments: None
Returns: None on success and a string indicating the reason for failure if login failed.
Side-effects: Current session is no longer valid.
Exceptions: None.
Description: This invalidates the currently active session.
processRegister(username = None, password = None, useAck = False, form = None)
Arguments:
- username -- (string or None) If a string, specifies the user name to log in. If None, "UserName" field of form is used.
- password -- (string or None) If a string, specifies the account password. If None, "Password" field of form is used.
- useAck -- (True|False) If True, user account is created disabled, and user object (from getUserData) includes a "ackkey" that must be provided to enable. account.
- form -- (Form Data or None) Form Data is expected to be a dictionary or SimpleForm.FormHandler() object. If None, a SimpleForm.FormHandler is instantiated and used.
Returns: None on success or a string indicating reason for failure.
Side-effects: Resets stored used data.
Exceptions: None.
Description: See processLogin() description for details of how username/password/form interact.
This function will register a new user. If useAck is true, the account is created disabled, and the user must further submit an acknowledgement with a special key to enable the account. This is for implementing a site where you verify the e-mail address of the user by sending a special acknowledgement e-mail message.
The acknowledgement must include both the username and the ackkey. On return from this function, your code should generate an e-mail or other response to the user which includes the acknowledgement key, obtained from the "ackkey" element of the "userData" dictionary ("session.getUserData()['ackkey']").
It is useful to remember that you can generate a "GET" HTTP request manually. For example, if your acknowledgement page is "http://example.com/ack.html", you can use the following code to build a URL that can be directly used to acknowledge the message:
userData = session.getUserData()
ackUrl = 'http://example.com/ack.html?UserName=%s&AckKey=%s' % (
userData['username'], userData['ackkey'] )
The above is Python code which will create the URL that can be clicked on to acknowledge the account creation.
processRemove(username = None, form = None)
Arguments:
- username -- (string or None) If a string, specifies the user name to log in. If None, "UserName" field of form is used.
- form -- (Form Data or None) Form Data is expected to be a dictionary or SimpleForm.FormHandler() object. If None, a SimpleForm.FormHandler is instantiated and used.
Returns: None on success or a string indicating reason for failure.
Side-effects: None.
Exceptions: None.
Description: See processLogin() description for details of how username and form interact.
This function will delete an existing user. It is the responsibility of the code which calls this to ensure that the user calling is has the privileges to do so.
sessionSave(password = None, cryptpassword = None, expiresecs = None, expires = None, payload = None)
Arguments:
- password -- (string or None) If set to a string, this password is crypted and used as the new password.
- cryptpassword -- (string or None) If set to a string, this password is and used as the new password. If both this and the "password" fields are set, this field takes precedence.
- expiresecs -- (integer or None) If set, indicates the number of seconds since the last session hit that the session will be valid.
- expires -- (integer or None) If set to a positive integer, indicates the time at which the session expires, as returned by time.time(). Setting this to -1 will expire the session immediately.
- payload -- (Dictionary or None) If passed a dictionary, the session record "payload" field is updated.
Returns: None.
Side-effects: Updates stored session record and session record in persistent store in the backend.
Exceptions: None.
Description: This method is used to update the data stored in the session record related to the current session. Any of the parameters that are set to non-None values will be updated in the permanent copy of the session record. Application-specific data should be stored in the "payload" dictionary.
The "payload" field should only be relied upon to hold 1024 bytes of data, after pickling the "payload" field. However, neither the Filesystem nor PyPgSQL backends currently implement limits. You probably shouldn't store megabytes of data in it, but it will probably work.
userSave(password = None, cryptpassword = None, enabled = None, payload = None)
Arguments:
- password -- (string or None) If set to a string, this password is crypted and used as the new password.
- cryptpassword -- (string or None) If set to a string, this password is and used as the new password. If both this and the "password" fields are set, this field takes precedence.
- enabled -- (Boolean or None) If set to a boolean, the account enabled state is set to match this parameter.
- payload -- (Dictionary or None) If passed a dictionary, the user record "payload" field is updated.
Returns: None.
Side-effects: Updates stored user record and user record in persistent store in the backend.
Exceptions: None.
Description: This method is used to update the data stored in the user record related to the current session. Any of the parameters that are set to non-None values will be updated in the permanent copy of the user record. Application-specific data should be stored in the "payload" dictionary.
The "payload" field should only be relied upon to hold 1024 bytes of data, after pickling the "payload" field. However, neither the Filesystem nor PyPgSQL backends currently implement limits. You probably shouldn't store megabytes of data in it, but it will probably work.
SimpleSession() vdt_* Validation Routines
The vdt_* methods of the SimpleSession() objects are sample validators to check the form fields using some common rules. This is meant to specify the common case, but you are likely to want to set up your own form validation, but these are a start.
More detailed information on the validators that these call is available from the "input.SimpleForm" documentation.
vdt_ack(form = None)
Arguments:
- form -- (Form Data or None) Form Data is expected to be a dictionary or SimpleForm.FormHandler() object. If None, a SimpleForm.FormHandler is instantiated and used.
Returns: Form object, either passed in the the one from the SimpleForm.FormHandler().
Side-effects: Instantiates a SimpleForm.FormHandler() if called with form=None.
Exceptions: None.
Description: "Username" field: Runs the "vdt_required()" if that succeeds runs "vdt_realname()". "AckID" field: Runs "vdt_required()" and if that succeeds runs the "vdt_alnum()" validator.
vdt_login(form = None)
Arguments:
- form -- (Form Data or None) Form Data is expected to be a dictionary or SimpleForm.FormHandler() object. If None, a SimpleForm.FormHandler is instantiated and used.
Returns: Form object, either passed in the the one from the SimpleForm.FormHandler().
Side-effects: Instantiates a SimpleForm.FormHandler() if called with form=None.
Exceptions: None.
Description: Runs the "vdt_required()" validator on the form "Username" and "Password" fields, and if each field is filled in aso runs "vdt_realname()" on "Username" field and "vdt_password()" on the "Password" field.
vdt_register(form = None)
Arguments:
- form -- (Form Data or None) Form Data is expected to be a dictionary or SimpleForm.FormHandler() object. If None, a SimpleForm.FormHandler is instantiated and used.
Returns: Form object, either passed in the the one from the SimpleForm.FormHandler().
Side-effects: Instantiates a SimpleForm.FormHandler() if called with form=None.
Exceptions: None.
Description: "Username" field: Runs the "vdt_required()" if that succeeds runs "vdt_realname()". "Password" field: Runs "vdt_required()" and if that succeeds runs the "vdt_password()" and "vdt_fieldequals()" validators, the latter checking for equality with the "PasswordAgain" field.
vdt_remove(form = None)
Arguments:
- form -- (Form Data or None) Form Data is expected to be a dictionary or SimpleForm.FormHandler() object. If None, a SimpleForm.FormHandler is instantiated and used.
Returns: Form object, either passed in the the one from the SimpleForm.FormHandler().
Side-effects: Instantiates a SimpleForm.FormHandler() if called with form=None.
Exceptions: None.
Description: "Username" field: Runs the "vdt_required()" if that succeeds runs "vdt_realname()".
Example
See the "sessionex" files in the JOTWeb "examples" directory in the source distribution for an example of using this code.