Deadline for comments: July 22, 2015
Status of the document: Proposal
Collaborators: Jim Abramson (Deactivated)
...
In the diagram:
The "photo verification service" is provided by an external vendor called Software Secure.
At the reverification checkpoint, users submit photos of their faces, which the photo verification service compares with photos of the user’s government-issued photo ID. Users submits ID photos during an "initial" verification process after enrolling in a course.
Users are allowed to resubmit (shown as a dashed line) only if the assessment is open and the user has not exceeded the attempt limit, which is configurable per-checkpoint.
In its current implementation, in-course reverification does not prevent users from accessing exam content before they submit photos for verification. Before we release this feature, we need to introduce an access control mechanism that can handle the following cases.
ICRV controls access to exam content.
When a student reaches an ICRV checkpoint, the student does not have access to exam content.
When a student skips (by clicking the "skip" button in the ICRV XBlock) or submits a reverification attempt (by completing the ICRV reverification flow), the user is allowed access to exam content.
Enrollment mode controls access to ICRV. When the student is not enrolled as "verified", all ICRV blocks should be hidden and the user should have access to all exam content.
ICRV controls access to other ICRV blocks. When the student has failed or skipped an earlier ICRV verification, all later ICRV blocks should be hidden and the user should have access to all exam content.
This document presents a design that satisfies these requirements. The design attempts to balance:
Course Author UX: It should be easy for course authors to add in-course reverification checkpoints to a course. In slightly more pessimistic terms, ICRV should be difficult to misconfigure.
Encapsulation: As much as possible, business logic specific to the verification process should be encapsulated from the core of the system. One way to achieve this is to re-use existing access control mechanisms, which are likely to provide better interoperability, performance, and security while minimizing development time and complexity.
Proposal
We propose a solution built on group-based access control for courseware content:
Implement a partition scheme that assigns users to groups based on their verification status and enrollment mode.
For each in-course reverification XBlock in a course, define a partition with three groups:
non_verified
verified_allow
verified_deny
Set the allowed groups for the ICRV XBlock to ["verified_allow", "verified_deny"]
Set the allowed groups for gated content to ["non_verified", "verified_allow"].
To minimize course author configuration, steps (2), (3), and (4) occur automatically when a version of the course is published.
To illustrate this, we consider an example course after it has been published:
In the diagram, ReverificationBlock has groups ["verified_allow", "verified_deny"], so it will be hidden for users not in the verified track and shown for users in the verified track (regardless of their verification status).
The sibling Vertical has groups ["non_verified", "verified_allow"], so they will be hidden to users who are in the verified track but have not yet submitted/skipped verification for this checkpoint.
Creating User Partitions (On Publish)
On course publish, new user partitions will be added to the course for each in-course reverification checkpoint. If there are existing partitions for checkpoints that have been deleted, they will be removed.
Reverification checkpoints are uniquely identified within a course by the location of the ReverificationBlock. To minimize course configuration outside of Studio, we propose extending the "User Partition" schema to include a new dictionary field called "parameters". This field can be used to pass information to the partition scheme -- in this case, we will use it to pass the location of the ReverificationBlock so the partition scheme can locate the associated reverification checkpoint.
Code Block | ||
---|---|---|
| ||
{ "version": 3, "id": "abcd1234", "name": "Verification Checkpoint for Midterm A", "description": "Verification Checkpoint for Midterm A", "scheme": "verification", "parameters": { "location": "block-v1:edX+DemoX+Demo+type@reverification+block@f02a238efac644e389e930fbf275953e" }, "groups": [ { "version": 1, "id": "non_verified", "name": "Not enrolled in a verified track", }, { "version": 1, "id": "verified_allow", "name": "Enrolled in a verified track and has access" }, { "version": 1, "id": "verified_deny", "name": "Enrolled in a verified track and does not have access" } ] } |
Configuring Groups (On Publish)
Every ReverificationBlock will have group_access for the associated user partition set to [“verified_allow”, “verified_deny”]
The following blocks will have group_access for the associated user partition set to [“non_verified”, “verified_allow”]
Include all siblings of the ReverificationBlock.
If the ReverificationBlock’s parent is a Vertical and its parent is a Subsection (sequential), then include every sibling of the parent Vertical.
These steps will configure groups correctly in most cases. There are two cases that can lead to unusual behavior:
If the ReverificationBlock is part of a content experiment, its grandparent will not be a Subsection, so it will control access to its siblings within the experiment, but not any surrounding content. This is arguably a reasonable way to handle this case.
If two or more ReverificationBlocks are children of the same Vertical or grandchildren of the same Subsection, then users in a verified track will not be able to see either block (or any of the content). Intuitively, reverification checkpoint #1 prevents access to checkpoint #2, and vice-versa. While potentially confusing, there is at least an easy way for course authors to fix the issue: delete all but one of the ReverificationBlocks in a particular subsection.
Partition Scheme
The LMS supports pluggable partition schemes. We will define a new partition scheme that places users into one of the three groups as follows:
Code Block | ||
---|---|---|
| ||
def get_group_for_user(cls, course_key, user, user_partition): checkpoint = user_partition.parameters[“location”] if ( not _is_enrolled_in_verified_mode(user, course_key) or _was_denied_at_other_checkpoint(user, course_key, location) ): return NON_VERIFIED_GROUP elif ( _has_skipped_any_checkpoint(user, course_key) or _has_completed_checkpoint(user, course_key, checkpoint) or _has_preview_permission(user, course_key) ): return VERIFIED_ALLOW_GROUP else: return VERIFIED_DENY_GROUP |
All of the information required for these checks is already available through existing SQL tables:
Enrollment mode is available from the CourseEnrollment table (in the student app).
When a user skips verification for a checkpoint in a course, a SkippedReverification record is created (in the verify_student app).
A user’s verification status at a checkpoint is stored in a VerificationStatus table, with a foreign key to a VerificationCheckpoint table (in the verify_student app).
Certain users (e.g. course staff) will be given permission to preview the exam content without needing to submit a verification attempt. A user’s permission can be calculated from the user’s roles. (The mapping from roles to permissions would be handled by a separate module, not within the verify_student app.)
Preview
Course staff need to be able to preview exam content that is gated by an in-course reverification. We enable this by automatically placing users with the appropriate permission into the “verified_allow” group. This will allow course staff to view both the ReverificationBlock and associated content without requiring them to enroll as verified or submit photos.
It would also be possible to allow users with the appropriate permission to force themselves into a particular group. This could be similar to how we allow course staff to preview different groups in content experiments.
Messaging for Blocked Content
Currently, when a user is denied access to courseware content, the content is completely hidden from the user. One potential enhancement would be for the access checks to provide additional messaging in certain cases to explain to users why they were blocked from accessing content. This proposal does not address messaging for blocked content, except to note that it is compatible with this approach.
There is currently no way to display a “disabled” version of blocked content (for example, displaying the content as “grayed out” with functionality disabled). It is unclear how we could support this functionality without significant changes to the LMS.