Skip to content

Commit

Permalink
Merge pull request #491 from ucsd-ets/alisalman/restrict-users
Browse files Browse the repository at this point in the history
Only allow certain email to access courses
  • Loading branch information
Ali-Salman29 authored Dec 12, 2022
2 parents cfd9f82 + b30c627 commit a9df544
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 3 deletions.
13 changes: 12 additions & 1 deletion common/lib/xmodule/xmodule/course_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -1028,7 +1028,18 @@ class CourseFields(object):
),
scope=Scope.settings
)

restricted_organizations = List(
display_name=_("Restrict Course"),
help=_(
"Restrict course only to certain organizations, "
"the default values is ['*'], it means all organization can access this course. "
"To only allow ucsd emails, replace list with [\"ucsd.\"]. This allow all domains of ucsd i.e [email protected], [email protected]."
"To further restric top level domains you can specify [domain].[top-level-domaain] i.e [\"ucsd.com\", \"ucsd.ca\", \"gmail.com\"]. "
"Similary, you can add as many domains in the list to allow specific organization students to access this course"
),
scope=Scope.settings,
default=['*'],
)

class CourseModule(CourseFields, SequenceModule): # pylint: disable=abstract-method
"""
Expand Down
17 changes: 16 additions & 1 deletion lms/djangoapps/courseware/access_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Simple utility functions for computing access.
It allows us to share code between access.py and block transformers.
"""

import re

from datetime import datetime, timedelta
from logging import getLogger
Expand Down Expand Up @@ -167,3 +167,18 @@ def check_public_access(course, visibilities):
return ACCESS_GRANTED

return ACCESS_DENIED

def check_organization_access(user, course):
"""
Checks if the urers belogs to certain organization
"""
organizations_regexes = course.restricted_organizations
if '*' in organizations_regexes:
return ACCESS_GRANTED

email = user.email if user.is_authenticated else ''
for regex in organizations_regexes:
if re.match(f'^[a-zA-Z0-9_.+-]+@{regex}', email):
return ACCESS_GRANTED

return ACCESS_DENIED
13 changes: 12 additions & 1 deletion lms/djangoapps/courseware/courses.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
from lms.djangoapps.courseware.access_utils import (
check_authentication,
check_enrollment,
check_organization_access,
)
from lms.djangoapps.courseware.courseware_access_exception import CoursewareAccessException
from lms.djangoapps.courseware.exceptions import CourseAccessRedirect
Expand Down Expand Up @@ -129,6 +130,7 @@ def get_course_with_access(user, action, course_key, depth=0, check_if_enrolled=
"""
course = get_course_by_id(course_key, depth)
check_course_access_with_redirect(course, user, action, check_if_enrolled, check_survey_complete, check_if_authenticated)
check_course_organization_access_with_redirect(course, user)
return course


Expand Down Expand Up @@ -196,6 +198,15 @@ def _check_nonstaff_access():
# This access_response will be ACCESS_GRANTED
return nonstaff_access_response

def check_course_organization_access_with_redirect(course, user):
"""
Check that the user has access to the organization courses
Only those users are allowed to see the course content that are either staff members or
are logedin with emails from certain organizations i.e ucsd.edu
"""
access_response = has_access(user, 'staff', course.id) or check_organization_access(user, course)
if not access_response:
raise CourseAccessRedirect(reverse('courses'), access_response)

def check_course_access_with_redirect(course, user, action, check_if_enrolled=False, check_survey_complete=True, check_if_authenticated=False):
"""
Expand Down Expand Up @@ -685,7 +696,7 @@ def get_courses(user, org=None, filter_=None):
)

return LazySequence(
(c for c in courses if has_access(user, permission_name, c)),
(c for c in courses if has_access(user, permission_name, c) and check_organization_access(user, get_course_by_id(c.id))),
est_len=courses.count()
)

Expand Down

0 comments on commit a9df544

Please sign in to comment.