first commit
This commit is contained in:
212
app.py
Normal file
212
app.py
Normal file
@@ -0,0 +1,212 @@
|
||||
from flask import Flask, render_template, request, jsonify, redirect, url_for, session
|
||||
from functools import wraps
|
||||
import malias_wrapper as malias_w
|
||||
import os
|
||||
|
||||
app = Flask(__name__)
|
||||
app.secret_key = os.urandom(24) # Secret key for session management
|
||||
|
||||
# Initialize database on startup
|
||||
malias_w.init_database()
|
||||
|
||||
def login_required(f):
|
||||
"""Decorator to require login for routes"""
|
||||
@wraps(f)
|
||||
def decorated_function(*args, **kwargs):
|
||||
if not session.get('logged_in'):
|
||||
return jsonify({'status': 'error', 'message': 'Not authenticated', 'redirect': '/login'}), 401
|
||||
return f(*args, **kwargs)
|
||||
return decorated_function
|
||||
|
||||
@app.route('/login', methods=['GET', 'POST'])
|
||||
def login():
|
||||
"""Login page"""
|
||||
if request.method == 'POST':
|
||||
password = request.json.get('password', '')
|
||||
if malias_w.verify_password(password):
|
||||
session['logged_in'] = True
|
||||
return jsonify({'status': 'success', 'message': 'Login successful'})
|
||||
else:
|
||||
return jsonify({'status': 'error', 'message': 'Invalid password'})
|
||||
|
||||
# Check if already logged in
|
||||
if session.get('logged_in'):
|
||||
return redirect(url_for('index'))
|
||||
|
||||
return render_template('login.html')
|
||||
|
||||
@app.route('/logout')
|
||||
def logout():
|
||||
"""Logout"""
|
||||
session.pop('logged_in', None)
|
||||
return redirect(url_for('login'))
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
"""Main page - requires login"""
|
||||
if not session.get('logged_in'):
|
||||
return redirect(url_for('login'))
|
||||
return render_template('index.html')
|
||||
|
||||
@app.route('/list_aliases', methods=['POST'])
|
||||
@login_required
|
||||
def list_aliases():
|
||||
"""List all aliases from Mailcow with pagination"""
|
||||
try:
|
||||
connection = malias_w.get_settings_from_db()
|
||||
if not connection:
|
||||
return jsonify({'status': 'error', 'message': 'Please configure Mailcow server first'})
|
||||
|
||||
# Get page number from request, default to 1
|
||||
page = request.json.get('page', 1) if request.json else 1
|
||||
|
||||
result = malias_w.get_all_aliases(page=page, per_page=20)
|
||||
return jsonify({'status': 'success', 'data': result})
|
||||
except Exception as e:
|
||||
return jsonify({'status': 'error', 'message': f"Error: {str(e)}"})
|
||||
|
||||
@app.route('/sync_aliases', methods=['POST'])
|
||||
@login_required
|
||||
def sync_aliases():
|
||||
"""Sync aliases from server to local DB"""
|
||||
try:
|
||||
count = malias_w.update_aliases()
|
||||
result = f"Aliases synchronized successfully! Added {count} new aliases to local DB."
|
||||
return jsonify({'status': 'success', 'message': result})
|
||||
except Exception as e:
|
||||
return jsonify({'status': 'error', 'message': f"Error syncing: {str(e)}"})
|
||||
|
||||
@app.route('/get_domains', methods=['POST'])
|
||||
@login_required
|
||||
def get_domains():
|
||||
"""Get all mail domains"""
|
||||
try:
|
||||
domains = malias_w.get_domains()
|
||||
domain_list = [d['domain_name'] for d in domains]
|
||||
result = f"Domains: {', '.join(domain_list)}"
|
||||
return jsonify({'status': 'success', 'message': result, 'domains': domain_list})
|
||||
except Exception as e:
|
||||
return jsonify({'status': 'error', 'message': f"Error: {str(e)}"})
|
||||
|
||||
@app.route('/create_alias', methods=['POST'])
|
||||
@login_required
|
||||
def create_alias():
|
||||
"""Create a new alias"""
|
||||
try:
|
||||
data = request.json
|
||||
alias = data.get('alias', '')
|
||||
goto = data.get('goto', '')
|
||||
|
||||
if not alias or not goto:
|
||||
return jsonify({'status': 'error', 'message': 'Both alias and destination are required'})
|
||||
|
||||
malias_w.create_alias(alias, goto)
|
||||
result = f"Alias {alias} created successfully for {goto}"
|
||||
return jsonify({'status': 'success', 'message': result})
|
||||
except Exception as e:
|
||||
return jsonify({'status': 'error', 'message': f"Error creating alias: {str(e)}"})
|
||||
|
||||
@app.route('/delete_alias', methods=['POST'])
|
||||
@login_required
|
||||
def delete_alias_route():
|
||||
"""Delete an alias"""
|
||||
try:
|
||||
data = request.json
|
||||
alias = data.get('alias', '')
|
||||
|
||||
if not alias:
|
||||
return jsonify({'status': 'error', 'message': 'Alias is required'})
|
||||
|
||||
malias_w.delete_alias(alias)
|
||||
result = f"Alias {alias} deleted successfully"
|
||||
return jsonify({'status': 'success', 'message': result})
|
||||
except Exception as e:
|
||||
return jsonify({'status': 'error', 'message': f"Error deleting alias: {str(e)}"})
|
||||
|
||||
@app.route('/create_timed_alias', methods=['POST'])
|
||||
@login_required
|
||||
def create_timed_alias():
|
||||
"""Create a time-limited alias"""
|
||||
try:
|
||||
data = request.json
|
||||
username = data.get('username', '')
|
||||
domain = data.get('domain', '')
|
||||
|
||||
if not username or not domain:
|
||||
return jsonify({'status': 'error', 'message': 'Both username and domain are required'})
|
||||
|
||||
malias_w.create_timed_alias(username, domain)
|
||||
result = f"Timed alias created for {username} on domain {domain}"
|
||||
return jsonify({'status': 'success', 'message': result})
|
||||
except Exception as e:
|
||||
return jsonify({'status': 'error', 'message': f"Error: {str(e)}"})
|
||||
|
||||
@app.route('/search', methods=['POST'])
|
||||
@login_required
|
||||
def search():
|
||||
"""Search for aliases"""
|
||||
query = request.json.get('query', '')
|
||||
|
||||
if not query:
|
||||
return jsonify({'status': 'error', 'message': 'No search query provided'})
|
||||
|
||||
try:
|
||||
results = malias_w.search_aliases(query)
|
||||
|
||||
if results:
|
||||
result_list = [f"{alias} → {goto}" for alias, goto in results]
|
||||
message = f"Found {len(results)} alias(es):\n" + "\n".join(result_list)
|
||||
else:
|
||||
message = f"No aliases found matching '{query}'"
|
||||
|
||||
return jsonify({'status': 'success', 'message': message, 'query': query})
|
||||
except Exception as e:
|
||||
return jsonify({'status': 'error', 'message': f"Search error: {str(e)}"})
|
||||
|
||||
@app.route('/config', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def config_page():
|
||||
"""Configuration management for Mailcow connection"""
|
||||
if request.method == 'POST':
|
||||
mailcow_server = request.json.get('mailcow_server', '')
|
||||
mailcow_api_key = request.json.get('mailcow_api_key', '')
|
||||
|
||||
if mailcow_server and mailcow_api_key:
|
||||
malias_w.set_connection_info(mailcow_server, mailcow_api_key)
|
||||
return jsonify({'status': 'success', 'message': 'Mailcow configuration saved successfully'})
|
||||
else:
|
||||
return jsonify({'status': 'error', 'message': 'Server and API key are required'})
|
||||
|
||||
# GET request - return current config
|
||||
try:
|
||||
current_config = malias_w.get_config()
|
||||
return jsonify(current_config)
|
||||
except Exception as e:
|
||||
return jsonify({'mailcow_server': '', 'mailcow_api_key': ''})
|
||||
|
||||
@app.route('/change_password', methods=['POST'])
|
||||
@login_required
|
||||
def change_password_route():
|
||||
"""Change password"""
|
||||
try:
|
||||
data = request.json
|
||||
old_password = data.get('old_password', '')
|
||||
new_password = data.get('new_password', '')
|
||||
confirm_password = data.get('confirm_password', '')
|
||||
|
||||
if not old_password or not new_password or not confirm_password:
|
||||
return jsonify({'status': 'error', 'message': 'All fields are required'})
|
||||
|
||||
if new_password != confirm_password:
|
||||
return jsonify({'status': 'error', 'message': 'New passwords do not match'})
|
||||
|
||||
if len(new_password) < 6:
|
||||
return jsonify({'status': 'error', 'message': 'Password must be at least 6 characters'})
|
||||
|
||||
malias_w.change_password(old_password, new_password)
|
||||
return jsonify({'status': 'success', 'message': 'Password changed successfully'})
|
||||
except Exception as e:
|
||||
return jsonify({'status': 'error', 'message': str(e)})
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True, host='0.0.0.0', port=5172)
|
||||
Reference in New Issue
Block a user