3.9 KiB
3.9 KiB
IT Hardware Asset Management System
A full-featured web application built with Python / Flask + MySQL, containerised with Docker Compose.
Features
| Module | Capabilities |
|---|---|
| Users | Manual, CSV, and LDAP/AD import · search · GDPR masking |
| Assets | Track by Serial Number + Service Tag · full history |
| Assignments | Assign/return assets · complete audit trail |
| Paperwork | Generate PDF documents (handover, assignment, return, custom) |
| Audit Log | Immutable log of every create / update / delete / mask action |
| Settings | Admin user management · LDAP config view |
User masking (GDPR / off-boarding)
When an employee leaves, press Mask User to permanently erase PII (name, email, phone).
The record is kept — linked by the permanent Windows ID — so full asset history is preserved for audits, without exposing personal data.
Quick Start (Docker Compose)
# 1. Copy the example env file and fill in your values
cp .env.example .env
nano .env
# 2. Build and start
docker compose up -d --build
# 3. Open the app
http://localhost:5000
# Default credentials (change immediately in Settings!)
Username: admin
Password: ChangeMe123!
Running locally (without Docker)
# 1. Create a virtual environment
python -m venv venv
source venv/bin/activate # Linux/macOS
# venv\Scripts\activate # Windows
# 2. Install dependencies
pip install -r requirements.txt
# 3. Configure environment
cp .env.example .env
# Edit .env — set MYSQL_HOST=localhost and your DB credentials
# 4. Initialise the database
flask db init
flask db migrate -m "initial"
flask db upgrade
python init_db.py
# 5. Run
python run.py
Environment Variables (.env)
| Variable | Description | Default |
|---|---|---|
SECRET_KEY |
Flask secret key | (must change) |
MYSQL_HOST |
MySQL host | db (Docker) / localhost |
MYSQL_USER |
MySQL user | itasset_user |
MYSQL_PASSWORD |
MySQL password | itasset_pass |
MYSQL_DB |
Database name | itasset_db |
LDAP_SERVER |
LDAP server URL | (blank = disabled) |
LDAP_BIND_USER |
Service account DN | — |
LDAP_BIND_PASSWORD |
Service account password | — |
LDAP_BASE_DN |
Search base | — |
LDAP_WINDOWS_ID_ATTR |
AD attribute for numeric ID | employeeID |
COMPANY_NAME |
Shown on PDF headers | Your Company Name |
COMPANY_ADDRESS |
Shown on PDF headers | — |
DEFAULT_ADMIN_USER |
First-run admin username | admin |
DEFAULT_ADMIN_PASS |
First-run admin password | ChangeMe123! |
CSV Import Format
windows_id,first_name,last_name,email,department,job_title,location
408525,John,Doe,john.doe@company.com,IT,Engineer,HQ
408526,Jane,Smith,jane.smith@company.com,HR,Manager,HQ
Column names are matched case-insensitively. windows_id is required; all others are optional.
Project Structure
IT_asset_management/
├── app/
│ ├── __init__.py # App factory
│ ├── extensions.py # SQLAlchemy, Flask-Login, Migrate
│ ├── models/ # User, Asset, Assignment, Paperwork, AuditLog, AdminUser
│ ├── routes/ # auth, dashboard, users, assets, assignments, paperwork, audit, settings
│ ├── services/ # csv_service, ldap_service, pdf_service
│ └── templates/ # Jinja2 + Bootstrap 5
├── config.py
├── run.py
├── init_db.py
├── requirements.txt
├── Dockerfile
├── docker-compose.yml
└── .env.example
Security Notes
- Change
DEFAULT_ADMIN_PASSimmediately after first login. - Set a strong random
SECRET_KEYin.env. - The LDAP bind password is read from the environment — never commit
.envto source control. - PDF files are stored server-side in the
pdfs/directory (Docker volume). Restrict access as needed. - Masked user records permanently destroy PII and cannot be reversed.