#!/usr/bin/env python3 """ Demo mode for SME Server Password Change Application - Python 3.6.8 Compatible This version simulates SME Server functionality for testing purposes when actual SME Server tools are not available. 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 app = Flask(__name__) app.secret_key = os.environ.get('SECRET_KEY', 'sme-server-password-change-demo-key') CORS(app) # Demo users for testing DEMO_USERS = { 'testuser': 'oldpassword123', 'admin': 'adminpass456', 'john': 'johnpass789' } class DemoPasswordManager: """Demo password manager for testing""" @staticmethod def validate_username(username): """Validate username in demo mode""" if not username: return False, "Username cannot be empty" if username not in DEMO_USERS: return False, "User account does not exist" return True, "Username is valid" @staticmethod def validate_password_strength(password): """Validate password strength""" errors = [] if len(password) < 7: errors.append("Password must be at least 7 characters long") if len(password) > 127: errors.append("Password must be no more than 127 characters long") # Check for at least one letter and one number has_letter = any(c.isalpha() for c in password) has_number = any(c.isdigit() for c in password) if not (has_letter and has_number): errors.append("Password must contain at least one letter and one number") return errors @staticmethod def verify_current_password(username, password): """Verify current password in demo mode""" return DEMO_USERS.get(username) == password @staticmethod def change_password(username, new_password): """Change password in demo mode""" try: # Simulate password change DEMO_USERS[username] = new_password return True, "Password changed successfully (demo mode)" except Exception as e: return False, "Error changing password: {}".format(str(e)) class DemoSystemInfo: """Demo system info for testing""" @staticmethod def get_version(): return "SME Server 11 (beta1) - Demo Mode" @staticmethod def get_copyright_info(): return { 'mitel': 'Copyright 1999-2006 Mitel Corporation', 'rights': 'All rights reserved.', 'koozali': 'Copyright (C) 2013 - 2021 Koozali Foundation Inc.' } # Initialize demo utilities password_manager = DemoPasswordManager() system_info = DemoSystemInfo() @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('/demo-info') def demo_info(): """Demo information page""" return { 'mode': 'demo', 'demo_users': list(DEMO_USERS.keys()), 'instructions': 'Use any of the demo usernames with their corresponding passwords to test the application' } @app.route('/health') def health_check(): """Health check endpoint""" return {'status': 'healthy', 'service': 'sme-server-password-change-demo'} if __name__ == '__main__': print("Starting SME Server Password Change Application in Demo Mode") print("Demo users available:") for user, password in DEMO_USERS.items(): print(" Username: {}, Password: {}".format(user, password)) print("\nAccess the application at: http://localhost:5001") print("Demo info available at: http://localhost:5001/demo-info") app.run(host='0.0.0.0', port=5001, debug=False)