Commit fcefada2 by Chris Dodge

add middleware to be able to expire inactive sessions after N seconds

configure middleware

add test for session inactive timeouts

add Studio inactive session timeout test

change login method used

add create_test_account to test

make sure the expected redirect URL is right

fix indenting problem

fix doc string since we moved from minutes to seconds

use utility methods rather than calling another test to set up and activate an account

clean up code violations

respond to PR feedback

use optional params to make code cleaner

pylint fix on test files
parent d9f98b84
"""
This test file will test registration, login, activation, and session activity timeouts
"""
import time
from django.test.utils import override_settings
from django.core.cache import cache
from django.core.urlresolvers import reverse
from django.conf import settings
from contentstore.tests.utils import parse_json, user, registration, AjaxEnabledTestClient
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
......@@ -188,6 +194,29 @@ class AuthTestCase(ContentStoreTestCase):
# Logged in should work.
@override_settings(SESSION_INACTIVITY_TIMEOUT_IN_SECONDS=1)
def test_inactive_session_timeout(self):
"""
Verify that an inactive session times out and redirects to the
login page
"""
self.create_account(self.username, self.email, self.pw)
self.activate_user(self.email)
self.login(self.email, self.pw)
# make sure we can access courseware immediately
resp = self.client.get_html('/course')
self.assertEquals(resp.status_code, 200)
# then wait a bit and see if we get timed out
time.sleep(2)
resp = self.client.get_html('/course')
# re-request, and we should get a redirect to login page
self.assertRedirects(resp, settings.LOGIN_REDIRECT_URL + '?next=/course')
class ForumTestCase(CourseTestCase):
def setUp(self):
......
......@@ -174,6 +174,9 @@ MIDDLEWARE_CLASSES = (
# catches any uncaught RateLimitExceptions and returns a 403 instead of a 500
'ratelimitbackend.middleware.RateLimitMiddleware',
# for expiring inactive sessions
'session_inactivity_timeout.middleware.SessionInactivityTimeout',
)
############# XBlock Configuration ##########
......
"""
Middleware to auto-expire inactive sessions after N seconds, which is configurable in
settings.
To enable this feature, set in a settings.py:
SESSION_INACTIVITY_TIMEOUT_IN_SECS = 300
This was taken from StackOverflow (http://stackoverflow.com/questions/14830669/how-to-expire-django-session-in-5minutes)
"""
from datetime import datetime, timedelta
from django.conf import settings
from django.contrib import auth
LAST_TOUCH_KEYNAME = 'SessionInactivityTimeout:last_touch'
class SessionInactivityTimeout(object):
"""
Middleware class to keep track of activity on a given session
"""
def process_request(self, request):
"""
Standard entry point for processing requests in Django
"""
if not hasattr(request, "user") or not request.user.is_authenticated():
#Can't log out if not logged in
return
timeout_in_seconds = getattr(settings, "SESSION_INACTIVITY_TIMEOUT_IN_SECONDS", None)
# Do we have this feature enabled?
if timeout_in_seconds:
# what time is it now?
utc_now = datetime.utcnow()
# Get the last time user made a request to server, which is stored in session data
last_touch = request.session.get(LAST_TOUCH_KEYNAME)
# have we stored a 'last visited' in session? NOTE: first time access after login
# this key will not be present in the session data
if last_touch:
# compute the delta since last time user came to the server
time_since_last_activity = utc_now - last_touch
# did we exceed the timeout limit?
if time_since_last_activity > timedelta(seconds=timeout_in_seconds):
# yes? Then log the user out
del request.session[LAST_TOUCH_KEYNAME]
auth.logout(request)
return
request.session[LAST_TOUCH_KEYNAME] = utc_now
"""
This test file will run through some LMS test scenarios regarding access and navigation of the LMS
"""
import time
from django.conf import settings
from django.core.urlresolvers import reverse
from django.test.utils import override_settings
......@@ -37,6 +43,28 @@ class TestNavigation(ModuleStoreTestCase, LoginEnrollmentTestCase):
self.create_account(username, email, password)
self.activate_user(email)
@override_settings(SESSION_INACTIVITY_TIMEOUT_IN_SECONDS=1)
def test_inactive_session_timeout(self):
"""
Verify that an inactive session times out and redirects to the
login page
"""
email, password = self.STUDENT_INFO[0]
self.login(email, password)
# make sure we can access courseware immediately
resp = self.client.get(reverse('dashboard'))
self.assertEquals(resp.status_code, 200)
# then wait a bit and see if we get timed out
time.sleep(2)
resp = self.client.get(reverse('dashboard'))
# re-request, and we should get a redirect to login page
self.assertRedirects(resp, settings.LOGIN_REDIRECT_URL + '?next=' + reverse('dashboard'))
def test_redirects_first_time(self):
"""
Verify that the first time we click on the courseware tab we are
......
......@@ -654,6 +654,9 @@ MIDDLEWARE_CLASSES = (
# For A/B testing
'waffle.middleware.WaffleMiddleware',
# for expiring inactive sessions
'session_inactivity_timeout.middleware.SessionInactivityTimeout',
)
############################### Pipeline #######################################
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment