Compare commits

...
10 Commits
Author SHA1 Message Date
mxmehl 3c1fbf2cf2 force basic auth on all pages 2021-12-19 22:52:12 +01:00
mxmehl 724c4da9fa do not fail when rc == 0 2021-12-19 22:45:07 +01:00
mxmehl 973f7a087b extend prototype for qmail toggling 2021-12-19 22:25:09 +01:00
mxmehl 065def33fc prototype qmail toggling 2021-12-19 22:00:41 +01:00
mxmehl 28064e8144 steps for autoresponder mailbot 2021-12-19 21:05:18 +01:00
mxmehl fbebdad8fe fix wrong dir name 2021-12-19 21:05:05 +01:00
mxmehl d5ea0d0856 create empty message file if necessary 2021-12-19 20:58:24 +01:00
mxmehl d06c80e218 further ansible tasks 2021-12-19 20:51:04 +01:00
mxmehl 979039094e fix wrong command 2021-12-19 20:50:48 +01:00
mxmehl 85db8c7cff first steps for ansible deployment 2021-12-19 20:14:23 +01:00
12 changed files with 167 additions and 14 deletions
+3
View File
@@ -144,3 +144,6 @@ cython_debug/
# Project specific # Project specific
message.txt message.txt
config.py config.py
inventory.txt
ansible/host_vars/*
!.keep
+2 -2
View File
@@ -8,7 +8,7 @@ used in Uberspace.de environments.
1. Clone Repo, e.g. to `/home/YOURUSERNAME/autoreply-editor` 1. Clone Repo, e.g. to `/home/YOURUSERNAME/autoreply-editor`
2. Create `config.py` and `message.txt` from their sample files 2. Create `config.py` and `message.txt` from their sample files
3. Install requirements: `pip3 install -r requirements.txt --user` 3. Install requirements: `pip3 install -r requirements.txt --user`
4. Create web backend on uberspace: `uberspace web backend app.example.com --http --port 5000` 4. Create web backend on uberspace: `uberspace web backend set app.example.com --http --port 5000`
5. Create a service in `~/etc/services.d/autoreply-editor.ini`: 5. Create a service in `~/etc/services.d/autoreply-editor.ini`:
``` ```
@@ -36,7 +36,7 @@ to "| mailbot -T reply -t $HOME/autoreply-editor/message.txt -d $HOME/autorespon
Make sure that the file permissions are `0600`! Make sure that the file permissions are `0600`!
Afterwards, also create the directory `~/autoreply` if necessary. Afterwards, also create the directory `~/autoresponders` if necessary.
### .qmail file ### .qmail file
+3
View File
@@ -0,0 +1,3 @@
[defaults]
interpreter_python = python3
inventory = inventory.txt
+3
View File
@@ -0,0 +1,3 @@
---
message_file: message.txt
port: 5000
View File
+60
View File
@@ -0,0 +1,60 @@
- hosts: autoreply_editor
gather_facts: true
tasks:
- name: Get newest version of autoreply-editor
git:
repo: https://src.mehl.mx/mxmehl/autoreply-editor.git
dest: autoreply-editor
- name: Deploy config file
template:
src: config.py.j2
dest: autoreply-editor/config.py
- name: Create empty message file if it does not exist
copy:
content: ""
dest: "autoreply-editor/{{ message_file }}"
force: no
- name: Install specified python requirements
pip:
requirements: requirements.txt
chdir: autoreply-editor
extra_args: --user
- name: Register domain for service
command: "uberspace web domain add {{ domain }}"
register: cmdrtrn
failed_when:
# Adding an already registered domain fails, but we ignore this specific error
- cmdrtrn.rc != 0
- "'It is already configured for your Uberspace account' not in cmdrtrn.stderr"
- name: Create web backend for service
command: "uberspace web backend set {{ domain }} --http --port {{ port }}"
- name: Deploy supervisord service
template:
src: autoreply-editor.ini.j2
dest: etc/services.d/autoreply-editor.ini
notify: reload supervisord
- name: Create autoresponders directory
file:
path: autoresponders
state: directory
- name: Create autoreply mailbot filter
template:
src: filter-autoreply.j2
dest: .filter-autoreply
mode: 0600
handlers:
- name: reread supervisord
command: supervisorctl reread
listen: reload supervisord
- name: update supervisord
command: supervisorctl update
listen: reload supervisord
@@ -0,0 +1,4 @@
[program:autoreply-editor]
directory=/home/{{ ansible_user_id }}/autoreply-editor
command=gunicorn --bind 0.0.0.0:{{ port }} wsgi:app
startsecs=60
+3
View File
@@ -0,0 +1,3 @@
MESSAGE_FILE = "{{ message_file }}"
BASIC_AUTH_USERNAME = "{{ auth_user }}"
BASIC_AUTH_PASSWORD = "{{ auth_pass }}"
+5
View File
@@ -0,0 +1,5 @@
logfile "$HOME/mailfilter-autoreply.log"
FROM="{{ mail_from }}"
to "| mailbot -T reply -t $HOME/autoreply-editor/{{ message_file }} -d $HOME/autoresponders/autoresponsedb -N -A 'From: $FROM' /var/qmail/bin/qmail-inject -f ''"
+1
View File
@@ -4,4 +4,5 @@ app = Flask(__name__)
import autoreply_editor.main import autoreply_editor.main
app.config['BASIC_AUTH_FORCE'] = True
app.config.from_pyfile("../config.py") app.config.from_pyfile("../config.py")
+62 -10
View File
@@ -1,25 +1,77 @@
"""Provide basic settings and views""" """Provide basic settings and views"""
from flask import request, render_template, redirect import fileinput
import re
from pathlib import Path
from flask import request, render_template
from flask_basicauth import BasicAuth from flask_basicauth import BasicAuth
from autoreply_editor import app from autoreply_editor import app
basic_auth = BasicAuth(app) basic_auth = BasicAuth(app)
qmail_prefix = f"{str(Path.home())}/.qmail-"
maildrop_line = "|maildrop $HOME/.filter-autoreply"
def qmail_status(user):
"""Find out whether the filter is currently activated for the given mail user"""
with open(f"{qmail_prefix}{user}", encoding="utf8") as dotqmail:
# TODO: RE not necessary here
if not re.search(
r"^\|maildrop \$HOME/\.filter-autoreply$", dotqmail.read(), re.MULTILINE
):
return False
else:
return True
@app.route("/") @app.route("/")
def index(): def index():
with open(app.config.get("MESSAGE_FILE"), "r") as f: with open(app.config.get("MESSAGE_FILE"), "r", encoding="utf-8") as messagefile:
message = f.read() message = messagefile.read()
return render_template("index.html", message=message) return render_template(
"index.html",
message=message,
qmail_status=qmail_status(app.config.get("MAIL_USER")),
)
@app.route('/', methods=['POST'])
@app.route("/", methods=["POST"])
def index_post(): def index_post():
input_message = request.form['message'] if request.method == "POST":
if request.form["action"] == "message":
if request.method == 'POST': input_message = request.form["message"]
with open(app.config.get("MESSAGE_FILE"), 'w') as f: with open(
f.write(str(input_message)) app.config.get("MESSAGE_FILE"), "w", encoding="utf-8"
) as messagefile:
messagefile.write(str(input_message))
result = "Success: The autoreply message has been updated!" result = "Success: The autoreply message has been updated!"
if request.form["action"] == "qmail":
# define whether to set a comment
if request.form["status"] == "on":
preis = "#"
preshould = ""
else:
preis = ""
preshould = "#"
with fileinput.FileInput(
f"{qmail_prefix}{app.config.get('MAIL_USER')}",
inplace=True,
backup=".bak",
) as dotqmail:
for line in dotqmail:
print(
line.replace(
f"{preis}{maildrop_line}", f"{preshould}{maildrop_line}"
),
end="",
)
result = f"Success: the autoreply is now {request.form['status']}."
try:
return render_template("result.html", result=result) return render_template("result.html", result=result)
except UnboundLocalError:
return render_template("result.html", result="Something went terribly wrong!")
+20 -1
View File
@@ -6,11 +6,30 @@
<body> <body>
<h1>Autoreply Editor</h1> <h1>Autoreply Editor</h1>
<h2>Toggle autoreply message</h2>
<p>
The autoreply is <strong>{%if qmail_status%}active{%else%}inactive{%endif%}</strong>
</p>
<form method="POST">
<input type="hidden" name="action" value="qmail" />
{% if qmail_status %}
<input type="hidden" name="status" value="off" />
<input type="submit" value="Deactivate">
{% else %}
<input type="hidden" name="status" value="on" />
<input type="submit" value="Activate">
{% endif %}
</form>
<h2>Change autoreply message</h2>
<p> <p>
Below you can see the current text of your autoreply message. You Below you can see the current text of your autoreply message. You
can edit and update it directly below: can edit and update it directly below:
</p> </p>
<form action="" method="POST"> <form method="POST">
<input type="hidden" name="action" value="message" />
<textarea name="message" cols="120" rows="20">{{ message }}</textarea> <textarea name="message" cols="120" rows="20">{{ message }}</textarea>
<br /> <br />
<input type="submit" value="Update"> <input type="submit" value="Update">