238 lines
6.9 KiB
Python
238 lines
6.9 KiB
Python
from .handle_params import HandleParams, timewindowcheck
|
|
from email.message import EmailMessage
|
|
from subprocess import Popen, PIPE
|
|
import sys
|
|
import datetime
|
|
from textwrap import TextWrapper
|
|
from io import StringIO
|
|
import os
|
|
aa = open('/web/etc/allowed.adress')
|
|
|
|
addresses = {}
|
|
for line in aa:
|
|
short, longname, mailAddress = line.split(";")
|
|
addresses[short] = (longname, mailAddress.strip())
|
|
|
|
try:
|
|
aa.close()
|
|
except AttributeError:
|
|
pass
|
|
|
|
class ValidationError(RuntimeError):
|
|
def __init__(self, message):
|
|
self.langs = { 'de': message, 'en': message }
|
|
|
|
def __str__(self):
|
|
return self.langs['de']
|
|
|
|
HandleParams.ValidationError = ValidationError
|
|
|
|
class MultiLangExc(ValidationError):
|
|
def __init__(self, **langs):
|
|
self.langs = langs
|
|
|
|
timewindowcheck.init_db()
|
|
|
|
def init(params, altfields, defaults, check_remote_ip='0.0.0.0'):
|
|
|
|
hp = HandleParams(altered_fields=altfields, params=params, defaults=defaults)
|
|
|
|
def render_text(field, **args):
|
|
value = field.value
|
|
attr = attributes_to_string(args)
|
|
return f'<input style="width:75%;" type="text" value="{value}" {attr}>'
|
|
|
|
def render_textfield(field,**args):
|
|
value = field.value
|
|
attr = attributes_to_string(args)
|
|
return f'<textarea style="width: 75%; min-height: 12em;" {attr}>{value}</textarea>'
|
|
|
|
def render_checkbox(field, **args):
|
|
attr = attributes_to_string(args)
|
|
return f'<input type="checkbox" {attr} >'
|
|
|
|
mandatory_text = { 'de': "obligatorisch", 'en': "mandatory" }
|
|
|
|
def render_local_time(field,**args):
|
|
return str(datetime.datetime.now())
|
|
|
|
def must_be_nonempty(field, value):
|
|
if value is None or len(value) == 0:
|
|
raise MultiLangExc(**mandatory_text)
|
|
return True
|
|
|
|
def must_be_nonempty_then_validate(inner_val, field, value):
|
|
if len(value) == 0:
|
|
raise MultiLangExc(**mandatory_text)
|
|
return inner_val(self, value)
|
|
|
|
def validate_honeypot_field(field,value):
|
|
if len(value):
|
|
raise ValidationError(
|
|
"Sie haben ein verstecktes Feld ausgefüllt"
|
|
"(Honigtopf für Spambots)"
|
|
)
|
|
return True
|
|
|
|
def pass_longname(field, name):
|
|
value = field.value
|
|
try:
|
|
longname = addresses[value][0]
|
|
except KeyError:
|
|
longname = "Heidelberg University Library (will forward)"
|
|
value = "ub"
|
|
return longname + f"<input type='hidden' name='adr' value='{value}'>"
|
|
|
|
def check_is_within_last24h():
|
|
pass
|
|
|
|
bei_allen_feldern_mgl = {
|
|
"mandatory": {
|
|
"required": True,
|
|
"wrap_validate": must_be_nonempty_then_validate,
|
|
}
|
|
}
|
|
|
|
hp.add_field("realname", {
|
|
"render":render_text
|
|
},
|
|
**bei_allen_feldern_mgl
|
|
)
|
|
|
|
hp.add_field("subject", {
|
|
"render":render_text,
|
|
"required": True,
|
|
})
|
|
|
|
hp.add_field("name", {
|
|
"validate": validate_honeypot_field,
|
|
"render":render_text
|
|
},
|
|
)
|
|
|
|
hp.add_field("body", {
|
|
"render":render_textfield,
|
|
"required": True,
|
|
})
|
|
|
|
hp.add_field("mailadr", {
|
|
"render":render_text
|
|
})
|
|
|
|
hp.add_field("wohnort", {
|
|
"render":render_text
|
|
})
|
|
|
|
hp.add_field("adr", {
|
|
"render":pass_longname
|
|
})
|
|
|
|
def twc_error(which):
|
|
msgs = {
|
|
"not passed": {
|
|
"de": "Spamprüfung gescheitert: kein timewindowcheck-Wert übergeben",
|
|
"en": "Spam detection failed: No field 'timewindowcheck' passed"
|
|
},
|
|
"invalid": { "de": "Zeitstempel und Digest ungültig", "en": "Timestamp and digest invalid" },
|
|
"missing": { "de": "Zeitstempel oder IP-Adresse nicht ermittelbar", "en": "Timestamp or IP address not indicated" },
|
|
"overused": { "de": "Der Zeitstempel wurde zu häufig verwendet", "en": "The timestamp has been used too often" },
|
|
"outdated": { "de": "Die Formularabfrage ist zu alt. Bitte laden Sie die Seite neu.", "en": "Form request is too old. Please reload the page." },
|
|
"fast_as_spambot": { "de": "Sie sind so schnell wie ein Spambot (oder schneller). Bitte lassen Sie sich vor dem Senden etwas mehr Zeit.", "en": "You are as fast as a spambot (or faster). Please have a breath or two before sending." },
|
|
}
|
|
return MultiLangExc(**msgs[which])
|
|
|
|
hp.add_field(
|
|
'timewindowcheck',
|
|
timewindowcheck.signed_fresh_timestamp_check(check_remote_ip, twc_error)
|
|
)
|
|
|
|
hp.add_field("dsgvochecked", {
|
|
"render":render_checkbox,
|
|
"rendervalue":render_local_time,
|
|
"required": True,
|
|
"validate": must_be_nonempty
|
|
})
|
|
|
|
return hp
|
|
|
|
def process(hp):
|
|
|
|
form = {
|
|
"adr": "adr",
|
|
"subject": "subject",
|
|
"realname": "realname",
|
|
"body": "body",
|
|
"ort": "wohnort",
|
|
"mymail": "mailadr",
|
|
"dsgvo_ts": "dsgvochecked",
|
|
}
|
|
|
|
for k,v in form.items():
|
|
form[k] = hp.fields[v].rendervalue() or hp.fields[v].value
|
|
|
|
adresse_formular = addresses[ hp.fields["adr"].value ][1]
|
|
|
|
# Mail bzw. Request rausschicken
|
|
send_mail(form, adresse_formular)
|
|
|
|
return form
|
|
|
|
|
|
def attributes_to_string(args):
|
|
attrs = []
|
|
for key, value in args.items():
|
|
attrs.append(f'{key}="{value}"')
|
|
return " ".join(attrs)
|
|
|
|
|
|
def send_mail(data, adr):
|
|
|
|
_w = TextWrapper(width=67, subsequent_indent=" "*13)
|
|
def wrap(label, slot):
|
|
_w.initial_indent = label+" "*(11-len(label))+': '
|
|
return _w.wrap(data[slot])
|
|
|
|
form = {
|
|
"Adressat": "adr",
|
|
"Betreff": "subject",
|
|
"Inhalt": "body",
|
|
"Absender": "realname",
|
|
"Wohnort": "ort",
|
|
"Antwort an": "mymail",
|
|
"DSE z.k.g.": "dsgvo_ts"
|
|
}
|
|
|
|
with open('/tmp/data_test.txt', 'w') as outfile:
|
|
outfile.write(str(data))
|
|
|
|
userinput = list()
|
|
for label,slot in form.items():
|
|
userinput.append('\n'.join(wrap(label,slot)))
|
|
|
|
text = ('' if data['mymail'] else """
|
|
-----------------------------------------------------------------
|
|
Bitte nicht die REPLY-Funktion verwenden. Es wurde keine Absende-
|
|
adresse angegeben.
|
|
Dieser Hinweis kann geloescht werden.
|
|
-----------------------------------------------------------------
|
|
""") + "\n".join(userinput)
|
|
|
|
mail = EmailMessage()
|
|
mail['From'] = 'WWW-Formular <noreply@ub.uni-heidelberg.de>'
|
|
#mail['From'] = data['mymail'] or 'WWW-Formular'
|
|
mail['To'] = adr
|
|
del mail['Subject']
|
|
mail['Subject'] = data['subject']
|
|
mail.add_header('Content-Type', 'text/plain;charset=utf-8')
|
|
mail.set_payload(text)
|
|
|
|
mail_string = str(mail)
|
|
|
|
sml = Popen(['/usr/sbin/sendmail', '-t', '-oi'], stdin=PIPE)
|
|
#err = sml.communicate(mail.as_bytes(policy=mail.policy.clone(linesep='\r\n')))
|
|
with open('/var/tmp/mail_string_encode.txt', 'w') as file:
|
|
print(mail_string, file=file)
|
|
|
|
err = sml.communicate(mail_string.encode('utf8'))
|
|
|