Telephony Toolbox is a web application for managing Cisco UCM Call Forward All (CFA) diversions with strict destination validation, role-based access control, comprehensive audit logging, and flexible authentication support.
Telephony Toolbox provides a safe, audited interface for authorized users to update diversion destinations for pre-defined Cisco UCM Directory Numbers, using the UCM AXL API as the source of truth for live state.
It is designed to be extensible so that if core telephony platforms are later moved from CUCM to a different application (eg Asterisk, Freeswitch, or hosted provider) then the user experience for diversion management remains consistent, with the backend API calls modified appropriately.
- Diversion Management: View and update Call Forward All destinations for assigned diversions
- Strict Validation: Destination numbers are validated and normalized to Australian +E.164 format
- Role-Based Access: Two application roles (Standard User, App Admin) with group-based diversion access
- Flexible Authentication: Support for Entra (OIDC), LDAP, or local user authentication with CSRF protection
- Audit Logging: Complete audit trail with 90-day retention for compliance
- CUCM Integration: Uses Cisco AXL API with support for CUCM versions 8.0–14
- AudioCodes CDR Analysis: App Admin-only, read-only search and analysis of SDR sessions and associated CDR legs, using a separately configured AudioCodes PostgreSQL source
- Responsive UI: Quasar Vue 3 frontend with admin dashboards for user and group management
- Graceful Degradation: Allows cached state viewing when CUCM is unavailable; blocks edits
- Frontend: Quasar SPA on Vue 3 with responsive Quasar components
- Backend: Django 5.2 + Django REST Framework with session authentication
- Database: PostgreSQL in production; SQLite for local development
- Authentication: Django sessions with CSRF; Entra OIDC, LDAP, and local users
- CUCM Integration: Zeep SOAP client with versioned local WSDL schemas
- Deployment: nginx (static files & proxy), Gunicorn, systemd on RHEL 9
- ARCHITECTURE.md — System design, data flow, and component interactions
- API_SPECIFICATION.md — REST API endpoints, authentication, and request/response formats
- CONFIGURATION.md — Environment variables and deployment settings
- AUTHENTICATION.md — Authentication flows and identity provider setup
- DEVELOPMENT.md — Local development setup and testing
- DEPLOYMENT.md — Production deployment on RHEL 9 with nginx and Gunicorn
- audiocodes-cdr-manager-specification.md — AudioCodes CDR module requirements and behaviour
- AUDIOCODES_CDR_IMPLEMENTATION_CHECKLIST.md — Implementation status, confirmed decisions, and known implementation differences
- AUDIOCODES_CDR_INDEX_RECOMMENDATIONS.md — DBA-only source index recommendations; not applied by the application
- Python 3.10+
- Node.js 24+ with npm
- PostgreSQL (optional; SQLite used by default)
-
Clone the repository and navigate to the root directory.
-
Create an environment file:
cp scripts/env.example .env
-
Create and activate a Python virtual environment:
python3 -m venv .venv source .venv/bin/activate pip install -r backend/requirements.txt -
Install frontend dependencies:
npm --prefix frontend install
-
Run database migrations:
python backend/manage.py migrate
-
(Optional) Create a bootstrap app admin:
python backend/manage.py bootstrap_local_app_admin \ --email admin@example.com \ --display-name "App Admin" \ --password 'ChangeMeNow!'
-
Start the development servers:
# Starts backend on http://localhost:8000 and frontend on http://localhost:9000 scripts/dev.sh start # Stop both development servers scripts/dev.sh stop
The script loads the repository-local
.envfile, which is excluded from git. Usescripts/dev.sh status,scripts/dev.sh restart backend, orscripts/dev.sh stop frontendto control individual services.
Run tests from the repository root:
# Backend tests
.venv/bin/pytest
# Frontend validation
npm --prefix frontend run lint:check
npm --prefix frontend run buildAudioCodes backend tests use isolated unmanaged-table fixtures and do not require the live source:
pytest backend/audiocodes_cdr/tests| Role | Capabilities |
|---|---|
| Standard User | View assigned diversions, update CFA destinations (when CUCM available), audit access |
| App Admin | Full user and group management, create/edit/delete diversions, access all groups' diversions, export audit logs, health monitoring |
| App Admin | Full user and group management, create/edit/delete diversions, access all groups' diversions, export audit logs, health monitoring, read-only AudioCodes SDR/CDR search and analysis |
Accepted destination formats:
- Australian FNN:
(02, 03, 07, 08) + 8 digits→ normalized to+612...or+613...etc. - Australian Mobile:
04 + 8 digits→ normalized to+614... - E.164 Format:
+61...(Australian country code only)
Rejected:
- Internal extensions (< 10 digits)
- International numbers (including
0011prefix) - SIP URIs and email-like formats
- Blank destinations
- Leading + characters outside +61 format
Simplest setup; no database configuration needed. Suitable for testing and feature development.
See DEPLOYMENT.md for full production setup with nginx, Gunicorn, systemd, and SELinux configuration.
backend/ # Django REST Framework backend
accounts/ # User management, authentication, roles
access_groups/ # Group definitions and memberships
diversions/ # Diversion CRUD and update operations
audit/ # Audit event logging and export
audiocodes_cdr/ # Read-only AudioCodes SDR/CDR integration, search, stats and settings
audiocodes_cdr/ # Read-only AudioCodes SDR/CDR integration, search, stats and settings
cucm/ # CISCO AXL client and schemas
dialplan/ # Phone number validation and normalization
health/ # System health endpoints
telephony_toolbox/ # Django configuration and URL routing
frontend/ # Quasar Vue 3 SPA
src/
pages/ # Page components (login, diversions, admin)
components/ # Reusable UI components
stores/ # Pinia state management
services/ # API client and business logic
router/ # Route definitions
docs/ # Documentation (this directory)
ARCHITECTURE.md
API_SPECIFICATION.md
CONFIGURATION.md
AUTHENTICATION.md
DEVELOPMENT.md
DEPLOYMENT.md
scripts/ # Deployment and utility scripts
install-rhel-baremetal.sh
upgrade-rhel-baremetal.sh
wsdl/ # Versioned CISCO AXL WSDL schemas
CUCM is unavailable: Check backend logs and CUCM AXL connectivity. The UI shows "unavailable" status; cached diversions remain viewable but edits are blocked.
Authentication fails: Verify ENTRA or LDAP settings in .env. Check authentication provider connectivity and user existence.
Database migration errors: Ensure Django settings reference the correct database backend (PostgreSQL or SQLite).
For more details, see DEVELOPMENT.md and DEPLOYMENT.md.
App Admins can open AudioCodes CDR from the existing application navigation. The module is
served by the same Quasar SPA, Django API, session, CSRF configuration, Gunicorn service and
deployment as the rest of Telephony Toolbox. It has no separate login, service, application
database, or source-data copy. Its SPA pages are under /admin/cdr; its API is under
/api/admin/cdr/.
The application database stores module settings and user display preferences. SDR and CDR rows
are queried live from the selected external AudioCodes PostgreSQL source using unmanaged models,
a guarded read-only connection, and a PostgreSQL account that must be provisioned with SELECT
access only. Source profile credentials are encrypted in the application database using the
deployment-only CDR_SOURCE_ENCRYPTION_KEY. App Admins configure profiles and module settings in
the in-app settings page; a read replica is selected by default and source failover is never
automatic.
Before production use, complete the AudioCodes source provisioning steps in DEPLOYMENT.md. The RHEL install/upgrade scripts generate the encryption key when it is blank (never overwriting an existing key), create the application cache table, align Gunicorn/Nginx request timeouts with the source statement timeout, and redact CDR query strings from Gunicorn and Nginx access logs. See the implementation checklist for status.
- Fresh RHEL 9 install: scripts/install-rhel-baremetal.sh
- Upgrade existing RHEL 9 deployment: scripts/upgrade-rhel-baremetal.sh
- Environment template: scripts/env.example
- Systemd template: scripts/templates/telephonytoolbox-gunicorn.service.template
The RHEL install flow defaults to /opt/telephonytoolbox, binds Gunicorn to 127.0.0.1:8010, creates a dedicated nginx site under sites-enabled, and prompts for APP_HOSTNAME when it is not already supplied in the environment.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.