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
This commit is contained in:
@@ -1,6 +1,12 @@
|
||||
"""
|
||||
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 ##########
|
||||
|
||||
53
common/djangoapps/session_inactivity_timeout/middleware.py
Normal file
53
common/djangoapps/session_inactivity_timeout/middleware.py
Normal file
@@ -0,0 +1,53 @@
|
||||
"""
|
||||
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
|
||||
@@ -1,3 +1,9 @@
|
||||
"""
|
||||
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 #######################################
|
||||
|
||||
Reference in New Issue
Block a user