[albatross-users] Session and validate_request()
Dave Cole
djc at object-craft.com.au
Tue Mar 29 11:57:35 EST 2005
Denis Toporov wrote:
> Hi again,
> it seems like I'm in trouble again:)
> lets imagine I have modular random session application,
> and initialize session variables in main script (specified as start_page
> script in application
> constructor) in validate_request() method.
> I hoped that validate_request() called on each request.
> The problem: if user have no actions for a while, session is dead
> because of session timeout.
> And if user try to request after dead session any page he gets an
> exception, because of session is dead,
> and no session variables any more. So he got no variable exception trace.
>
> The way to avoid this is to put check of session
> variables existence in each .py module, but this is brute force method.
> Is any smart solution already exists for this kind of problem?
Random access applications are inherently difficult. There is no
escaping that.
The best approach to this sort of problem is to make your own execution
context class that tests the contents of the session and enforce
exceptional processing in the absence of required variables.
Something like this:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
from albatross import RandomModularSessionApp, SessionAppContext
from albatross.cgiapp import Request
class AppContext(SessionAppContext):
def assert_user(self):
if not hasattr(self.locals, '_user'):
self.redirect('login')
def assert_something_else(self):
self.assert_user()
if not hasattr(self.locals, '_something_else'):
self.redirect('somepage')
class App(RandomModularSessionApp):
def create_context(self):
return AppContext(self)
app = App(base_url='myapp', page_path='pages', start_page='login',
secret='mysecret', session_appid='myapp')
if __name__ == '__main__':
app.run(Request())
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Then for each page you need to do something like this:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def page_process(ctx):
ctx.assert_user()
# prepare to display thispage
def page_display(ctx):
ctx.run_template('thispage.html')
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The redirect method on the execution context will raise Redirect
exception that is handled within the normal application run() method.
Taking that sort of approach should make things easier.
Once that is working you might want to be able to go back to the
originally requested page. You could probably do that by doing
something similar to the following:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
class AppContext(SessionAppContext):
def memo_redirect(self, page):
ctx.locals._memo_page = self.locals.__page__
self.add_session_vars('_memo_page')
self.redirect(page)
def memo_restore(self):
try:
page = ctx.locals._memo_page
except AttributeError:
return
self.del_session_vars('_memo_page')
self.redirect(page)
class App(RandomModularSessionApp):
def load_page_module(self, ctx, page):
RandomModularSessionApp.load_page_module(self, ctx, page)
ctx.locals.__page__ = page
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Then instead of calling redirect() in your assert methods you would call
memo_redirect().
The extension of the load_page_module() method is required because (for
some reason) Albatross does not seem to be maintaining __page__ for
random applications.
In the page_process() function for the assertion handling pages you can
then call ctx.memo_restore(). If the method returns then the user was
not visiting the page in response to an assertion, so some sort of
normal application processing would need to be performed.
Hopefully that makes sense.
Note that none of the above code has been tested - it is only provided
as an illustration.
- Dave
--
http://www.object-craft.com.au
More information about the Albatross-users
mailing list