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¶
- Admin creates a cohort with an ID number (this becomes the enrollment code)
- Admin sets up cohort sync to enroll cohort members in specific courses
- Supervisor provides the code to users (via Discord, email, etc.)
- User visits the Get Roles page at
/getroles.html - User enters the code and clicks "ASSIGN ROLE"
- System validates the code and adds user to the cohort
- 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¶
- Navigate to the Get Roles page
- Click in the code input field
- 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:
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:
- Cohorts are standard Moodle user groups
- Each cohort's "Cohort ID" (idnumber) becomes the enrollment code
- Users enter the Cohort ID to join the cohort
- Cohort sync enrollment automatically enrolls cohort members in courses
Required Setup¶
- Create cohorts with descriptive names and ID numbers
- Add cohort sync enrollment to courses
- Distribute codes to supervisors/users
Creating Cohort Codes¶
Step 1: Create a Cohort¶
- Go to Site administration > Users > Cohorts
- Click "Add new cohort"
- 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 |
- 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:
- Go to the course
- Navigate to Course administration > Users > Enrolment methods
- Select "Cohort sync" from the "Add method" dropdown
- 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 |
- Click "Add method"
Step 3: Distribute the Code¶
Share the Cohort ID with users via:
- Discord announcements
- 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¶
- Each failed attempt (invalid code) is counted
- Attempts are tracked by both user ID and IP address
- After reaching the limit, user must wait the lockout duration
- Successful attempts reset the counter
- Attempts automatically expire after the rate limit window
Recommended Settings¶
| 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:
Error Response:
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:
- Verify cohort exists in Site admin > Users > Cohorts
- Check that "Cohort ID" field is set (not just the name)
- 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:
- Verify cohort sync is added to course enrollment methods
- Run cohort sync:
- Check user is in correct cohort
Rate limit hit too quickly¶
Causes:
- Settings too restrictive
- Multiple users on same network/IP
Solutions:
- Adjust rate limit settings in plugin configuration
- Increase attempts or window time
- Consider IP-based vs user-based limiting
Page shows "You must be logged in"¶
Causes:
- Session expired
- Not logged in
Solutions:
- Log in to the LMS first
- Then navigate to Get Roles page
- 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:
Or for an IP address:
Integration with Discord¶
The Get Roles system works alongside the Discord Integration plugin:
Workflow with Discord¶
- Discord roles can automatically add users to cohorts (via Discord plugin)
- Cohort codes provide a manual alternative for users without Discord
- 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¶
- Get code from supervisor
- Go to
/getroles.html - Enter code, click "ASSIGN ROLE"
- Access your new courses
For Admins¶
- Create cohort with ID number (the code)
- Add cohort sync to courses
- Distribute code to supervisors
- Monitor via attempt logs
For Supervisors¶
- Get approved codes from admin
- Distribute to team members
- Direct users to Get Roles page
- Report any access issues to admin
Support¶
For issues with the Get Roles system:
- Users: Contact your supervisor or training coordinator
- Supervisors: Contact LMS administrator
- Admins: Check troubleshooting section above or contact [email protected]