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:
Dillon Dumesnil
2022-02-18 13:20:20 -05:00
parent d44f021580
commit 31f33da625
2 changed files with 20 additions and 4 deletions

View File

@@ -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')

View File

@@ -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')