Commit 617db2b2 by chrisndodge

Merge pull request #89 from edx/cdodge/detect-timer-manipulation

add computed remaining time to the API result set
parents 5ab7121e a0b4621f
......@@ -2,6 +2,9 @@
Helpers for the HTTP APIs
"""
import pytz
from datetime import datetime, timedelta
from django.utils.translation import ugettext as _
from rest_framework.views import APIView
from rest_framework.authentication import SessionAuthentication
......@@ -16,6 +19,23 @@ class AuthenticatedAPIView(APIView):
permission_classes = (IsAuthenticated,)
def get_time_remaining_for_attempt(attempt):
"""
Returns the remaining time (in seconds) on an attempt
"""
# need to adjust for allowances
expires_at = attempt['started_at'] + timedelta(minutes=attempt['allowed_time_limit_mins'])
now_utc = datetime.now(pytz.UTC)
if expires_at > now_utc:
time_remaining_seconds = (expires_at - now_utc).seconds
else:
time_remaining_seconds = 0
return time_remaining_seconds
def humanized_time(time_in_minutes):
"""
Converts the given value in minutes to a more human readable format
......
......@@ -4,7 +4,7 @@ Proctored Exams HTTP-based API endpoints
import logging
import pytz
from datetime import datetime, timedelta
from datetime import datetime
from django.utils.decorators import method_decorator
from django.conf import settings
......@@ -40,7 +40,7 @@ from edx_proctoring.exceptions import (
from edx_proctoring.serializers import ProctoredExamSerializer, ProctoredExamStudentAttemptSerializer
from edx_proctoring.models import ProctoredExamStudentAttemptStatus, ProctoredExamStudentAttempt
from .utils import AuthenticatedAPIView
from .utils import AuthenticatedAPIView, get_time_remaining_for_attempt
ATTEMPTS_PER_PAGE = 25
......@@ -264,7 +264,9 @@ class StudentProctoredExamAttempt(AuthenticatedAPIView):
attempt_id=attempt_id
)
)
raise StudentExamAttemptDoesNotExistsException(err_msg)
return Response(
status=status.HTTP_400_BAD_REQUEST
)
# make sure the the attempt belongs to the calling user_id
if attempt['user']['id'] != request.user.id:
......@@ -289,6 +291,11 @@ class StudentProctoredExamAttempt(AuthenticatedAPIView):
ProctoredExamStudentAttemptStatus.error
)
# add in the computed time remaining as a helper to a client app
time_remaining_seconds = get_time_remaining_for_attempt(attempt)
attempt['time_remaining_seconds'] = time_remaining_seconds
return Response(
data=attempt,
status=status.HTTP_200_OK
......@@ -449,14 +456,7 @@ class StudentProctoredExamAttemptCollection(AuthenticatedAPIView):
exam = exam_info['exam']
attempt = exam_info['attempt']
# need to adjust for allowances
expires_at = attempt['started_at'] + timedelta(minutes=attempt['allowed_time_limit_mins'])
now_utc = datetime.now(pytz.UTC)
if expires_at > now_utc:
time_remaining_seconds = (expires_at - now_utc).seconds
else:
time_remaining_seconds = 0
time_remaining_seconds = get_time_remaining_for_attempt(attempt)
proctoring_settings = getattr(settings, 'PROCTORING_SETTINGS', {})
low_threshold_pct = proctoring_settings.get('low_threshold_pct', .2)
......
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