112 lines
3.6 KiB
Python
112 lines
3.6 KiB
Python
|
#!/usr/bin/env python3
|
||
|
"""
|
||
|
SME Server Password Change Application - Python 3.6.8 Compatible
|
||
|
|
||
|
A Flask web application for changing user passwords on SME Server,
|
||
|
interfacing with the smeserver configuration database and using
|
||
|
signal-event password-update to apply changes.
|
||
|
|
||
|
Compatible with Python 3.6.8 and Flask 2.0.3
|
||
|
"""
|
||
|
|
||
|
import os
|
||
|
from flask import Flask, render_template, request, flash, redirect, url_for
|
||
|
from flask_cors import CORS
|
||
|
from smeserver_utils import SMEPasswordManager, SMESystemInfo
|
||
|
|
||
|
app = Flask(__name__)
|
||
|
app.secret_key = os.environ.get('SECRET_KEY', 'sme-server-password-change-key')
|
||
|
CORS(app)
|
||
|
|
||
|
# Initialize SME Server utilities
|
||
|
password_manager = SMEPasswordManager()
|
||
|
system_info = SMESystemInfo()
|
||
|
|
||
|
@app.route('/', methods=['GET', 'POST'])
|
||
|
def password_change():
|
||
|
"""Main password change form handler"""
|
||
|
|
||
|
if request.method == 'POST':
|
||
|
# Get form data
|
||
|
username = request.form.get('username', '').strip()
|
||
|
old_password = request.form.get('old_password', '')
|
||
|
new_password = request.form.get('new_password', '')
|
||
|
verify_password = request.form.get('verify_password', '')
|
||
|
|
||
|
# Validation
|
||
|
errors = []
|
||
|
|
||
|
if not username:
|
||
|
errors.append("Username is required")
|
||
|
|
||
|
if not old_password:
|
||
|
errors.append("Current password is required")
|
||
|
|
||
|
if not new_password:
|
||
|
errors.append("New password is required")
|
||
|
|
||
|
if not verify_password:
|
||
|
errors.append("Password verification is required")
|
||
|
|
||
|
if new_password != verify_password:
|
||
|
errors.append("New password and verification do not match")
|
||
|
|
||
|
# Validate username
|
||
|
if username:
|
||
|
valid_username, username_msg = password_manager.validate_username(username)
|
||
|
if not valid_username:
|
||
|
errors.append(username_msg)
|
||
|
|
||
|
# Validate current password
|
||
|
if username and old_password and not errors:
|
||
|
if not password_manager.verify_current_password(username, old_password):
|
||
|
errors.append("Current password is incorrect")
|
||
|
|
||
|
# Validate new password strength
|
||
|
if new_password:
|
||
|
strength_errors = password_manager.validate_password_strength(new_password)
|
||
|
errors.extend(strength_errors)
|
||
|
|
||
|
if errors:
|
||
|
for error in errors:
|
||
|
flash(error, 'error')
|
||
|
else:
|
||
|
# Change the password
|
||
|
success, message = password_manager.change_password(username, new_password)
|
||
|
|
||
|
if success:
|
||
|
flash(message, 'success')
|
||
|
return redirect(url_for('password_change'))
|
||
|
else:
|
||
|
flash(message, 'error')
|
||
|
|
||
|
# Get system information for the template
|
||
|
version = system_info.get_version()
|
||
|
copyright_info = system_info.get_copyright_info()
|
||
|
|
||
|
return render_template('password_change.html',
|
||
|
version=version,
|
||
|
copyright_info=copyright_info)
|
||
|
|
||
|
@app.route('/health')
|
||
|
def health_check():
|
||
|
"""Health check endpoint"""
|
||
|
return {'status': 'healthy', 'service': 'sme-server-password-change'}
|
||
|
|
||
|
@app.errorhandler(404)
|
||
|
def not_found(error):
|
||
|
"""Handle 404 errors"""
|
||
|
return render_template('password_change.html',
|
||
|
error="Page not found"), 404
|
||
|
|
||
|
@app.errorhandler(500)
|
||
|
def internal_error(error):
|
||
|
"""Handle 500 errors"""
|
||
|
return render_template('password_change.html',
|
||
|
error="Internal server error"), 500
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
# Run the application
|
||
|
app.run(host='0.0.0.0', port=5000, debug=True)
|
||
|
|