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
ca08b979
Commit
ca08b979
authored
Apr 07, 2015
by
aamir-khan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ECOM-1290: added the redirection back to courseware after re-verification
parent
37e2ffec
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
123 additions
and
54 deletions
+123
-54
lms/djangoapps/courseware/url_helpers.py
+46
-0
lms/djangoapps/courseware/views.py
+3
-27
lms/djangoapps/verify_student/services.py
+2
-2
lms/djangoapps/verify_student/tests/test_views.py
+34
-8
lms/djangoapps/verify_student/urls.py
+1
-1
lms/djangoapps/verify_student/views.py
+23
-8
lms/static/js/verify_student/incourse_reverify.js
+1
-0
lms/static/js/verify_student/models/reverification_model.js
+7
-5
lms/static/js/verify_student/views/incourse_reverify_view.js
+5
-3
lms/templates/verify_student/incourse_reverify.html
+1
-0
No files found.
lms/djangoapps/courseware/url_helpers.py
0 → 100644
View file @
ca08b979
"""
Module to define url helpers functions
"""
from
xmodule.modulestore.search
import
path_to_location
,
navigation_index
from
xmodule.modulestore.django
import
modulestore
from
django.core.urlresolvers
import
reverse
def
get_redirect_url
(
course_key
,
usage_key
):
""" Returns the redirect url back to courseware
Args:
course_id(str): Course Id string
location(str): The location id of course component
Raises:
ItemNotFoundError if no data at the location or NoPathToItem if location not in any class
Returns:
Redirect url string
"""
(
course_key
,
chapter
,
section
,
position
)
=
path_to_location
(
modulestore
(),
usage_key
)
# choose the appropriate view (and provide the necessary args) based on the
# args provided by the redirect.
# Rely on index to do all error handling and access control.
if
chapter
is
None
:
redirect_url
=
reverse
(
'courseware'
,
args
=
(
unicode
(
course_key
),
))
elif
section
is
None
:
redirect_url
=
reverse
(
'courseware_chapter'
,
args
=
(
unicode
(
course_key
),
chapter
))
elif
position
is
None
:
redirect_url
=
reverse
(
'courseware_section'
,
args
=
(
unicode
(
course_key
),
chapter
,
section
)
)
else
:
# Here we use the navigation_index from the position returned from
# path_to_location - we can only navigate to the topmost vertical at the
# moment
redirect_url
=
reverse
(
'courseware_position'
,
args
=
(
unicode
(
course_key
),
chapter
,
section
,
navigation_index
(
position
))
)
return
redirect_url
lms/djangoapps/courseware/views.py
View file @
ca08b979
...
...
@@ -60,7 +60,6 @@ from util.cache import cache, cache_if_anonymous
from
xblock.fragment
import
Fragment
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
,
NoPathToItem
from
xmodule.modulestore.search
import
path_to_location
,
navigation_index
from
xmodule.tabs
import
CourseTabList
,
StaffGradingTab
,
PeerGradingTab
,
OpenEndedGradingTab
from
xmodule.x_module
import
STUDENT_VIEW
import
shoppingcart
...
...
@@ -82,6 +81,7 @@ import survey.views
from
util.views
import
ensure_valid_course_key
from
eventtracking
import
tracker
import
analytics
from
courseware.url_helpers
import
get_redirect_url
log
=
logging
.
getLogger
(
"edx.courseware"
)
...
...
@@ -642,37 +642,13 @@ def jump_to(_request, course_id, location):
except
InvalidKeyError
:
raise
Http404
(
u"Invalid course_key or usage_key"
)
try
:
(
course_key
,
chapter
,
section
,
position
)
=
path_to_location
(
modulestore
()
,
usage_key
)
redirect_url
=
get_redirect_url
(
course_key
,
usage_key
)
except
ItemNotFoundError
:
raise
Http404
(
u"No data at this location: {0}"
.
format
(
usage_key
))
except
NoPathToItem
:
raise
Http404
(
u"This location is not in any class: {0}"
.
format
(
usage_key
))
# choose the appropriate view (and provide the necessary args) based on the
# args provided by the redirect.
# Rely on index to do all error handling and access control.
if
chapter
is
None
:
return
redirect
(
'courseware'
,
course_id
=
unicode
(
course_key
))
elif
section
is
None
:
return
redirect
(
'courseware_chapter'
,
course_id
=
unicode
(
course_key
),
chapter
=
chapter
)
elif
position
is
None
:
return
redirect
(
'courseware_section'
,
course_id
=
unicode
(
course_key
),
chapter
=
chapter
,
section
=
section
)
else
:
# Here we use the navigation_index from the position returned from
# path_to_location - we can only navigate to the topmost vertical at the
# moment
return
redirect
(
'courseware_position'
,
course_id
=
unicode
(
course_key
),
chapter
=
chapter
,
section
=
section
,
position
=
navigation_index
(
position
)
)
return
redirect
(
redirect_url
)
@ensure_csrf_cookie
...
...
lms/djangoapps/verify_student/services.py
View file @
ca08b979
...
...
@@ -34,7 +34,7 @@ class ReverificationService(object):
except
ObjectDoesNotExist
:
return
None
def
start_verification
(
self
,
course_id
,
checkpoint_name
,
item_id
):
# pylint: disable=W0613
def
start_verification
(
self
,
course_id
,
checkpoint_name
,
item_id
):
""" Get or create the verification checkpoint and return the re-verification link
Args:
...
...
@@ -46,5 +46,5 @@ class ReverificationService(object):
"""
course_key
=
CourseKey
.
from_string
(
course_id
)
VerificationCheckpoint
.
objects
.
get_or_create
(
course_id
=
course_key
,
checkpoint_name
=
checkpoint_name
)
re_verification_link
=
reverse
(
"verify_student_incourse_reverify"
,
args
=
(
course_id
,
checkpoint_name
))
re_verification_link
=
reverse
(
"verify_student_incourse_reverify"
,
args
=
(
course_id
,
checkpoint_name
,
item_id
))
return
re_verification_link
lms/djangoapps/verify_student/tests/test_views.py
View file @
ca08b979
...
...
@@ -20,7 +20,7 @@ from django.core.exceptions import ObjectDoesNotExist
from
django.core
import
mail
from
bs4
import
BeautifulSoup
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
xmodule.modulestore.tests.factories
import
CourseFactory
from
xmodule.modulestore.tests.factories
import
CourseFactory
,
ItemFactory
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore
import
ModuleStoreEnum
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
...
...
@@ -1701,20 +1701,42 @@ class TestInCourseReverifyView(ModuleStoreTestCase):
IMAGE_DATA
=
"abcd,1234"
MIDTERM
=
"midterm"
def
setUp
(
self
):
super
(
TestInCourseReverifyView
,
self
)
.
setUp
()
self
.
user
=
UserFactory
.
create
(
username
=
"rusty"
,
password
=
"test"
)
self
.
client
.
login
(
username
=
"rusty"
,
password
=
"test"
)
def
build_course
(
self
):
"""
Build up a course tree with a Reverificaiton xBlock.
"""
# pylint: disable=attribute-defined-outside-init
self
.
course_key
=
SlashSeparatedCourseKey
(
"Robot"
,
"999"
,
"Test_Course"
)
CourseFactory
.
create
(
org
=
'Robot'
,
number
=
'999'
,
display_name
=
'Test Course'
)
self
.
course
=
CourseFactory
.
create
(
org
=
'Robot'
,
number
=
'999'
,
display_name
=
'Test Course'
)
# Create the course modes
for
mode
in
(
'audit'
,
'honor'
,
'verified'
):
min_price
=
0
if
mode
in
[
"honor"
,
"audit"
]
else
1
CourseModeFactory
(
mode_slug
=
mode
,
course_id
=
self
.
course_key
,
min_price
=
min_price
)
# Create the 'edx-reverification-block' in course tree
section
=
ItemFactory
.
create
(
parent
=
self
.
course
,
category
=
'chapter'
,
display_name
=
'Test Section'
)
subsection
=
ItemFactory
.
create
(
parent
=
section
,
category
=
'sequential'
,
display_name
=
'Test Subsection'
)
vertical
=
ItemFactory
.
create
(
parent
=
subsection
,
category
=
'vertical'
,
display_name
=
'Test Unit'
)
reverification
=
ItemFactory
.
create
(
parent
=
vertical
,
category
=
'edx-reverification-block'
,
display_name
=
'Test Verification Block'
)
self
.
section_location
=
section
.
location
self
.
subsection_location
=
subsection
.
location
self
.
vertical_location
=
vertical
.
location
self
.
reverification_location
=
reverification
.
location
def
setUp
(
self
):
super
(
TestInCourseReverifyView
,
self
)
.
setUp
()
self
.
build_course
()
self
.
user
=
UserFactory
.
create
(
username
=
"rusty"
,
password
=
"test"
)
self
.
client
.
login
(
username
=
"rusty"
,
password
=
"test"
)
# Enroll the user in the default mode (honor) to emulate
CourseEnrollment
.
enroll
(
self
.
user
,
self
.
course_key
,
mode
=
"verified"
)
self
.
config
=
InCourseReverificationConfiguration
(
enabled
=
True
)
...
...
@@ -1863,4 +1885,8 @@ class TestInCourseReverifyView(ModuleStoreTestCase):
"""
return
reverse
(
'verify_student_incourse_reverify'
,
kwargs
=
{
"course_id"
:
unicode
(
course_key
),
"checkpoint_name"
:
checkpoint
})
kwargs
=
{
"course_id"
:
unicode
(
course_key
),
"checkpoint_name"
:
checkpoint
,
"location"
:
unicode
(
self
.
reverification_location
)
})
lms/djangoapps/verify_student/urls.py
View file @
ca08b979
...
...
@@ -143,7 +143,7 @@ urlpatterns = patterns(
# Users are sent to this end-point from within courseware
# to re-verify their identities by re-submitting face photos.
url
(
r'^reverify/{course_id}/{checkpoint}/$'
.
format
(
r'^reverify/{course_id}/{checkpoint}/
(?P<location>.*)/
$'
.
format
(
course_id
=
settings
.
COURSE_ID_PATTERN
,
checkpoint
=
settings
.
CHECKPOINT_PATTERN
),
views
.
InCourseReverifyView
.
as_view
(),
...
...
lms/djangoapps/verify_student/views.py
View file @
ca08b979
...
...
@@ -24,9 +24,10 @@ from django.utils.decorators import method_decorator
from
django.utils.translation
import
ugettext
as
_
,
ugettext_lazy
from
django.contrib.auth.decorators
import
login_required
from
django.core.mail
import
send_mail
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys.edx.keys
import
CourseKey
,
UsageKey
from
opaque_keys
import
InvalidKeyError
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
,
NoPathToItem
from
edxmako.shortcuts
import
render_to_response
,
render_to_string
from
openedx.core.djangoapps.user_api.accounts.api
import
get_account_settings
,
update_account_settings
...
...
@@ -55,7 +56,7 @@ from util.json_request import JsonResponse
from
util.date_utils
import
get_default_time_display
from
eventtracking
import
tracker
import
analytics
from
courseware.url_helpers
import
get_redirect_url
log
=
logging
.
getLogger
(
__name__
)
...
...
@@ -1089,7 +1090,7 @@ class InCourseReverifyView(View):
Does not need to worry about pricing
"""
@method_decorator
(
login_required
)
def
get
(
self
,
request
,
course_id
,
checkpoint_name
):
def
get
(
self
,
request
,
course_id
,
checkpoint_name
,
location
):
""" Display the view for face photo submission"""
# Check the in-course re-verification is enabled or not
incourse_reverify_enabled
=
InCourseReverificationConfiguration
.
current
()
.
enabled
...
...
@@ -1120,11 +1121,12 @@ class InCourseReverifyView(View):
'course_name'
:
course
.
display_name_with_default
,
'checkpoint_name'
:
checkpoint_name
,
'platform_name'
:
settings
.
PLATFORM_NAME
,
'location'
:
location
}
return
render_to_response
(
"verify_student/incourse_reverify.html"
,
context
)
@method_decorator
(
login_required
)
def
post
(
self
,
request
,
course_id
,
checkpoint_name
):
def
post
(
self
,
request
,
course_id
,
checkpoint_name
,
location
):
"""Submits the re-verification attempt to SoftwareSecure
Args:
...
...
@@ -1143,7 +1145,11 @@ class InCourseReverifyView(View):
raise
Http404
user
=
request
.
user
course_key
=
CourseKey
.
from_string
(
course_id
)
try
:
course_key
=
CourseKey
.
from_string
(
course_id
)
usage_key
=
UsageKey
.
from_string
(
location
)
.
replace
(
course_key
=
course_key
)
except
InvalidKeyError
:
raise
Http404
(
u"Invalid course_key or usage_key"
)
course
=
modulestore
()
.
get_course
(
course_key
)
checkpoint
=
VerificationCheckpoint
.
get_verification_checkpoint
(
course_key
,
checkpoint_name
)
if
checkpoint
is
None
:
...
...
@@ -1156,6 +1162,7 @@ class InCourseReverifyView(View):
'error'
:
True
,
'errorMsg'
:
_
(
"No checkpoint found"
),
'platform_name'
:
settings
.
PLATFORM_NAME
,
'location'
:
location
}
return
render_to_response
(
"verify_student/incourse_reverify.html"
,
context
)
init_verification
=
SoftwareSecurePhotoVerification
.
get_initial_verification
(
user
)
...
...
@@ -1175,12 +1182,20 @@ class InCourseReverifyView(View):
EVENT_NAME_USER_SUBMITTED_INCOURSE_REVERIFY
,
user
.
id
,
course_id
,
checkpoint_name
)
return
HttpResponse
()
try
:
redirect_url
=
get_redirect_url
(
course_key
,
usage_key
)
except
(
ItemNotFoundError
,
NoPathToItem
):
redirect_url
=
reverse
(
"courseware"
,
args
=
(
unicode
(
course_key
),))
return
JsonResponse
({
'url'
:
redirect_url
})
except
Http404
as
expt
:
log
.
exception
(
"Invalid location during photo verification."
)
return
HttpResponseBadRequest
(
expt
.
message
)
except
IndexError
:
log
.
exception
(
"Invalid image data during photo verification."
)
return
HttpResponseBadRequest
(
_
(
"Invalid image data during photo verification."
))
except
Exception
:
# pylint: disable=broad-except
log
.
exception
(
"Could not submit verification attempt for user
{}."
)
.
format
(
request
.
user
.
id
)
log
.
exception
(
"Could not submit verification attempt for user
%
s."
,
request
.
user
.
id
)
msg
=
_
(
"Could not submit photos"
)
return
HttpResponseBadRequest
(
msg
)
...
...
lms/static/js/verify_student/incourse_reverify.js
View file @
ca08b979
...
...
@@ -22,6 +22,7 @@
courseKey
:
el
.
data
(
'course-key'
),
checkpointName
:
el
.
data
(
'checkpoint-name'
),
platformName
:
el
.
data
(
'platform-name'
),
location
:
el
.
data
(
'location'
),
errorModel
:
errorView
.
model
}).
render
();
...
...
lms/static/js/verify_student/models/reverification_model.js
View file @
ca08b979
...
...
@@ -18,18 +18,20 @@ var edx = edx || {};
courseKey
:
''
,
checkpointName
:
''
,
faceImage
:
''
,
location
:
''
},
sync
:
function
(
method
)
{
var
model
=
this
;
var
headers
=
{
'X-CSRFToken'
:
$
.
cookie
(
'csrftoken'
)
},
data
=
{
face_image
:
model
.
get
(
'faceImage'
)
,
face_image
:
model
.
get
(
'faceImage'
)
},
url
=
_
.
str
.
sprintf
(
'/verify_student/reverify/%(courseKey)s/%(checkpointName)s/'
,
{
'/verify_student/reverify/%(courseKey)s/%(checkpointName)s/
%(location)s/
'
,
{
courseKey
:
model
.
get
(
'courseKey'
),
checkpointName
:
model
.
get
(
'checkpointName'
)
checkpointName
:
model
.
get
(
'checkpointName'
),
location
:
model
.
get
(
'location'
)
}
);
...
...
@@ -38,8 +40,8 @@ var edx = edx || {};
type
:
'POST'
,
data
:
data
,
headers
:
headers
,
success
:
function
()
{
model
.
trigger
(
'sync'
);
success
:
function
(
response
)
{
model
.
trigger
(
'sync'
,
response
.
url
);
},
error
:
function
(
error
)
{
model
.
trigger
(
'error'
,
error
);
...
...
lms/static/js/verify_student/views/incourse_reverify_view.js
View file @
ca08b979
...
...
@@ -28,11 +28,13 @@
this
.
courseKey
=
obj
.
courseKey
||
null
;
this
.
checkpointName
=
obj
.
checkpointName
||
null
;
this
.
platformName
=
obj
.
platformName
||
null
;
this
.
location
=
obj
.
location
||
null
;
this
.
model
=
new
edx
.
verify_student
.
ReverificationModel
({
courseKey
:
this
.
courseKey
,
checkpointName
:
this
.
checkpointName
checkpointName
:
this
.
checkpointName
,
location
:
this
.
location
});
this
.
listenTo
(
this
.
model
,
'sync'
,
_
.
bind
(
this
.
handleSubmitPhotoSuccess
,
this
));
...
...
@@ -75,10 +77,10 @@
this
.
model
.
save
();
},
handleSubmitPhotoSuccess
:
function
()
{
handleSubmitPhotoSuccess
:
function
(
redirect_url
)
{
// Eventually this will be a redirect back into the courseware,
// but for now we can return to the student dashboard.
window
.
location
.
href
=
'/dashboard'
;
window
.
location
.
href
=
redirect_url
;
},
handleSubmissionError
:
function
(
xhr
)
{
...
...
lms/templates/verify_student/incourse_reverify.html
View file @
ca08b979
...
...
@@ -46,6 +46,7 @@ checkpoint_name=checkpoint_name)}
data-course-key=
'${course_key}'
data-checkpoint-name=
'${checkpoint_name}'
data-platform-name=
'${platform_name}'
data-location=
'${location}'
></div>
</section>
</div>
...
...
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