Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
1b465d1b
Commit
1b465d1b
authored
Feb 05, 2013
by
Brian Wilson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
implement testcenter_login
parent
b6ae62e3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
131 additions
and
9 deletions
+131
-9
common/djangoapps/student/views.py
+125
-5
lms/djangoapps/courseware/models.py
+4
-0
lms/djangoapps/courseware/views.py
+2
-4
No files found.
common/djangoapps/student/views.py
View file @
1b465d1b
import
datetime
import
datetime
import
feedparser
import
feedparser
#import itertools
import
json
import
json
import
logging
import
logging
import
random
import
random
import
string
import
string
import
sys
import
sys
#import time
import
urllib
import
urllib
import
uuid
import
uuid
...
@@ -18,10 +16,13 @@ from django.contrib.auth.models import User
...
@@ -18,10 +16,13 @@ from django.contrib.auth.models import User
from
django.contrib.auth.decorators
import
login_required
from
django.contrib.auth.decorators
import
login_required
from
django.core.context_processors
import
csrf
from
django.core.context_processors
import
csrf
from
django.core.mail
import
send_mail
from
django.core.mail
import
send_mail
from
django.core.urlresolvers
import
reverse
from
django.core.validators
import
validate_email
,
validate_slug
,
ValidationError
from
django.core.validators
import
validate_email
,
validate_slug
,
ValidationError
from
django.db
import
IntegrityError
from
django.db
import
IntegrityError
from
django.http
import
HttpResponse
,
HttpResponseForbidden
,
Http404
from
django.http
import
HttpResponse
,
HttpResponseForbidden
,
Http404
,
\
HttpResponseRedirect
from
django.shortcuts
import
redirect
from
django.shortcuts
import
redirect
from
mitxmako.shortcuts
import
render_to_response
,
render_to_string
from
mitxmako.shortcuts
import
render_to_response
,
render_to_string
from
bs4
import
BeautifulSoup
from
bs4
import
BeautifulSoup
from
django.core.cache
import
cache
from
django.core.cache
import
cache
...
@@ -39,11 +40,11 @@ from xmodule.course_module import CourseDescriptor
...
@@ -39,11 +40,11 @@ from xmodule.course_module import CourseDescriptor
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.django
import
modulestore
#from datetime import date
from
collections
import
namedtuple
from
collections
import
namedtuple
from
courseware.courses
import
get_courses
,
sort_by_announcement
from
courseware.courses
import
get_courses
,
sort_by_announcement
from
courseware.access
import
has_access
from
courseware.access
import
has_access
from
courseware.models
import
TimedModule
from
statsd
import
statsd
from
statsd
import
statsd
...
@@ -1058,7 +1059,7 @@ def accept_name_change(request):
...
@@ -1058,7 +1059,7 @@ def accept_name_change(request):
# TODO: This is a giant kludge to give Pearson something to test against ASAP.
# TODO: This is a giant kludge to give Pearson something to test against ASAP.
# Will need to get replaced by something that actually ties into TestCenterUser
# Will need to get replaced by something that actually ties into TestCenterUser
@csrf_exempt
@csrf_exempt
def
test_center_login
(
request
):
def
a
test_center_login
(
request
):
if
not
settings
.
MITX_FEATURES
.
get
(
'ENABLE_PEARSON_HACK_TEST'
):
if
not
settings
.
MITX_FEATURES
.
get
(
'ENABLE_PEARSON_HACK_TEST'
):
raise
Http404
raise
Http404
...
@@ -1076,6 +1077,125 @@ def test_center_login(request):
...
@@ -1076,6 +1077,125 @@ def test_center_login(request):
return
HttpResponseForbidden
()
return
HttpResponseForbidden
()
@csrf_exempt
def
test_center_login
(
request
):
# errors are returned by navigating to the error_url, adding a query parameter named "code"
# which contains the error code describing the exceptional condition.
def
makeErrorURL
(
error_url
,
error_code
):
return
"{}&code={}"
.
format
(
error_url
,
error_code
);
# get provided error URL, which will be used as a known prefix for returning error messages to the
# Pearson shell. It does not have a trailing slash, so we need to add one when creating output URLs.
error_url
=
request
.
POST
.
get
(
"errorURL"
)
# check that the parameters have not been tampered with, by comparing the code provided by Pearson
# with the code we calculate for the same parameters.
if
'code'
not
in
request
.
POST
:
return
HttpResponseRedirect
(
makeErrorURL
(
error_url
,
"missingSecurityCode"
));
code
=
request
.
POST
.
get
(
"code"
)
# calculate SHA for query string
# TODO: figure out how to get the original query string, so we can hash it and compare.
if
'clientCandidateID'
not
in
request
.
POST
:
return
HttpResponseRedirect
(
makeErrorURL
(
error_url
,
"missingClientCandidateID"
));
client_candidate_id
=
request
.
POST
.
get
(
"clientCandidateID"
)
# TODO: check remaining parameters, and maybe at least log if they're not matching
# expected values....
# registration_id = request.POST.get("registrationID")
# exit_url = request.POST.get("exitURL")
# find testcenter_user that matches the provided ID:
try
:
testcenteruser
=
TestCenterUser
.
objects
.
get
(
client_candidate_id
=
client_candidate_id
)
except
TestCenterUser
.
DoesNotExist
:
return
HttpResponseRedirect
(
makeErrorURL
(
error_url
,
"invalidClientCandidateID"
));
# find testcenter_registration that matches the provided exam code:
# Note that we could rely on either the registrationId or the exam code,
# or possibly both.
if
'vueExamSeriesCode'
not
in
request
.
POST
:
# TODO: confirm this error code (made up, not in documentation)
return
HttpResponseRedirect
(
makeErrorURL
(
error_url
,
"missingExamSeriesCode"
));
exam_series_code
=
request
.
POST
.
get
(
'vueExamSeriesCode'
)
registrations
=
TestCenterRegistration
.
objects
.
filter
(
testcenter_user
=
testcenteruser
,
exam_series_code
=
exam_series_code
)
if
not
registrations
:
return
HttpResponseRedirect
(
makeErrorURL
(
error_url
,
"noTestsAssigned"
));
# TODO: figure out what to do if there are more than one registrations....
# for now, just take the first...
registration
=
registrations
[
0
]
course_id
=
registration
.
course_id
# if we want to look up whether the test has already been taken, or to
# communicate that a time accommodation needs to be applied, we need to
# know the module_id to use that corresponds to the particular exam_series_code.
# For now, we can hardcode that...
if
exam_series_code
==
'6002x001'
:
chapter_url_name
=
'Final_Exam'
section_url_name
=
'Final_Exam_Fall_2012'
redirect_url
=
reverse
(
'courseware_section'
,
args
=
[
course_id
,
chapter_url_name
,
section_url_name
])
location
=
'i4x://MITx/6.002x/2012_Fall/sequence/Final_Exam_Fall_2012'
else
:
# TODO: clarify if this is the right error code for this condition.
return
HttpResponseRedirect
(
makeErrorURL
(
error_url
,
"incorrectCandidateTests"
));
time_accommodation_mapping
=
{
'ET12ET'
:
'ADDHALFTIME'
,
'ET30MN'
:
'ADD30MIN'
,
'ETDBTM'
:
'ADDDOUBLE'
,
}
# check if the test has already been taken
timed_modules
=
TimedModule
.
objects
.
filter
(
student
=
testcenteruser
.
user
,
course_id
=
course_id
,
module_state_key
=
location
)
if
timed_modules
:
timed_module
=
timed_modules
[
0
]
if
timed_module
.
has_ended
:
return
HttpResponseRedirect
(
makeErrorURL
(
error_url
,
"allTestsTaken"
));
elif
registration
.
get_accommodation_codes
():
# we don't have a timed module created yet, so if we have time accommodations
# to implement, create an entry now:
time_accommodation_code
=
None
for
code
in
registration
.
get_accommodation_codes
():
if
code
in
time_accommodation_mapping
:
time_accommodation_code
=
time_accommodation_mapping
[
code
]
if
client_candidate_id
==
"edX003671291147"
:
time_accommodation_code
=
'TESTING'
if
time_accommodation_code
:
timed_module
=
TimedModule
(
student
=
request
.
user
,
course_id
=
course_id
,
module_state_key
=
location
)
timed_module
.
accommodation_code
=
time_accommodation_code
timed_module
.
save
()
# Now log the user in:
# user = authenticate(username=testcenteruser.user.username,
# password=testcenteruser.user.password)
#
# if user is None:
# # argh. We couldn't login!
# return HttpResponseRedirect(makeErrorURL(error_url, "ARGH! User cannot log in"));
# UGLY HACK!!!
# Login assumes that authentication has occurred, and that there is a
# backend annotation on the user object, indicating which backend
# against which the user was authenticated. We're authenticating here
# against the registration entry, and assuming that the request given
# this information is correct, we allow the user to be logged in
# without a password. This could all be formalized in a backend object
# that does the above checking.
# TODO: create a backend class to do this.
# testcenteruser.user.backend = "%s.%s" % (backend.__module__, backend.__class__.__name__)
testcenteruser
.
user
.
backend
=
"
%
s.
%
s"
%
(
"TestcenterAuthenticationModule"
,
"TestcenterAuthenticationClass"
)
login
(
request
,
testcenteruser
.
user
)
# And start the test:
return
redirect
(
redirect_url
)
def
_get_news
(
top
=
None
):
def
_get_news
(
top
=
None
):
"Return the n top news items on settings.RSS_URL"
"Return the n top news items on settings.RSS_URL"
...
...
lms/djangoapps/courseware/models.py
View file @
1b465d1b
...
@@ -239,6 +239,7 @@ class TimedModule(models.Model):
...
@@ -239,6 +239,7 @@ class TimedModule(models.Model):
(
'ADDHALFTIME'
,
'Extra Time - 1 1/2 Time'
),
(
'ADDHALFTIME'
,
'Extra Time - 1 1/2 Time'
),
(
'ADD30MIN'
,
'Extra Time - 30 Minutes'
),
(
'ADD30MIN'
,
'Extra Time - 30 Minutes'
),
(
'DOUBLE'
,
'Extra Time - Double Time'
),
(
'DOUBLE'
,
'Extra Time - Double Time'
),
(
'TESTING'
,
'Extra Time -- Large amount for testing purposes'
)
)
)
accommodation_code
=
models
.
CharField
(
max_length
=
12
,
choices
=
TIME_ACCOMMODATION_CODES
,
default
=
'NONE'
,
db_index
=
True
)
accommodation_code
=
models
.
CharField
(
max_length
=
12
,
choices
=
TIME_ACCOMMODATION_CODES
,
default
=
'NONE'
,
db_index
=
True
)
...
@@ -256,6 +257,9 @@ class TimedModule(models.Model):
...
@@ -256,6 +257,9 @@ class TimedModule(models.Model):
return
(
duration
+
(
30
*
60
))
return
(
duration
+
(
30
*
60
))
elif
self
.
accommodation_code
==
'DOUBLE'
:
elif
self
.
accommodation_code
==
'DOUBLE'
:
return
(
duration
*
2
)
return
(
duration
*
2
)
elif
self
.
accommodation_code
==
'TESTING'
:
# when testing, set timer to run for a week at a time.
return
3600
*
24
*
7
# store state:
# store state:
...
...
lms/djangoapps/courseware/views.py
View file @
1b465d1b
...
@@ -415,9 +415,8 @@ def timed_exam(request, course_id, chapter, section):
...
@@ -415,9 +415,8 @@ def timed_exam(request, course_id, chapter, section):
duration
=
int
(
section_descriptor
.
metadata
.
get
(
'duration'
))
duration
=
int
(
section_descriptor
.
metadata
.
get
(
'duration'
))
# get corresponding time module, if one is present:
# get corresponding time module, if one is present:
# TODO: determine what to use for module_key...
try
:
try
:
timed_module
=
TimedModule
.
objects
.
get
(
student
=
request
.
user
,
course_id
=
course_id
)
timed_module
=
TimedModule
.
objects
.
get
(
student
=
request
.
user
,
course_id
=
course_id
,
module_state_key
=
section_module
.
id
)
# if a module exists, check to see if it has already been started,
# if a module exists, check to see if it has already been started,
# and if it has already ended.
# and if it has already ended.
...
@@ -447,8 +446,7 @@ def timed_exam(request, course_id, chapter, section):
...
@@ -447,8 +446,7 @@ def timed_exam(request, course_id, chapter, section):
except
TimedModule
.
DoesNotExist
:
except
TimedModule
.
DoesNotExist
:
# no entry found. So we're starting this test
# no entry found. So we're starting this test
# without any accommodations being preset.
# without any accommodations being preset.
# TODO: determine what to use for module_key...
timed_module
=
TimedModule
(
student
=
request
.
user
,
course_id
=
course_id
,
module_state_key
=
section_module
.
id
)
timed_module
=
TimedModule
(
student
=
request
.
user
,
course_id
=
course_id
)
timed_module
.
begin
(
duration
)
timed_module
.
begin
(
duration
)
timed_module
.
save
()
timed_module
.
save
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment