446 lines
12 KiB
Markdown
446 lines
12 KiB
Markdown
|
|
# Tinker Tickets SSO Integration - Deployment Guide
|
|||
|
|
|
|||
|
|
## ✅ Implementation Complete
|
|||
|
|
|
|||
|
|
All code for Authelia SSO with LLDAP integration has been implemented. This guide will walk you through deployment and testing.
|
|||
|
|
|
|||
|
|
## 📋 What Was Implemented
|
|||
|
|
|
|||
|
|
### 1. Database Schema (New Tables)
|
|||
|
|
- **users** - Stores user accounts synced from LLDAP
|
|||
|
|
- **api_keys** - Manages API keys for external services (hwmonDaemon)
|
|||
|
|
- **audit_log** - Tracks all user actions for audit trail
|
|||
|
|
|
|||
|
|
### 2. Authentication System
|
|||
|
|
- **AuthMiddleware.php** - Reads Authelia forward auth headers and syncs users
|
|||
|
|
- **ApiKeyAuth.php** - Validates API keys for external services
|
|||
|
|
- Session management with 5-hour timeout
|
|||
|
|
- Group-based access control (admin/employee groups)
|
|||
|
|
|
|||
|
|
### 3. Models
|
|||
|
|
- **UserModel.php** - User CRUD operations and authentication
|
|||
|
|
- **ApiKeyModel.php** - API key generation and validation
|
|||
|
|
- **AuditLogModel.php** - Audit trail logging
|
|||
|
|
- Updated **TicketModel.php** and **CommentModel.php** with user tracking
|
|||
|
|
|
|||
|
|
### 4. Protected Endpoints
|
|||
|
|
- All web pages now require Authelia authentication
|
|||
|
|
- API endpoints require session authentication
|
|||
|
|
- `/create_ticket_api.php` requires API key authentication
|
|||
|
|
|
|||
|
|
### 5. User Interface Updates
|
|||
|
|
- User info header showing logged-in user
|
|||
|
|
- Admin badge for admin users
|
|||
|
|
- Comment display shows user's display name from LLDAP
|
|||
|
|
|
|||
|
|
## 🚀 Deployment Steps
|
|||
|
|
|
|||
|
|
### Step 1: Push Code to Git
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cd /root/code/tinker_tickets
|
|||
|
|
git add .
|
|||
|
|
git commit -m "Add Authelia SSO integration with LLDAP
|
|||
|
|
|
|||
|
|
- Implement user authentication via forward auth headers
|
|||
|
|
- Add API key authentication for hwmonDaemon
|
|||
|
|
- Create audit log for all user actions
|
|||
|
|
- Add user tracking to tickets and comments
|
|||
|
|
- Update views to display user information"
|
|||
|
|
git push origin main
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
The Gitea webhook will automatically deploy to production at 10.10.10.45.
|
|||
|
|
|
|||
|
|
### Step 2: Run Database Migrations
|
|||
|
|
|
|||
|
|
SSH into the production server:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
ssh jared@10.10.10.45
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Navigate to the application directory:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cd /var/www/html/tinkertickets
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Run the migrations:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
php migrations/run_migrations.php
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Expected output:
|
|||
|
|
```
|
|||
|
|
Connected to database: ticketing_system
|
|||
|
|
|
|||
|
|
Found 6 migration(s):
|
|||
|
|
- 001_create_users_table.sql
|
|||
|
|
- 002_create_api_keys_table.sql
|
|||
|
|
- 003_create_audit_log_table.sql
|
|||
|
|
- 004_alter_tickets_table.sql
|
|||
|
|
- 005_alter_comments_table.sql
|
|||
|
|
- 006_add_indexes.sql
|
|||
|
|
|
|||
|
|
Executing: 001_create_users_table.sql... OK
|
|||
|
|
Executing: 002_create_api_keys_table.sql... OK
|
|||
|
|
Executing: 003_create_audit_log_table.sql... OK
|
|||
|
|
Executing: 004_alter_tickets_table.sql... OK
|
|||
|
|
Executing: 005_alter_comments_table.sql... OK
|
|||
|
|
Executing: 006_add_indexes.sql... OK
|
|||
|
|
|
|||
|
|
Migration Summary:
|
|||
|
|
Success: 6
|
|||
|
|
Errors: 0
|
|||
|
|
|
|||
|
|
All migrations completed successfully!
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Step 3: Generate API Key for hwmonDaemon
|
|||
|
|
|
|||
|
|
Since we need an admin user to generate API keys, we'll create a temporary PHP script:
|
|||
|
|
|
|||
|
|
Create `/var/www/html/tinkertickets/generate_api_key.php`:
|
|||
|
|
|
|||
|
|
```php
|
|||
|
|
<?php
|
|||
|
|
require_once 'config/config.php';
|
|||
|
|
require_once 'models/ApiKeyModel.php';
|
|||
|
|
require_once 'models/UserModel.php';
|
|||
|
|
|
|||
|
|
$conn = new mysqli(
|
|||
|
|
$GLOBALS['config']['DB_HOST'],
|
|||
|
|
$GLOBALS['config']['DB_USER'],
|
|||
|
|
$GLOBALS['config']['DB_PASS'],
|
|||
|
|
$GLOBALS['config']['DB_NAME']
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
if ($conn->connect_error) {
|
|||
|
|
die("Connection failed: " . $conn->connect_error);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$userModel = new UserModel($conn);
|
|||
|
|
$apiKeyModel = new ApiKeyModel($conn);
|
|||
|
|
|
|||
|
|
// Get system user (should exist from migration)
|
|||
|
|
$systemUser = $userModel->getSystemUser();
|
|||
|
|
|
|||
|
|
if (!$systemUser) {
|
|||
|
|
die("Error: System user not found. Check migrations.\n");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
echo "System user found: ID " . $systemUser['user_id'] . "\n";
|
|||
|
|
|
|||
|
|
// Generate API key
|
|||
|
|
$result = $apiKeyModel->createKey(
|
|||
|
|
'hwmonDaemon',
|
|||
|
|
$systemUser['user_id'],
|
|||
|
|
null // No expiration
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
if ($result['success']) {
|
|||
|
|
echo "\n✅ API Key generated successfully!\n\n";
|
|||
|
|
echo "API Key: " . $result['api_key'] . "\n";
|
|||
|
|
echo "Key Prefix: " . $result['key_prefix'] . "\n";
|
|||
|
|
echo "\n⚠️ IMPORTANT: Save this API key now! It cannot be retrieved later.\n";
|
|||
|
|
echo "\nAdd this to hwmonDaemon .env file:\n";
|
|||
|
|
echo "TICKET_API_KEY=" . $result['api_key'] . "\n";
|
|||
|
|
} else {
|
|||
|
|
echo "Error generating API key: " . $result['error'] . "\n";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$conn->close();
|
|||
|
|
?>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Run it:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
php generate_api_key.php
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Save the API key output - you'll need it for hwmonDaemon.
|
|||
|
|
|
|||
|
|
Delete the script after use:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
rm generate_api_key.php
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Step 4: Update hwmonDaemon Configuration
|
|||
|
|
|
|||
|
|
On each Proxmox server running hwmonDaemon, update the `.env` file:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# On each Proxmox server
|
|||
|
|
cd /path/to/hwmonDaemon
|
|||
|
|
nano .env
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Add the API key:
|
|||
|
|
|
|||
|
|
```env
|
|||
|
|
TICKET_API_KEY=<paste_the_api_key_here>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Update `hwmonDaemon.py` to send the Authorization header (around line 1198):
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
def create_ticket(self, title, description, priority=4, category="Hardware", ticket_type="Issue"):
|
|||
|
|
"""Create a ticket via the API"""
|
|||
|
|
url = self.CONFIG["TICKET_API_URL"]
|
|||
|
|
|
|||
|
|
payload = {
|
|||
|
|
"title": title,
|
|||
|
|
"description": description,
|
|||
|
|
"priority": priority,
|
|||
|
|
"category": category,
|
|||
|
|
"type": ticket_type
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
headers = {
|
|||
|
|
'Content-Type': 'application/json',
|
|||
|
|
'Authorization': f'Bearer {self.CONFIG["TICKET_API_KEY"]}'
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
try:
|
|||
|
|
response = requests.post(url, json=payload, headers=headers, timeout=10)
|
|||
|
|
response.raise_for_status()
|
|||
|
|
return response.json()
|
|||
|
|
except Exception as e:
|
|||
|
|
logger.error(f"Failed to create ticket: {e}")
|
|||
|
|
return None
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Restart hwmonDaemon:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
sudo systemctl restart hwmonDaemon
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Step 5: Migrate Legacy Data (Optional)
|
|||
|
|
|
|||
|
|
If you want to assign existing comments to a specific user:
|
|||
|
|
|
|||
|
|
1. First, log into the web UI to create your user account in the database
|
|||
|
|
2. Then run this SQL to update existing comments:
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
-- Get jared's user_id (replace with actual value after login)
|
|||
|
|
SELECT user_id FROM users WHERE username = 'jared';
|
|||
|
|
|
|||
|
|
-- Update existing comments (replace 1 with actual user_id)
|
|||
|
|
UPDATE ticket_comments SET user_id = 1 WHERE user_id IS NULL;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 🧪 Testing
|
|||
|
|
|
|||
|
|
### Test 1: Web UI Authentication
|
|||
|
|
|
|||
|
|
1. Open https://t.lotusguild.org in your browser
|
|||
|
|
2. You should be redirected to Authelia login (if not already logged in)
|
|||
|
|
3. Log in with your LLDAP credentials
|
|||
|
|
4. Verify you see your name in the top-right corner
|
|||
|
|
5. If you're in the admin group, verify you see the "Admin" badge
|
|||
|
|
|
|||
|
|
### Test 2: Create Ticket via Web UI
|
|||
|
|
|
|||
|
|
1. Click "New Ticket"
|
|||
|
|
2. Fill out the form
|
|||
|
|
3. Submit the ticket
|
|||
|
|
4. Verify the ticket appears in the dashboard
|
|||
|
|
5. Check the database to confirm `created_by` is set:
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
SELECT ticket_id, title, created_by FROM tickets ORDER BY created_at DESC LIMIT 5;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Test 3: Add Comment
|
|||
|
|
|
|||
|
|
1. Open a ticket
|
|||
|
|
2. Add a comment
|
|||
|
|
3. Verify your display name appears on the comment
|
|||
|
|
4. Check the database to confirm `user_id` is set:
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
SELECT comment_id, ticket_id, user_id, comment_text FROM ticket_comments ORDER BY created_at DESC LIMIT 5;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Test 4: hwmonDaemon API
|
|||
|
|
|
|||
|
|
1. Trigger a hardware issue or manually test the API:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
curl -X POST https://t.lotusguild.org/create_ticket_api.php \
|
|||
|
|
-H "Content-Type: application/json" \
|
|||
|
|
-H "Authorization: Bearer <your_api_key>" \
|
|||
|
|
-d '{
|
|||
|
|
"title": "[test-server][auto][hardware]Test Ticket[single-device][production][warning]",
|
|||
|
|
"description": "This is a test ticket from hwmonDaemon",
|
|||
|
|
"priority": "2",
|
|||
|
|
"category": "Hardware",
|
|||
|
|
"type": "Issue"
|
|||
|
|
}'
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Expected response:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"success": true,
|
|||
|
|
"ticket_id": "123456789",
|
|||
|
|
"message": "Ticket created successfully"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
2. Verify the ticket appears in the dashboard
|
|||
|
|
3. Check the database to confirm `created_by` is the system user:
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
SELECT t.ticket_id, t.title, u.username
|
|||
|
|
FROM tickets t
|
|||
|
|
LEFT JOIN users u ON t.created_by = u.user_id
|
|||
|
|
ORDER BY t.created_at DESC LIMIT 5;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Test 5: Audit Log
|
|||
|
|
|
|||
|
|
Check that actions are being logged:
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
-- View recent audit log entries
|
|||
|
|
SELECT al.*, u.username, u.display_name
|
|||
|
|
FROM audit_log al
|
|||
|
|
LEFT JOIN users u ON al.user_id = u.user_id
|
|||
|
|
ORDER BY al.created_at DESC
|
|||
|
|
LIMIT 20;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
You should see entries for:
|
|||
|
|
- Ticket views
|
|||
|
|
- Ticket creations
|
|||
|
|
- Ticket updates
|
|||
|
|
- Comment creations
|
|||
|
|
|
|||
|
|
## 🔒 Security Notes
|
|||
|
|
|
|||
|
|
1. **API Keys**: The API key generated for hwmonDaemon is shown only once. Store it securely.
|
|||
|
|
2. **Session Timeout**: Web sessions expire after 5 hours of inactivity.
|
|||
|
|
3. **Group Access**: Only users in `admin` or `employee` groups can access the system.
|
|||
|
|
4. **Audit Trail**: All actions are logged with user ID, IP address, and timestamp.
|
|||
|
|
|
|||
|
|
## 🔄 Rollback Procedure
|
|||
|
|
|
|||
|
|
If you need to rollback the changes:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cd /var/www/html/tinkertickets
|
|||
|
|
mysql -u <user> -p ticketing_system < migrations/rollback_all.sql
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Then revert the git commit:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
git revert HEAD
|
|||
|
|
git push origin main
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 📊 Database Indexes Added
|
|||
|
|
|
|||
|
|
For improved performance:
|
|||
|
|
- `tickets.status` - Speeds up status filtering
|
|||
|
|
- `tickets.priority` - Speeds up priority filtering
|
|||
|
|
- `tickets.created_at` - Speeds up date sorting
|
|||
|
|
- `users.username` - Speeds up user lookups
|
|||
|
|
- `audit_log.user_id` - Speeds up user audit queries
|
|||
|
|
- `audit_log.created_at` - Speeds up date-based audit queries
|
|||
|
|
|
|||
|
|
## 🎯 Next Steps (Future Enhancements)
|
|||
|
|
|
|||
|
|
1. **Admin Panel** - Create UI for managing API keys
|
|||
|
|
2. **Bulk Actions** - Admin-only bulk ticket operations
|
|||
|
|
3. **User Audit View** - UI to view audit logs per ticket
|
|||
|
|
4. **Advanced Permissions** - Fine-grained permission system
|
|||
|
|
5. **Email Notifications** - Email users on ticket updates
|
|||
|
|
|
|||
|
|
## 📝 Files Created/Modified
|
|||
|
|
|
|||
|
|
### New Files Created:
|
|||
|
|
- `migrations/001_create_users_table.sql`
|
|||
|
|
- `migrations/002_create_api_keys_table.sql`
|
|||
|
|
- `migrations/003_create_audit_log_table.sql`
|
|||
|
|
- `migrations/004_alter_tickets_table.sql`
|
|||
|
|
- `migrations/005_alter_comments_table.sql`
|
|||
|
|
- `migrations/006_add_indexes.sql`
|
|||
|
|
- `migrations/rollback_all.sql`
|
|||
|
|
- `migrations/run_migrations.php`
|
|||
|
|
- `middleware/AuthMiddleware.php`
|
|||
|
|
- `middleware/ApiKeyAuth.php`
|
|||
|
|
- `models/UserModel.php`
|
|||
|
|
- `models/ApiKeyModel.php`
|
|||
|
|
- `models/AuditLogModel.php`
|
|||
|
|
- `DEPLOYMENT_GUIDE.md` (this file)
|
|||
|
|
|
|||
|
|
### Modified Files:
|
|||
|
|
- `index.php` - Added authentication
|
|||
|
|
- `create_ticket_api.php` - Added API key auth
|
|||
|
|
- `api/add_comment.php` - Added session auth
|
|||
|
|
- `api/update_ticket.php` - Added session auth
|
|||
|
|
- `models/TicketModel.php` - Added user_id parameters
|
|||
|
|
- `models/CommentModel.php` - Added user_id parameters
|
|||
|
|
- `controllers/TicketController.php` - Pass current user, log actions
|
|||
|
|
- `views/TicketView.php` - Display user info
|
|||
|
|
- `views/DashboardView.php` - Display user info
|
|||
|
|
|
|||
|
|
## ❓ Troubleshooting
|
|||
|
|
|
|||
|
|
### Issue: "Authentication Required" error on web UI
|
|||
|
|
|
|||
|
|
**Solution**: Check that Nginx Proxy Manager is sending the forward auth headers:
|
|||
|
|
- Remote-User
|
|||
|
|
- Remote-Groups
|
|||
|
|
- Remote-Name
|
|||
|
|
- Remote-Email
|
|||
|
|
|
|||
|
|
Verify headers are being sent:
|
|||
|
|
|
|||
|
|
```php
|
|||
|
|
<?php
|
|||
|
|
// Create test.php in web root
|
|||
|
|
print_r($_SERVER);
|
|||
|
|
?>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Access https://t.lotusguild.org/test.php and look for `HTTP_REMOTE_USER` in the output.
|
|||
|
|
|
|||
|
|
### Issue: hwmonDaemon tickets failing with 401 Unauthorized
|
|||
|
|
|
|||
|
|
**Solution**:
|
|||
|
|
1. Verify API key is correct in hwmonDaemon `.env`
|
|||
|
|
2. Check that Authorization header is being sent
|
|||
|
|
3. Verify API key exists in database: `SELECT * FROM api_keys WHERE is_active = 1;`
|
|||
|
|
|
|||
|
|
### Issue: Existing comments show "Unknown User"
|
|||
|
|
|
|||
|
|
**Solution**: This is expected for legacy data. To fix:
|
|||
|
|
1. Log into the web UI to create your user account
|
|||
|
|
2. Run the SQL migration to assign your user_id to legacy comments
|
|||
|
|
|
|||
|
|
### Issue: Database migration fails
|
|||
|
|
|
|||
|
|
**Solution**:
|
|||
|
|
1. Check database connection in `.env`
|
|||
|
|
2. Ensure database user has CREATE, ALTER, and INSERT privileges
|
|||
|
|
3. Review migration output for specific error messages
|
|||
|
|
4. Check `/tmp/api_debug.log` for detailed errors
|
|||
|
|
|
|||
|
|
## 📧 Support
|
|||
|
|
|
|||
|
|
For issues or questions:
|
|||
|
|
1. Check the audit log: `SELECT * FROM audit_log ORDER BY created_at DESC LIMIT 50;`
|
|||
|
|
2. Check PHP error logs: `tail -f /var/log/php-fpm/error.log`
|
|||
|
|
3. Check debug logs: `tail -f /tmp/api_debug.log`
|
|||
|
|
4. Review Authelia logs: `docker logs authelia`
|