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
775ae010
Commit
775ae010
authored
Aug 20, 2013
by
David Ormsbee
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Shorted names of models in verify_student
parent
8f572e53
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
68 additions
and
26 deletions
+68
-26
lms/djangoapps/verify_student/models.py
+23
-15
lms/djangoapps/verify_student/tests/test_models.py
+10
-9
lms/djangoapps/verify_student/urls.py
+15
-0
lms/djangoapps/verify_student/views.py
+20
-2
No files found.
lms/djangoapps/verify_student/models.py
View file @
775ae010
...
@@ -4,8 +4,8 @@ Models for Student Identity Verification
...
@@ -4,8 +4,8 @@ Models for Student Identity Verification
This is where we put any models relating to establishing the real-life identity
This is where we put any models relating to establishing the real-life identity
of a student over a period of time. Right now, the only models are the abstract
of a student over a period of time. Right now, the only models are the abstract
`PhotoVerification
Attempt
`, and its one concrete implementation
`PhotoVerification`, and its one concrete implementation
`SoftwareSecurePhotoVerification
Attempt
`. The hope is to keep as much of the
`SoftwareSecurePhotoVerification`. The hope is to keep as much of the
photo verification process as generic as possible.
photo verification process as generic as possible.
"""
"""
from
datetime
import
datetime
from
datetime
import
datetime
...
@@ -63,14 +63,14 @@ def status_before_must_be(*valid_start_statuses):
...
@@ -63,14 +63,14 @@ def status_before_must_be(*valid_start_statuses):
return
decorator_func
return
decorator_func
class
PhotoVerification
Attempt
(
StatusModel
):
class
PhotoVerification
(
StatusModel
):
"""
"""
Each PhotoVerification
Attempt
represents a Student's attempt to establish
Each PhotoVerification represents a Student's attempt to establish
their identity by uploading a photo of themselves and a picture ID. An
their identity by uploading a photo of themselves and a picture ID. An
attempt actually has a number of fields that need to be filled out at
attempt actually has a number of fields that need to be filled out at
different steps of the approval process. While it's useful as a Django Model
different steps of the approval process. While it's useful as a Django Model
for the querying facilities, **you should only create and edit a
for the querying facilities, **you should only create and edit a
`PhotoVerification
Attempt
` object through the methods provided**. Do not
`PhotoVerification` object through the methods provided**. Do not
just construct one and start setting fields unless you really know what
just construct one and start setting fields unless you really know what
you're doing.
you're doing.
...
@@ -96,9 +96,9 @@ class PhotoVerificationAttempt(StatusModel):
...
@@ -96,9 +96,9 @@ class PhotoVerificationAttempt(StatusModel):
Because this Model inherits from StatusModel, we can also do things like::
Because this Model inherits from StatusModel, we can also do things like::
attempt.status == PhotoVerification
Attempt
.STATUS.created
attempt.status == PhotoVerification.STATUS.created
attempt.status == "created"
attempt.status == "created"
pending_requests = PhotoVerification
Attempt
.submitted.all()
pending_requests = PhotoVerification.submitted.all()
"""
"""
######################## Fields Set During Creation ########################
######################## Fields Set During Creation ########################
# See class docstring for description of status states
# See class docstring for description of status states
...
@@ -154,24 +154,33 @@ class PhotoVerificationAttempt(StatusModel):
...
@@ -154,24 +154,33 @@ class PhotoVerificationAttempt(StatusModel):
class
Meta
:
class
Meta
:
abstract
=
True
abstract
=
True
ordering
=
[
'-created_at'
]
##### Methods listed in the order you'd typically call them
##### Methods listed in the order you'd typically call them
@classmethod
@classmethod
def
user_is_verified
(
cls
,
user_id
):
def
user_is_verified
(
cls
,
user
):
"""Returns whether or not a user has satisfactorily proved their
"""
Returns whether or not a user has satisfactorily proved their
identity. Depending on the policy, this can expire after some period of
identity. Depending on the policy, this can expire after some period of
time, so a user might have to renew periodically."""
time, so a user might have to renew periodically."""
raise
NotImplementedError
raise
NotImplementedError
@classmethod
@classmethod
def
active_for_user
(
cls
,
user_id
):
def
active_for_user
(
cls
,
user
):
"""Return all PhotoVerificationAttempts that are still active (i.e. not
"""
Return all PhotoVerifications that are still active (i.e. not
approved or denied).
approved or denied).
Should there only be one active at any given time for a user? Enforced
Should there only be one active at any given time for a user? Enforced
at the DB level?
at the DB level?
"""
"""
raise
NotImplementedError
# This should only be one at the most, but just in case we create more
# by mistake, we'll grab the most recently created one.
active_attempts
=
cls
.
objects
.
filter
(
user
=
user
,
status
=
'created'
)
if
active_attempts
:
return
active_attempts
[
0
]
else
:
return
None
@status_before_must_be
(
"created"
)
@status_before_must_be
(
"created"
)
def
upload_face_image
(
self
,
img
):
def
upload_face_image
(
self
,
img
):
...
@@ -315,10 +324,10 @@ class PhotoVerificationAttempt(StatusModel):
...
@@ -315,10 +324,10 @@ class PhotoVerificationAttempt(StatusModel):
self
.
save
()
self
.
save
()
class
SoftwareSecurePhotoVerification
Attempt
(
PhotoVerificationAttempt
):
class
SoftwareSecurePhotoVerification
(
PhotoVerification
):
"""
"""
Model to verify identity using a service provided by Software Secure. Much
Model to verify identity using a service provided by Software Secure. Much
of the logic is inherited from `PhotoVerification
Attempt
`, but this class
of the logic is inherited from `PhotoVerification`, but this class
encrypts the photos.
encrypts the photos.
Software Secure (http://www.softwaresecure.com/) is a remote proctoring
Software Secure (http://www.softwaresecure.com/) is a remote proctoring
...
@@ -368,4 +377,3 @@ class SoftwareSecurePhotoVerificationAttempt(PhotoVerificationAttempt):
...
@@ -368,4 +377,3 @@ class SoftwareSecurePhotoVerificationAttempt(PhotoVerificationAttempt):
)
)
rsa_cipher
=
PKCS1_OAEP
.
new
(
key
)
rsa_cipher
=
PKCS1_OAEP
.
new
(
key
)
rsa_encrypted_aes_key
=
rsa_cipher
.
encrypt
(
aes_key
)
rsa_encrypted_aes_key
=
rsa_cipher
.
encrypt
(
aes_key
)
lms/djangoapps/verify_student/tests/test_models.py
View file @
775ae010
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
from
nose.tools
import
assert_in
,
assert_is_none
,
assert_equals
,
\
from
nose.tools
import
(
assert_raises
,
assert_not_equals
assert_in
,
assert_is_none
,
assert_equals
,
assert_raises
,
assert_not_equals
)
from
django.test
import
TestCase
from
django.test
import
TestCase
from
student.tests.factories
import
UserFactory
from
student.tests.factories
import
UserFactory
from
verify_student.models
import
PhotoVerificationAttempt
,
VerificationException
from
verify_student.models
import
SoftwareSecurePhotoVerification
,
VerificationException
class
TestPhotoVerification
Attempt
(
object
):
class
TestPhotoVerification
(
object
):
def
test_state_transitions
(
self
):
def
test_state_transitions
(
self
):
"""Make sure we can't make unexpected status transitions.
"""Make sure we can't make unexpected status transitions.
...
@@ -14,12 +15,12 @@ class TestPhotoVerificationAttempt(object):
...
@@ -14,12 +15,12 @@ class TestPhotoVerificationAttempt(object):
The status transitions we expect are::
The status transitions we expect are::
created → ready → submitted → approved
created → ready → submitted → approved
↑ ↓
↑ ↓
→ denied
→ denied
"""
"""
user
=
UserFactory
.
create
()
user
=
UserFactory
.
create
()
attempt
=
PhotoVerificationAttempt
(
user
=
user
)
attempt
=
SoftwareSecurePhotoVerification
(
user
=
user
)
assert_equals
(
attempt
.
status
,
PhotoVerificationAttempt
.
STATUS
.
created
)
assert_equals
(
attempt
.
status
,
SoftwareSecurePhotoVerification
.
STATUS
.
created
)
assert_equals
(
attempt
.
status
,
"created"
)
assert_equals
(
attempt
.
status
,
"created"
)
# This should fail because we don't have the necessary fields filled out
# This should fail because we don't have the necessary fields filled out
...
@@ -38,7 +39,7 @@ class TestPhotoVerificationAttempt(object):
...
@@ -38,7 +39,7 @@ class TestPhotoVerificationAttempt(object):
assert_equals
(
attempt
.
status
,
"ready"
)
assert_equals
(
attempt
.
status
,
"ready"
)
# Once again, state transitions should fail here. We can't approve or
# Once again, state transitions should fail here. We can't approve or
# deny anything until it's been placed into the submitted state -- i.e.
# deny anything until it's been placed into the submitted state -- i.e.
# the user has clicked on whatever agreements, or given payment, or done
# the user has clicked on whatever agreements, or given payment, or done
# whatever the application requires before it agrees to process their
# whatever the application requires before it agrees to process their
# attempt.
# attempt.
...
...
lms/djangoapps/verify_student/urls.py
View file @
775ae010
...
@@ -25,4 +25,19 @@ urlpatterns = patterns(
...
@@ -25,4 +25,19 @@ urlpatterns = patterns(
views
.
final_verification
,
views
.
final_verification
,
name
=
"verify_student/final_verification"
name
=
"verify_student/final_verification"
),
),
# The above are what we did for the design mockups, but what we're really
# looking at now is:
url
(
r'^show_verification_page'
,
views
.
show_verification_page
,
name
=
"verify_student/show_verification_page"
),
url
(
r'^start_or_resume_attempt'
,
views
.
start_or_resume_attempt
,
name
=
"verify_student/start_or_resume_attempt"
)
)
)
lms/djangoapps/verify_student/views.py
View file @
775ae010
...
@@ -4,14 +4,26 @@
...
@@ -4,14 +4,26 @@
"""
"""
from
mitxmako.shortcuts
import
render_to_response
from
mitxmako.shortcuts
import
render_to_response
from
verify_student.models
import
SoftwareSecurePhotoVerification
# @login_required
# @login_required
def
start_or_resume_attempt
(
request
):
def
start_or_resume_attempt
(
request
,
course_id
):
"""
"""
If they've already started a PhotoVerificationAttempt, we move to wherever
If they've already started a PhotoVerificationAttempt, we move to wherever
they are in that process. If they've completed one, then we skip straight
they are in that process. If they've completed one, then we skip straight
to payment.
to payment.
"""
"""
pass
# If the user has already been verified within the given time period,
# redirect straight to the payment -- no need to verify again.
#if SoftwareSecurePhotoVerification.user_is_verified(user):
# pass
attempt
=
SoftwareSecurePhotoVerification
.
active_for_user
(
request
.
user
)
if
not
attempt
:
# Redirect to show requirements
pass
# if attempt.
def
show_requirements
(
request
):
def
show_requirements
(
request
):
"""This might just be a plain template without a view."""
"""This might just be a plain template without a view."""
...
@@ -29,3 +41,9 @@ def photo_id_upload(request):
...
@@ -29,3 +41,9 @@ def photo_id_upload(request):
def
final_verification
(
request
):
def
final_verification
(
request
):
context
=
{
"course_id"
:
"edX/Certs101/2013_Test"
}
context
=
{
"course_id"
:
"edX/Certs101/2013_Test"
}
return
render_to_response
(
"verify_student/final_verification.html"
,
context
)
return
render_to_response
(
"verify_student/final_verification.html"
,
context
)
#
def
show_verification_page
(
request
):
pass
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