0

[Use case] Our django application utilizes AJAX and allows multiple writers and editor to view and edit a single article.

Our Django application has the following session management requirements.

  1. Only allows 1 authenticated user on the page at any 1 time.
  2. Sessions expire when the user closes the window or exits the page.
  3. Sessions expire after a period of inactivity
  4. If the user is active on the app, the session must not time out.

Currently I have been looking into the sessions model however I have not seen any solutions to limit the page to only 1 user.

Thanks!

laycat
  • 5,381
  • 7
  • 31
  • 46
  • Conceptually: Set a global boolean to True when you have 1 user, and false when you have 0 users. If True the user cannot log in. – Henrik Andersson Jun 24 '13 at 07:06
  • Thanks! great input. However I have some doubts on my ability to extend the user session using django signals (call a extend session from jquery should the user click yes, extend session). – laycat Jun 24 '13 at 07:12
  • You don't have to extend the session, it extends "automatically" when the user is performing activities. Read this: https://docs.djangoproject.com/en/dev/topics/http/sessions/#browser-length-sessions-vs-persistent-sessions – Henrik Andersson Jun 24 '13 at 07:30

1 Answers1

2

Blocking decorator:

def view_only_by_one(key_function=lambda request: sha256(request.path).hexdigest()):
    def __dec(the_view):
        def __inner(request, *args, **kwargs):                
            key_for_view = key_function(request)
            current_blocked = request.session.get('blocked_view'):
            if current_blocked and current_blocked != key_for_view:
                 cache.set(key, None, timeout=0)
            user_id = cache.get(key_for_view)
            if user_id and user_id != request.user.id:
               raise PermissionDenied()
            cache.set(key, request.user.id, timeout=settings.ONLY_BY_ONE_BLOCK_TIME)
            request.session['blocked_view'] = key_for_view
            return the_view(request, *args, **kwargs)
       return __inner
    return __dec

Additionally you can have a unblocking view called by ajax and removes lock (read from session) on page exit. Session + cache is the simplest solution, but it's easy to change it to db version.

dswistowski
  • 171
  • 4
  • whoa.. 1 second reading this http://stackoverflow.com/questions/739654/how-can-i-make-a-chain-of-function-decorators-in-python to catch up with your code now. – laycat Jun 24 '13 at 13:51
  • i made mistake, now is fixed. view_only_by_one function produces decorator, usage: @view_only_by_one()\ndef my_view(request): ... – dswistowski Jun 24 '13 at 14:05
  • where would i put this decorator in?? – laycat Jun 26 '13 at 09:58