Merge pull request #3954 from edx/brian/fix_session_id
Encrypt the session id before writing to tracking logs.
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import hmac
|
||||
import hashlib
|
||||
import json
|
||||
import re
|
||||
import logging
|
||||
@@ -111,12 +113,26 @@ class TrackMiddleware(object):
|
||||
)
|
||||
|
||||
def get_session_key(self, request):
|
||||
"""Gets the Django session key from the request or an empty string if it isn't found"""
|
||||
""" Gets and encrypts the Django session key from the request or an empty string if it isn't found."""
|
||||
try:
|
||||
return request.session.session_key
|
||||
return self.encrypt_session_key(request.session.session_key)
|
||||
except AttributeError:
|
||||
return ''
|
||||
|
||||
def encrypt_session_key(self, session_key):
|
||||
"""Encrypts a Django session key to another 32-character hex value."""
|
||||
if not session_key:
|
||||
return ''
|
||||
|
||||
# Follow the model of django.utils.crypto.salted_hmac() and
|
||||
# django.contrib.sessions.backends.base._hash() but use MD5
|
||||
# instead of SHA1 so that the result has the same length (32)
|
||||
# as the original session_key.
|
||||
key_salt = "common.djangoapps.track" + self.__class__.__name__
|
||||
key = hashlib.md5(key_salt + settings.SECRET_KEY).digest()
|
||||
encrypted_session_key = hmac.new(key, msg=session_key, digestmod=hashlib.md5).hexdigest()
|
||||
return encrypted_session_key
|
||||
|
||||
def get_user_primary_key(self, request):
|
||||
"""Gets the primary key of the logged in Django user"""
|
||||
try:
|
||||
|
||||
@@ -117,12 +117,20 @@ class TrackMiddlewareTestCase(TestCase):
|
||||
SessionMiddleware().process_request(request)
|
||||
request.session.save()
|
||||
session_key = request.session.session_key
|
||||
|
||||
expected_session_key = self.track_middleware.encrypt_session_key(session_key)
|
||||
self.assertEquals(len(session_key), len(expected_session_key))
|
||||
context = self.get_context_for_request(request)
|
||||
self.assert_dict_subset(context, {
|
||||
'session': session_key,
|
||||
'session': expected_session_key,
|
||||
})
|
||||
|
||||
@override_settings(SECRET_KEY='85920908f28904ed733fe576320db18cabd7b6cd')
|
||||
def test_session_key_encryption(self):
|
||||
session_key = '665924b49a93e22b46ee9365abf28c2a'
|
||||
expected_session_key = '3b81f559d14130180065d635a4f35dd2'
|
||||
encrypted_session_key = self.track_middleware.encrypt_session_key(session_key)
|
||||
self.assertEquals(encrypted_session_key, expected_session_key)
|
||||
|
||||
def test_request_headers(self):
|
||||
ip_address = '10.0.0.0'
|
||||
user_agent = 'UnitTest/1.0'
|
||||
|
||||
@@ -7,6 +7,8 @@ from freezegun import freeze_time
|
||||
from django.test import TestCase
|
||||
from django.test.client import RequestFactory
|
||||
|
||||
from eventtracking import tracker
|
||||
|
||||
from datetime import datetime
|
||||
expected_time = datetime(2013, 10, 3, 8, 24, 55)
|
||||
|
||||
@@ -34,11 +36,12 @@ class TestTrackViews(TestCase):
|
||||
'event_type': sentinel.event_type,
|
||||
'event': {}
|
||||
})
|
||||
views.user_track(request)
|
||||
with tracker.get_tracker().context('edx.request', {'session': sentinel.session}):
|
||||
views.user_track(request)
|
||||
|
||||
expected_event = {
|
||||
'username': 'anonymous',
|
||||
'session': '',
|
||||
'session': sentinel.session,
|
||||
'ip': '127.0.0.1',
|
||||
'event_source': 'browser',
|
||||
'event_type': str(sentinel.event_type),
|
||||
@@ -50,6 +53,7 @@ class TestTrackViews(TestCase):
|
||||
'context': {
|
||||
'course_id': 'foo/bar/baz',
|
||||
'org_id': 'foo',
|
||||
'session': sentinel.session,
|
||||
},
|
||||
}
|
||||
self.mock_tracker.send.assert_called_once_with(expected_event)
|
||||
|
||||
@@ -41,18 +41,13 @@ def user_track(request):
|
||||
except:
|
||||
username = "anonymous"
|
||||
|
||||
try:
|
||||
scookie = request.META['HTTP_COOKIE'] # Get cookies
|
||||
scookie = ";".join([c.split('=')[1] for c in scookie.split(";") if "sessionid" in c]).strip() # Extract session ID
|
||||
except:
|
||||
scookie = ""
|
||||
|
||||
page = request.REQUEST['page']
|
||||
|
||||
with eventtracker.get_tracker().context('edx.course.browser', contexts.course_context_from_url(page)):
|
||||
context = eventtracker.get_tracker().resolve_context()
|
||||
event = {
|
||||
"username": username,
|
||||
"session": scookie,
|
||||
"session": context.get('session', ''),
|
||||
"ip": _get_request_header(request, 'REMOTE_ADDR'),
|
||||
"event_source": "browser",
|
||||
"event_type": request.REQUEST['event_type'],
|
||||
@@ -61,7 +56,7 @@ def user_track(request):
|
||||
"page": page,
|
||||
"time": datetime.datetime.utcnow(),
|
||||
"host": _get_request_header(request, 'SERVER_NAME'),
|
||||
"context": eventtracker.get_tracker().resolve_context(),
|
||||
"context": context,
|
||||
}
|
||||
|
||||
log_event(event)
|
||||
|
||||
Reference in New Issue
Block a user