Skip to content

Cohort Enrollment (Get Roles)

Plugin: PulseTech Cohort Enrollment (local_pulsetech_cohort)
Version: 1.0.0 (2025010500)
Compatibility: Moodle 4.5+ / Moodle 5.0


Overview

The PulseTech Cohort Enrollment plugin (commonly referred to as "Get Roles") provides a simple, user-friendly way for members to self-enroll into cohorts using enrollment codes. This enables:

  • Self-service role assignment - Users can join training groups without admin intervention
  • Code-based access control - Supervisors distribute codes to grant access to specific programs
  • Automatic course enrollment - Via cohort sync, joining a cohort automatically enrolls users in associated courses
  • Rate limiting protection - Prevents brute-force code guessing attacks

Key Benefits

Benefit Description
Simplicity Users only need to enter a single code
Scalability Supervisors can distribute codes to many users without admin work
Security Rate limiting and attempt logging prevent abuse
Flexibility Codes map to any cohort, which can sync to any courses

How It Works

System Flow

flowchart LR
    A[Supervisor] -->|1. Gets code| B[User]
    B -->|2. Enters code on Get Roles page| C[PulseLMS]
    C -->|3. Validates & adds to cohort| D[Cohort Sync]
    D -->|4. Enrolls user in courses| E[Course Access]

Step-by-Step Process

  1. Admin creates a cohort with an ID number (this becomes the enrollment code)
  2. Admin sets up cohort sync to enroll cohort members in specific courses
  3. Supervisor provides the code to users (via Discord, email, etc.)
  4. User visits the Get Roles page at /getroles.html
  5. User enters the code and clicks "ASSIGN ROLE"
  6. System validates the code and adds user to the cohort
  7. Cohort sync automatically enrolls user in associated courses

User Guide

Accessing the Get Roles Page

Direct URL: https://your-site.com/getroles.html

From Navigation:

  • Log in to the LMS
  • Click "Get Roles" in the navigation menu

Step 1: Obtain Your Code

Before using the Get Roles page, you need an enrollment code. Codes are provided by:

  • Your supervisor
  • Training coordinator
  • Via Discord announcements

Example codes: DISPATCH, PATROL101, FTO-PHASE1, ADMIN-ACCESS

Step 2: Enter Your Code

  1. Navigate to the Get Roles page
  2. Click in the code input field
  3. Type your code exactly as provided
    • Codes are not case-sensitive (uppercase/lowercase doesn't matter)
    • Remove any extra spaces

Step 3: Submit

Click the "ASSIGN ROLE" button to submit your code.

Step 4: Check the Result

Success Message:

Role assigned successfully! You have been added to: [Cohort Name]

After success:

  • Click "RETURN TO MY COURSES" to access your new courses
  • Your course access is immediate

Error Messages

Error Meaning Solution
"Please enter a code" Empty input Enter a valid code
"Invalid code" Code doesn't exist Check spelling, contact supervisor
"Already enrolled in this cohort" You've already used this code No action needed, you already have access
"Too many attempts" Rate limit reached Wait the indicated time before trying again
"You must be logged in" Not authenticated Log in first, then try again

Tips for Users

  • Codes are provided by supervisors - Don't guess codes
  • Enter codes exactly - Copy/paste if possible
  • One code per role - You may need multiple codes for different training programs
  • Wait if rate limited - The system protects against abuse; wait the indicated time
  • Contact support if you have issues - Don't repeatedly try invalid codes

Administrator Guide

Plugin Location

The plugin is installed at /var/www/moodle/local/pulsetech_cohort/

Accessing Settings

Navigate to: Site administration > Plugins > Local plugins > PulseTech Cohort Enrollment

Understanding the System

The Get Roles system uses Moodle cohorts with their built-in ID Number field as enrollment codes:

  1. Cohorts are standard Moodle user groups
  2. Each cohort's "Cohort ID" (idnumber) becomes the enrollment code
  3. Users enter the Cohort ID to join the cohort
  4. Cohort sync enrollment automatically enrolls cohort members in courses

Required Setup

  1. Create cohorts with descriptive names and ID numbers
  2. Add cohort sync enrollment to courses
  3. Distribute codes to supervisors/users

Creating Cohort Codes

Step 1: Create a Cohort

  1. Go to Site administration > Users > Cohorts
  2. Click "Add new cohort"
  3. Fill in the details:
Field Description Example
Name Display name for the cohort "Patrol Training Phase 1"
Cohort ID THE ENROLLMENT CODE PATROL-PHASE1
Description What this cohort grants access to "Phase 1 patrol training program"
Context Where cohort is visible System (for site-wide)
Visible Whether users can see it Yes
  1. Click "Save changes"

The Cohort ID is the Code

The Cohort ID field is what users will enter on the Get Roles page. Make it memorable and easy to communicate.

Step 2: Set Up Cohort Sync (Course Enrollment)

For each course the cohort should grant access to:

  1. Go to the course
  2. Navigate to Course administration > Users > Enrolment methods
  3. Select "Cohort sync" from the "Add method" dropdown
  4. Configure:
Setting Description Recommended
Cohort Select the cohort you created (your cohort)
Assign role Role to assign in course Student
Add to group Optionally add to a course group None or as needed
  1. Click "Add method"

Step 3: Distribute the Code

Share the Cohort ID with users via:

  • Discord announcements
  • Email
  • Training materials
  • Supervisor communication

Best Practices for Codes

Practice Reason
Use descriptive codes DISPATCH-TRAINING is clearer than DT01
Use uppercase Easier to communicate verbally
Avoid special characters Simpler to type
Keep codes short Easier to remember and enter
Use hyphens for readability FTO-PHASE-1 vs FTOPHASE1

Example Cohort Setup

Cohort Name Cohort ID (Code) Associated Course Role
FTO Phase 1 Trainees FTO-PHASE1 FTO Training Phase 1 Student
Dispatch Certification DISPATCH Dispatch Operations Student
Supervisor Access SUPERVISOR Supervisor Portal Teacher
Admin Staff ADMIN-ACCESS Admin Dashboard Manager

Configuration Settings

Access settings at: Site administration > Plugins > Local plugins > PulseTech Cohort Enrollment

Rate Limiting Settings

Setting Default Description
Rate limit attempts 5 Maximum failed attempts before lockout
Rate limit window 5 minutes Time window for counting attempts
Lockout duration 15 minutes How long user is locked out after exceeding limit

How Rate Limiting Works

  1. Each failed attempt (invalid code) is counted
  2. Attempts are tracked by both user ID and IP address
  3. After reaching the limit, user must wait the lockout duration
  4. Successful attempts reset the counter
  5. Attempts automatically expire after the rate limit window
Environment Attempts Window Lockout
High Security 3 10 min 30 min
Standard (default) 5 5 min 15 min
Lenient 10 5 min 10 min

Security Features

Rate Limiting

Prevents brute-force attacks:

  • Configurable attempt limits
  • Dual tracking (user ID + IP address)
  • Automatic lockout after threshold

Attempt Logging

All attempts are logged in local_pulsetech_cohort_attempts table:

  • User ID
  • IP address
  • Attempted code
  • Success/failure
  • Timestamp

Server-Side Validation

  • Codes validated against actual cohort idnumbers
  • Case-insensitive matching (forgiving for users)
  • Duplicate enrollment prevention
  • User must be logged in

Client-Side Protection

  • Additional rate limiting in browser
  • Visual feedback during processing
  • Disabled button during requests

Database Schema

Table: local_pulsetech_cohort_codes

Stores optional custom enrollment codes (if using advanced code management).

Column Type Description
id INT Primary key
code VARCHAR(64) The enrollment code (uppercase, unique)
name VARCHAR(255) Display name
description TEXT Description of what code grants
cohortid INT FK to cohort table
courseid INT Direct course enrollment (optional)
roleid INT Role to assign (optional)
enabled INT(1) Whether code is active
max_uses INT Maximum uses (null = unlimited)
use_count INT Current usage count
expires_at INT Expiration timestamp
success_message TEXT Custom success message
timecreated INT Creation timestamp
timemodified INT Modification timestamp

Table: local_pulsetech_cohort_attempts

Tracks enrollment attempts for rate limiting and auditing.

Column Type Description
id INT Primary key
userid INT User who attempted (if logged in)
ip_address VARCHAR(45) IP address of attempt
attempted_code VARCHAR(64) The code that was tried
success INT(1) Whether attempt succeeded
timecreated INT Attempt timestamp

Table: local_pulsetech_cohort_usage

Tracks which users have used which codes (prevents re-use).

Column Type Description
id INT Primary key
userid INT User who used the code
codeid INT Code that was used
timecreated INT Usage timestamp

Technical Reference

File Structure

/var/www/moodle/
├── getroles.html                    # User-facing enrollment page
├── local/
│   ├── cohort_enrollment.php        # AJAX API endpoint
│   └── pulsetech_cohort/
│       ├── version.php              # Plugin version
│       ├── lib.php                  # Library functions
│       ├── settings.php             # Admin settings
│       ├── db/
│       │   ├── install.xml          # Database schema
│       │   └── access.php           # Capabilities
│       └── lang/
│           └── en/
│               └── local_pulsetech_cohort.php
└── theme/
    └── pulsetech/
        ├── lib.php                  # Adds "Get Roles" to navigation
        └── fto_enrollment.js        # Alternative enrollment JS

API Endpoint

URL: /local/cohort_enrollment.php

Method: POST

Parameters:

Parameter Type Required Description
action string Yes Must be enroll
code string Yes The enrollment code

Success Response:

{
  "success": true,
  "message": "Role assigned successfully! You have been added to: Cohort Name"
}

Error Response:

{
  "success": false,
  "message": "Invalid code. Please check and try again."
}

Capabilities

Capability Purpose Default
local/pulsetech_cohort:manage Manage enrollment settings Manager

Troubleshooting

"Invalid code" when code should be valid

Causes:

  • Typo in code entry
  • Cohort doesn't exist
  • Cohort ID (idnumber) not set on cohort

Solutions:

  1. Verify cohort exists in Site admin > Users > Cohorts
  2. Check that "Cohort ID" field is set (not just the name)
  3. Try the exact Cohort ID from admin panel

User can't access courses after successful enrollment

Causes:

  • Cohort sync not set up on course
  • Cohort sync scheduled task hasn't run
  • Different cohort than expected

Solutions:

  1. Verify cohort sync is added to course enrollment methods
  2. Run cohort sync:
    php admin/cli/scheduled_task.php --execute='\enrol_cohort\task\enrol_cohort_sync'
    
  3. Check user is in correct cohort

Rate limit hit too quickly

Causes:

  • Settings too restrictive
  • Multiple users on same network/IP

Solutions:

  1. Adjust rate limit settings in plugin configuration
  2. Increase attempts or window time
  3. Consider IP-based vs user-based limiting

Page shows "You must be logged in"

Causes:

  • Session expired
  • Not logged in

Solutions:

  1. Log in to the LMS first
  2. Then navigate to Get Roles page
  3. Check session timeout settings

Viewing Attempt Logs

To audit enrollment attempts, query the database:

SELECT
    u.username,
    a.ip_address,
    a.attempted_code,
    CASE WHEN a.success = 1 THEN 'Success' ELSE 'Failed' END as result,
    FROM_UNIXTIME(a.timecreated) as attempt_time
FROM mdl_local_pulsetech_cohort_attempts a
LEFT JOIN mdl_user u ON a.userid = u.id
ORDER BY a.timecreated DESC
LIMIT 100;

Clearing Rate Limits

To clear rate limits for a specific user:

DELETE FROM mdl_local_pulsetech_cohort_attempts
WHERE userid = [USER_ID] AND success = 0;

Or for an IP address:

DELETE FROM mdl_local_pulsetech_cohort_attempts
WHERE ip_address = '[IP_ADDRESS]' AND success = 0;

Integration with Discord

The Get Roles system works alongside the Discord Integration plugin:

Workflow with Discord

  1. Discord roles can automatically add users to cohorts (via Discord plugin)
  2. Cohort codes provide a manual alternative for users without Discord
  3. Both methods result in cohort membership, which syncs to course enrollment

Use Cases

Scenario Method
User has Discord and verified Automatic via Discord role sync
User doesn't have Discord Manual via Get Roles page
Guest/temporary access Provide one-time code
Training program signup Supervisor distributes code

Best Practice

  • Use Discord role sync for primary role management
  • Use Get Roles codes for:
    • Users without Discord access
    • Special/temporary training programs
    • Quick group signups during events

Quick Reference

For Users

  1. Get code from supervisor
  2. Go to /getroles.html
  3. Enter code, click "ASSIGN ROLE"
  4. Access your new courses

For Admins

  1. Create cohort with ID number (the code)
  2. Add cohort sync to courses
  3. Distribute code to supervisors
  4. Monitor via attempt logs

For Supervisors

  1. Get approved codes from admin
  2. Distribute to team members
  3. Direct users to Get Roles page
  4. Report any access issues to admin

Support

For issues with the Get Roles system:

  1. Users: Contact your supervisor or training coordinator
  2. Supervisors: Contact LMS administrator
  3. Admins: Check troubleshooting section above or contact [email protected]