Running the Demo Application
This guide covers how to build, run, and access the django-ldaporm demo
application, which showcases the library’s features with a complete web
interface.
Prerequisites
Before running the demo, ensure you have:
Docker and Docker Compose: Required for running the demo with LDAP services
docker --version docker-compose --version
Dependencies: Install all required dependencies
uv sync --group=demo --dev
Python Environment: Activate the project’s virtual environment
source .venv/bin/activate
Demo Overview
The demo application provides:
User Management: Create, edit, and delete LDAP users
REST API: Full CRUD operations via API endpoints
LDAP Integration: Real LDAP server connectivity
Demo Architecture
The demo consists of several components:
Django Application: Main web application
LDAP Server: 389 Directory Server for user data
Database: MySQL for Django models
Web Server: Nginx for static file serving
Application Server: Gunicorn for Django application
Quick Start with Docker
The easiest way to run the demo is using Docker Compose:
Navigate to the sandbox directory:
cd sandbox
Build the demo application:
# tars up ../ldaporm into a tar file in the sandbox directory make package # builds the docker image from the tar file make build
Run the LDAP server and load the data:
docker-compose up -d ldap docker exec -ti ldap bash > dsconf localhost backend create --suffix "o=example,c=us" --be-name example > ^D cd data/ldap/init ./load_data.sh docker-compose down ldap The data will be loaded into the LDAP server, and saved to the volume ``django_ldaporm_demo_ldap_data`` for persistence.
Run the demo application:
make devThis will run the demo application and automatically run all the migrations and load the initial fixture data, including Django user data.
Access the demo:
Main Application: https://localhost
API Endpoints: https://localhost/api/
Since this is a development demo, there is no authentication. You can just browse the application and API endpoints.
Docker Services
The demo includes several Docker services:
Web Application (django_ldaporm_demo)
Nginx reverse proxy
Gunicorn WSGI server
Port: 443
Mounts the
./demofolder over/ve/lib/python3.13/site-packages/sandbox/demoAlso mounts
../ldapormfolder over/ve/lib/python3.13/site-packages/ldaporm
LDAP Server (ldap)
389 Directory Server
Port: 389 (LDAP), 636 (LDAPS)
Admin DN:
cn=Directory ManagerAdmin Password:
passwordData is persisted in the
django_ldaporm_demo_ldap_datavolume
Note
After following the instructions above, this LDAP server will be configured
to use the o=example,c=us suffix. This is the default suffix for the
demo data.
For whatever reason, I could not get
nsRoleattributes to appear on the users inside the 389-ds server. I checked many things:
The “Roles Plugin” is installed and enabled
The roles we create have the proper object classes
The
nsslapd-ignore-virtual-attrsis automatically set tooff(enablingnsRole, a virtual attribute, to be populated) when we load the role objects (you can see this in the ldap startup logs)The roles assigned to
nsRoleDNon each user each have adnthat corresponds to an actual role objectThe
nsFilteredRoleDefinitionobjects just don’t seem to do anythingI assure you that in our production environment, all this works fine.
Database (mysql)
MySQL database
Port: 3306
Database:
demoUser:
demo_uPassword:
passwordRoot Password:
root_passwordData is persisted in the
django_ldaporm_demo_datavolume
Configuration
The demo uses different settings files for different environments:
Docker Settings (settings_docker.py)
Used when building the Docker image
Development Settings (settings.py)
Local development configuration
Debug mode enabled
MySQL database
Test Settings (settings_test.py)
Test-specific configuration
In-memory database
Mock LDAP connections
Demo Features
User Management
Browse all LDAP users
Create new users
Edit user attributes
Delete users
Search and filter users
Group Management
Browse all LDAP groups
Create new groups
Edit group attributes
Delete groups
Search and filter groups
Role Management
Browse all LDAP roles
Search and filter roles
- REST API
Full CRUD operations
JSON responses
Filtering and pagination
Authentication support
API Endpoints
The demo provides REST API endpoints for managing users, groups, and roles:
Users API
GET /api/users/ - List all users
POST /api/users/ - Create new user
GET /api/users/{username}/ - Get user details
PUT /api/users/{username}/ - Update user
PATCH /api/users/{username}/ - Partial update user
DELETE /api/users/{username}/ - Delete user
Groups API
GET /api/groups/ - List all groups
POST /api/groups/ - Create new group
GET /api/groups/{group_name}/ - Get group details
PUT /api/groups/{group_name}/ - Update group
PATCH /api/groups/{group_name}/ - Partial update group
DELETE /api/groups/{group_name}/ - Delete group
Roles API
GET /api/roles/ - List all roles
POST /api/roles/ - Create new role
GET /api/roles/{role_name}/ - Get role details
PUT /api/roles/{role_name}/ - Update role
PATCH /api/roles/{role_name}/ - Partial update role
DELETE /api/roles/{role_name}/ - Delete role
Example API Usage
Since this is a development demo, there is no authentication. You can just browse the application and API endpoints.
Here are some example API calls:
List all users:
curl --insecure https://localhost/api/users/
Filter users:
curl --insecure https://localhost/api/users/?employee_type=manager
Create a new user:
curl --insecure -X POST -H "Content-Type: application/json" \ -d '{"uid": "newuser", "first_name": "New", "last_name": "User", "employee_type": "developer", "full_name": "New User", "mail": ["newuser@example.com"]}' \ https://localhost/api/users/
Update just the first name of a user:
curl --insecure -X PATCH -H "Content-Type: application/json" \ -d '{"first_name": "Updated"}' \ https://localhost/api/users/newuser/
Delete a user:
curl --insecure -X DELETE https://localhost/api/users/newuser/
Troubleshooting
Docker Issues
Service won’t start:
# Check service logs docker-compose logs web docker-compose logs ldap docker-compose logs db # Restart services docker-compose down docker-compose up -d
Port conflicts:
Ensure ports 443, 389, 636 and 3306 are available
Change ports in docker-compose.yml if needed
LDAP Connection Issues
Cannot connect to LDAP server:
# Test LDAP connection ldapsearch -H ldap://localhost:389 -D "cn=admin,ou=example,c=us" -w password123 -b "ou=example,c=us" # Check LDAP server status docker-compose exec ldap ldapsearch -x -b "ou=example,c=us"
Authentication failures:
Verify LDAP_BIND_DN and LDAP_BIND_PASSWORD
Check LDAP server logs
Ensure user exists in LDAP
Database Issues
Migration errors:
# Start the demo stack make dev # In another terminal make exec ./manage.py migrate
Connection refused:
Wait for database to fully start
Check database logs: docker-compose logs db
Development Workflow
Making Changes
Edit code in the appropriate directory
Test changes locally or with Docker
Run tests to ensure nothing is broken
Commit changes with descriptive messages
Adding New Features
Create models in demo/core/models.py
Add views in demo/core/views/
Create templates in demo/core/templates/
Add URL patterns in demo/core/urls.py
Write tests in demo/core/tests/
Database Changes
Create migrations:
python manage.py makemigrations
Apply migrations:
python manage.py migrate
For Docker:
docker-compose exec web python manage.py makemigrations docker-compose exec web python manage.py migrate
Performance Tuning
Database Optimization
Use database indexes for frequently queried fields
Optimize LDAP queries with proper filters
Use connection pooling for LDAP connections
Caching
Enable Django caching for frequently accessed data
Cache LDAP query results where appropriate
Use Redis for session storage in production
Monitoring
Monitor LDAP connection performance
Track database query performance
Monitor application response times
Security Considerations
Production Deployment
Use HTTPS in production
Secure LDAP connections with LDAPS
Implement proper authentication and authorization
Use environment variables for sensitive data
Regular security updates
LDAP Security
Use strong passwords for LDAP bind accounts
Implement LDAP access controls
Monitor LDAP access logs
Use LDAPS for encrypted connections
Application Security
Keep Django and dependencies updated
Use Django’s security middleware
Implement proper input validation
Use HTTPS for all communications
Cleanup
Stop Docker services:
cd sandbox make clean