Add system settings, audit logging, user management, and dark mode fixes
System Settings: - Add SystemSettings.vue with Zabbix integration, SMTP/email config, SAML SSO settings - Add Setting model with key-value storage and typed values - Add settings API with caching Audit Logging: - Add AuditLog model tracking user, IP, action, entity changes - Add comprehensive audit logging to all CRUD operations: - Machines, Computers, Equipment, Network devices, VLANs, Subnets - Printers, USB devices (including checkout/checkin) - Applications, Settings, Users/Roles - Track old/new values for all field changes - Mask sensitive values (passwords, tokens) in logs User Management: - Add UsersList.vue with full user CRUD - Add Role management with granular permissions - Add 41 predefined permissions across 10 categories - Add users API with roles and permissions endpoints Reports: - Add TonerReport.vue for printer supply monitoring Dark Mode Fixes: - Fix map position section in PCForm, PrinterForm - Fix alert-warning in KnowledgeBaseDetail - All components now use CSS variables for theming CLI Commands: - Add flask seed permissions - Add flask seed settings Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -145,3 +145,180 @@ def seed_test_user():
|
||||
click.echo(click.style("Test user created: admin / admin123", fg='green'))
|
||||
else:
|
||||
click.echo(click.style("Test user already exists", fg='yellow'))
|
||||
|
||||
|
||||
@seed_cli.command('permissions')
|
||||
@with_appcontext
|
||||
def seed_permissions():
|
||||
"""Seed predefined permissions."""
|
||||
from shopdb.extensions import db
|
||||
from shopdb.core.models import Permission
|
||||
|
||||
created = Permission.seed()
|
||||
db.session.commit()
|
||||
click.echo(click.style(f"{created} permissions created.", fg='green'))
|
||||
|
||||
|
||||
@seed_cli.command('settings')
|
||||
@with_appcontext
|
||||
def seed_settings():
|
||||
"""Seed default system settings."""
|
||||
from shopdb.extensions import db
|
||||
from shopdb.core.models import Setting
|
||||
|
||||
defaults = [
|
||||
# Zabbix integration
|
||||
{
|
||||
'key': 'zabbix_enabled',
|
||||
'value': 'false',
|
||||
'valuetype': 'boolean',
|
||||
'category': 'integrations',
|
||||
'description': 'Enable Zabbix integration for printer supply monitoring'
|
||||
},
|
||||
{
|
||||
'key': 'zabbix_url',
|
||||
'value': '',
|
||||
'valuetype': 'string',
|
||||
'category': 'integrations',
|
||||
'description': 'Zabbix API URL (e.g., http://zabbix.example.com:8080)'
|
||||
},
|
||||
{
|
||||
'key': 'zabbix_token',
|
||||
'value': '',
|
||||
'valuetype': 'string',
|
||||
'category': 'integrations',
|
||||
'description': 'Zabbix API authentication token'
|
||||
},
|
||||
# Email/SMTP settings
|
||||
{
|
||||
'key': 'smtp_enabled',
|
||||
'value': 'false',
|
||||
'valuetype': 'boolean',
|
||||
'category': 'email',
|
||||
'description': 'Enable email notifications and alerts'
|
||||
},
|
||||
{
|
||||
'key': 'smtp_host',
|
||||
'value': '',
|
||||
'valuetype': 'string',
|
||||
'category': 'email',
|
||||
'description': 'SMTP server hostname'
|
||||
},
|
||||
{
|
||||
'key': 'smtp_port',
|
||||
'value': '587',
|
||||
'valuetype': 'integer',
|
||||
'category': 'email',
|
||||
'description': 'SMTP server port (usually 587 for TLS, 465 for SSL, 25 for unencrypted)'
|
||||
},
|
||||
{
|
||||
'key': 'smtp_username',
|
||||
'value': '',
|
||||
'valuetype': 'string',
|
||||
'category': 'email',
|
||||
'description': 'SMTP authentication username'
|
||||
},
|
||||
{
|
||||
'key': 'smtp_password',
|
||||
'value': '',
|
||||
'valuetype': 'string',
|
||||
'category': 'email',
|
||||
'description': 'SMTP authentication password'
|
||||
},
|
||||
{
|
||||
'key': 'smtp_use_tls',
|
||||
'value': 'true',
|
||||
'valuetype': 'boolean',
|
||||
'category': 'email',
|
||||
'description': 'Use TLS encryption for SMTP connection'
|
||||
},
|
||||
{
|
||||
'key': 'smtp_from_address',
|
||||
'value': '',
|
||||
'valuetype': 'string',
|
||||
'category': 'email',
|
||||
'description': 'From address for outgoing emails'
|
||||
},
|
||||
{
|
||||
'key': 'smtp_from_name',
|
||||
'value': 'ShopDB',
|
||||
'valuetype': 'string',
|
||||
'category': 'email',
|
||||
'description': 'From name for outgoing emails'
|
||||
},
|
||||
{
|
||||
'key': 'alert_recipients',
|
||||
'value': '',
|
||||
'valuetype': 'string',
|
||||
'category': 'email',
|
||||
'description': 'Default email recipients for alerts (comma-separated)'
|
||||
},
|
||||
# Audit log settings
|
||||
{
|
||||
'key': 'audit_retention_days',
|
||||
'value': '90',
|
||||
'valuetype': 'integer',
|
||||
'category': 'audit',
|
||||
'description': 'Number of days to retain audit logs (0 = keep forever)'
|
||||
},
|
||||
# Authentication settings
|
||||
{
|
||||
'key': 'saml_enabled',
|
||||
'value': 'false',
|
||||
'valuetype': 'boolean',
|
||||
'category': 'auth',
|
||||
'description': 'Enable SAML SSO authentication'
|
||||
},
|
||||
{
|
||||
'key': 'saml_idp_metadata_url',
|
||||
'value': '',
|
||||
'valuetype': 'string',
|
||||
'category': 'auth',
|
||||
'description': 'SAML Identity Provider metadata URL'
|
||||
},
|
||||
{
|
||||
'key': 'saml_entity_id',
|
||||
'value': '',
|
||||
'valuetype': 'string',
|
||||
'category': 'auth',
|
||||
'description': 'SAML Service Provider entity ID (e.g., https://shopdb.example.com)'
|
||||
},
|
||||
{
|
||||
'key': 'saml_acs_url',
|
||||
'value': '',
|
||||
'valuetype': 'string',
|
||||
'category': 'auth',
|
||||
'description': 'SAML Assertion Consumer Service URL'
|
||||
},
|
||||
{
|
||||
'key': 'saml_allow_local_login',
|
||||
'value': 'true',
|
||||
'valuetype': 'boolean',
|
||||
'category': 'auth',
|
||||
'description': 'Allow local username/password login when SAML is enabled'
|
||||
},
|
||||
{
|
||||
'key': 'saml_auto_create_users',
|
||||
'value': 'true',
|
||||
'valuetype': 'boolean',
|
||||
'category': 'auth',
|
||||
'description': 'Automatically create users on first SAML login'
|
||||
},
|
||||
{
|
||||
'key': 'saml_admin_group',
|
||||
'value': '',
|
||||
'valuetype': 'string',
|
||||
'category': 'auth',
|
||||
'description': 'SAML group name that grants admin role'
|
||||
},
|
||||
]
|
||||
|
||||
created = 0
|
||||
for d in defaults:
|
||||
if not Setting.query.filter_by(key=d['key']).first():
|
||||
setting = Setting(**d)
|
||||
db.session.add(setting)
|
||||
created += 1
|
||||
|
||||
db.session.commit()
|
||||
click.echo(click.style(f"{created} default settings created.", fg='green'))
|
||||
|
||||
Reference in New Issue
Block a user