#!/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)