Skip to content

Conversation

@efortish
Copy link
Contributor

@efortish efortish commented Aug 29, 2025

Related Issue: https://github.com/fccn/nau-technical/issues/580

Enrollment by Domain Filter

This new feature in nau-openedx-extensions allows restricting course enrollment based on user email domains. It integrates with the openedx-filters framework to automatically validate domains during the enrollment process.

Features

  • Automatic Domain Filtering: Blocks enrollment for users whose email domains are not in the allowed list
  • Course-Level Configuration: Enable/disable filtering per course via Advanced Settings
  • Simple Domain Management: Import domains via command or manage through Django Admin
  • Custom Error Messages: Configure personalized error messages at course or list level
  • Instructor Override: Preserves compatibility with manual enrollment allowlists

Quick Start

1. Configure OpenEdX Filters

Add to your Tutor plugin configuration:

from tutor import hooks

hooks.Filters.ENV_PATCHES.add_item(
    (
        "openedx-lms-common-settings",
        """
OPEN_EDX_FILTERS_CONFIG = {
    "org.openedx.learning.course.enrollment.started.v1": {
        "fail_silently": False,
        "pipeline": [
            "nau_openedx_extensions.enrollment_by_domain.domain_filter.FilterEnrollmentByAllowedList"
        ]
    }
}
"""
    )
)
hooks.Filters.ENV_PATCHES.add_item(
    (
        "openedx-common-settings",
"""
FEATURES["ENABLE_OTHER_COURSE_SETTINGS"] = True

"""
    )
)

2. Create Domain List

# Basic import with minimal options
python manage.py lms import_enrollment_domains example_domains.txt university-partners

Note: You must use the files relative or absolute path, example: ../extra/nau-openedx-extensions/nau_openedx_extensions/enrollment_by_domain/example_domains.txt

3. Configure Course

In StudioAdvanced SettingsOther Course Settings:

{
    "filter_enrollment_allowed_list_code": "university-partners"
}

Domain Management

Import Command Syntax

python manage.py lms import_enrollment_domains <file.txt> <list-code> [options]

Command Options

Option Description
--description "text" List description
--custom-message "text" Custom error message

Domain File Format

# University domains (comments start with #)
university.edu
student.university.edu
faculty.university.edu

# Partner institutions
partner.org
collaborator.ac.uk
alumni.university.edu

# Empty lines and comments are ignored

Usage Examples

Basic Usage

# Simple domain import
python manage.py lms import_enrollment_domains domains.txt list-code

# With description
python manage.py lms import_enrollment_domains domains.txt list-code --description "Partner universities"

# With custom error message
python manage.py lms import_enrollment_domains domains.txt list-code --custom-message "Contact admissions@university.edu for access"

# Full configuration
python manage.py lms import_enrollment_domains domains.txt list-code --description "Partner universities" --custom-message "Only partner university students can enroll"

Example 1: University Partners

# txt file
# Main universities
university.edu
partneruniv.edu
college.edu

# Student domains
students.university.edu
alumni.university.edu


# Import domains
python manage.py lms import_enrollment_domains university_domains.txt university-partners --description "Partner universities" --custom-message "Only students from partner universities can enroll. Contact admissions@university.edu for assistance."

Course Configuration in Studio:

{
    "filter_enrollment_allowed_list_code": "university-partners"
}

Example 2: Corporate Training Program

# Create corporate domains .txt file
# Primary companies
company.com
corporation.org
business.net

# Subsidiaries
subsidiary1.company.com
subsidiary2.company.com
EOF

# Import corporate domains
python manage.py lms import_enrollment_domains corporate_domains.txt corporate-training --description "Corporate training participants" --custom-message "This course is restricted to employees of partner companies."

Example 3: Multiple Domain Lists

# University partners list
python manage.py lms import_enrollment_domains university_domains.txt uni-partners --description "University partners"

# Corporate partners list
python manage.py lms import_enrollment_domains corporate_domains.txt corp-partners --description "Corporate partners"

# Alumni program list
python manage.py lms import_enrollment_domains alumni_domains.txt alumni-program --description "Alumni program participants"

Example 4: Adding More Domains

# Add new domains to existing list
python manage.py lms import_enrollment_domains additional_partners.txt university-partners

# Update existing list with new description and message
python manage.py lms import_enrollment_domains updated_domains.txt university-partners --description "Updated partner list" --custom-message "New enrollment policy applies"

Note: The command only adds new domains. Existing domains are preserved and duplicates are automatically skipped.

Course Configuration

Enable Filter for a Course

  1. Go to StudioSettingsAdvanced Settings
  2. Find "Other Course Settings" or add new field
  3. Add configuration:
{
    "filter_enrollment_allowed_list_code": "your-list-code"
}

Custom Error Messages

Option 1: List-level message (affects all courses using this list)

python manage.py lms import_enrollment_domains domains.txt my-list --custom-message "Contact support@example.com for enrollment assistance."

Option 2: Course-level message (overrides list message for this course)

{
    "filter_enrollment_allowed_list_code": "my-list",
    "filter_enrollment_by_domain_custom_exception_message": "This course is restricted to university partners only."
}

If the custom exception message is not defined, it will use a default message

Priority Order for Error Messages

  1. Course-level custom message (from Advanced Settings)
  2. List-level custom message (from import command or Django admin)
  3. Default message: "You can't enroll on this course because your email domain is not allowed. If you think this is an error, contact the course support."

Command Output Examples

New List Creation

============================================================
 IMPORT SUMMARY: university-partners
============================================================
 Created new allowed list

   Domain Statistics:
   Domains in file: 8
   Domains to add: 8
   Domains unchanged: 0
   Import completed successfully!
   Added: 8 domains
   Total domains in list: 8
============================================================

Adding to Existing List

============================================================
 IMPORT SUMMARY: university-partners
============================================================
  Found existing allowed list

   Domain Statistics:
   Domains in file: 10
   Domains to add: 2
   Domains unchanged: 8

   Import completed successfully!
   Added: 2 domains
   Total domains in list: 10
============================================================

No Changes Needed

============================================================
 IMPORT SUMMARY: university-partners
============================================================
  Found existing allowed list

   Domain Statistics:
   Domains in file: 8
   Domains to add: 0
   Domains unchanged: 8

   No changes needed
   All domains already in list
   Total domains in list: 8
============================================================

How It Works

Filter Activation

  1. User attempts enrollment in a course
  2. OpenEdX Event org.openedx.learning.course.enrollment.started.v1
  3. Filter checks if course has filter_enrollment_allowed_list_code configured
  4. If configured, validates user's email domain against the allowed list
  5. Blocks enrollment if domain is not allowed
  6. Shows custom message to the user

Django Admin Management

Access domain management through Django Admin:

  1. Go to /admin/
  2. Navigate to "Enrollment By Domain" section
  3. Manage "Enrollment Allowed Lists" and "Enrollment Allowed Domains"

Best Practices

  1. Use descriptive list codes (university-partners, not list1)
  2. Set custom messages for better user experience
  3. Test thoroughly after configuration changes

@efortish efortish force-pushed the ks/enrollment_by_domain_v2 branch from 53d9ac9 to 9e3b0c6 Compare August 29, 2025 21:24
@efortish efortish marked this pull request as ready for review August 29, 2025 21:24
@efortish efortish changed the title Ks/enrollment by domain v2 feat: new enrollment by domain system Aug 29, 2025
@efortish efortish force-pushed the ks/enrollment_by_domain_v2 branch from 685588d to dc9944b Compare September 1, 2025 22:26
@sandroscosta
Copy link
Contributor

@efortish
I'll save this to test later on as, for now, the priority is to get the Teak upgrade going and making sure everything is working as intended. Thanks.

@efortish
Copy link
Contributor Author

efortish commented Sep 26, 2025

Hello @sandroscosta

Sounds good!

Have a good day

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants