fix: Update get user timezone logic
Adds in sanitization of the timezone to ensure the timezone is formatted correctly and error handling to reasonably fall back to UTC
This commit is contained in:
@@ -5,8 +5,11 @@ This is meant to simplify the process of sending user preferences (espec. time_z
|
||||
to the templates without having to append every view file.
|
||||
|
||||
"""
|
||||
import string
|
||||
|
||||
from django.utils.translation import get_language
|
||||
from pytz import timezone
|
||||
from pytz.exceptions import UnknownTimeZoneError
|
||||
|
||||
from edx_django_utils.cache import TieredCache
|
||||
from lms.djangoapps.courseware.models import LastSeenCoursewareTimezone
|
||||
@@ -81,11 +84,19 @@ def get_user_timezone_or_last_seen_timezone_or_utc(user):
|
||||
Helper method for returning a reasonable timezone for a user.
|
||||
This method returns the timezone in the user's account if that is set.
|
||||
If that is not set, it returns a recent timezone that we have recorded from a user's visit to the courseware.
|
||||
If that is not set, it returns UTC.
|
||||
If that is not set or the timezone is unknown, it returns UTC.
|
||||
"""
|
||||
user_timezone = (
|
||||
get_user_preference(user, 'time_zone') or
|
||||
get_last_seen_courseware_timezone(user) or
|
||||
'UTC'
|
||||
)
|
||||
return timezone(user_timezone)
|
||||
# We have seen non-printable characters (i.e. \x00) showing up in the
|
||||
# user_timezone (I believe via the get_last_seen_courseware_timezone method).
|
||||
# This sanitizes the user_timezone before passing it in.
|
||||
user_timezone = filter(lambda l: l in string.printable, user_timezone)
|
||||
user_timezone = ''.join(user_timezone)
|
||||
try:
|
||||
return timezone(user_timezone)
|
||||
except UnknownTimeZoneError as err:
|
||||
return timezone('UTC')
|
||||
|
||||
@@ -62,9 +62,9 @@ class UserPrefContextProcessorUnitTest(ModuleStoreTestCase):
|
||||
time_zone = get_user_timezone_or_last_seen_timezone_or_utc(self.user)
|
||||
assert time_zone == timezone('UTC')
|
||||
|
||||
# We record the timezone when a user hits the courseware api
|
||||
# We record the timezone when a user hits the courseware api. Also sanitize input test
|
||||
self.client.login(username=self.user.username, password='foo')
|
||||
self.client.get(f'/api/courseware/course/{course.id}?browser_timezone=America/New_York')
|
||||
self.client.get(f'/api/courseware/course/{course.id}?browser_timezone=America/New_York\x00')
|
||||
time_zone = get_user_timezone_or_last_seen_timezone_or_utc(self.user)
|
||||
assert time_zone == timezone('America/New_York')
|
||||
|
||||
@@ -72,3 +72,8 @@ class UserPrefContextProcessorUnitTest(ModuleStoreTestCase):
|
||||
set_user_preference(self.user, 'time_zone', 'Asia/Tokyo')
|
||||
time_zone = get_user_timezone_or_last_seen_timezone_or_utc(self.user)
|
||||
assert time_zone == timezone('Asia/Tokyo')
|
||||
|
||||
# If we do not recognize the user's timezone, we default to UTC
|
||||
with patch('lms.djangoapps.courseware.context_processor.get_user_preference', return_value='Unknown/Timezone'):
|
||||
time_zone = get_user_timezone_or_last_seen_timezone_or_utc(self.user)
|
||||
assert time_zone == timezone('UTC')
|
||||
|
||||
Reference in New Issue
Block a user