diff options
author | Ismaël Bouya <ismael.bouya@normalesup.org> | 2023-10-04 01:35:06 +0200 |
---|---|---|
committer | Ismaël Bouya <ismael.bouya@normalesup.org> | 2023-10-04 02:11:48 +0200 |
commit | 1a64deeb894dc95e2645a75771732c6cc53a79ad (patch) | |
tree | 1b9df4838f894577a09b9b260151756272efeb53 /systems/eldiron/ejabberd/warn_xmpp_email.py | |
parent | fa25ffd4583cc362075cd5e1b4130f33306103f0 (diff) | |
download | Nix-1a64deeb894dc95e2645a75771732c6cc53a79ad.tar.gz Nix-1a64deeb894dc95e2645a75771732c6cc53a79ad.tar.zst Nix-1a64deeb894dc95e2645a75771732c6cc53a79ad.zip |
Squash changes containing private information
There were a lot of changes since the previous commit, but a lot of them
contained personnal information about users. All thos changes got
stashed into a single commit (history is kept in a different place) and
private information was moved in a separate private repository
Diffstat (limited to 'systems/eldiron/ejabberd/warn_xmpp_email.py')
-rwxr-xr-x | systems/eldiron/ejabberd/warn_xmpp_email.py | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/systems/eldiron/ejabberd/warn_xmpp_email.py b/systems/eldiron/ejabberd/warn_xmpp_email.py new file mode 100755 index 0000000..d482b43 --- /dev/null +++ b/systems/eldiron/ejabberd/warn_xmpp_email.py | |||
@@ -0,0 +1,112 @@ | |||
1 | #!@pythonEnv@/bin/python3 | ||
2 | |||
3 | import sys | ||
4 | import json | ||
5 | import slixmpp | ||
6 | import asyncio | ||
7 | import logging | ||
8 | import io | ||
9 | |||
10 | CONFIG = json.load(open("@scriptEnv@", "r")) | ||
11 | |||
12 | def sanitize(string): | ||
13 | import re | ||
14 | from unidecode import unidecode | ||
15 | return re.compile(r"[^-.A-Za-z0-9_]").sub("_", unidecode(string)) | ||
16 | |||
17 | def parse_email(): | ||
18 | import email | ||
19 | from email.header import decode_header | ||
20 | |||
21 | mail = email.message_from_file(sys.stdin) | ||
22 | try: | ||
23 | d = decode_header(mail["subject"])[0] | ||
24 | if d[1] is not None: | ||
25 | subject = d[0].decode(d[1]) | ||
26 | else: | ||
27 | subject = d[0] | ||
28 | except Exception as e: | ||
29 | subject = mail["subject"] | ||
30 | sender = mail["from"] | ||
31 | recipient = mail["X-Original-To"] | ||
32 | |||
33 | body = "" | ||
34 | html = None | ||
35 | files = {} | ||
36 | for part in mail.walk(): | ||
37 | if part.get_content_type() == "text/plain": | ||
38 | body += "\n-------------------\n" | ||
39 | try: | ||
40 | body += part.get_payload(decode=True).decode(encoding=part.get_content_charset() or "utf-8") | ||
41 | except Exception as e: | ||
42 | body += part.get_payload(decode=False) | ||
43 | elif part.get_content_type() == "text/html": | ||
44 | html = part.get_payload(decode=True) | ||
45 | elif part.get_content_type() != "text/html" and\ | ||
46 | part.get_content_maintype() != "multipart": | ||
47 | |||
48 | filename = part.get_filename() or "{}.dat".format(part["Content-ID"]) | ||
49 | files[sanitize(filename)] = (part.get_content_type(), part.get_payload(decode=True)) | ||
50 | |||
51 | return [body, html, subject, sender, recipient, files] | ||
52 | |||
53 | [body, html, subject, sender, recipient, files] = parse_email() | ||
54 | |||
55 | class Bot(slixmpp.ClientXMPP): | ||
56 | def __init__(self, jid, password, body, html, subject, sender, recipient, files): | ||
57 | super().__init__(jid, password) | ||
58 | |||
59 | self.got_error = False | ||
60 | self.body = body | ||
61 | self.html = html | ||
62 | self.subject = subject | ||
63 | self.sender = sender | ||
64 | self.recipient = recipient | ||
65 | self.files = files | ||
66 | self.register_plugin('xep_0363') | ||
67 | self.add_event_handler("session_start", self.session_start) | ||
68 | self.add_event_handler("message", self.message) | ||
69 | |||
70 | @asyncio.coroutine | ||
71 | def session_start(self, event): | ||
72 | files = [] | ||
73 | if self.html is not None: | ||
74 | url = yield from self['xep_0363'].upload_file( | ||
75 | "mail.html", | ||
76 | content_type="text/html", | ||
77 | input_file=io.BytesIO(self.html)) | ||
78 | files.append(("HTML version", url)) | ||
79 | for f in self.files: | ||
80 | url = yield from self['xep_0363'].upload_file( | ||
81 | f, | ||
82 | content_type=self.files[f][0], | ||
83 | input_file=io.BytesIO(self.files[f][1]) | ||
84 | ) | ||
85 | files.append((f, url)) | ||
86 | |||
87 | text = """ | ||
88 | New e-mail message from {sender} | ||
89 | Subject: {subject} | ||
90 | {body} | ||
91 | """.format(sender=self.sender, subject=self.subject, body=self.body) | ||
92 | if len(files) > 0: | ||
93 | text += "\n\nAttachments:" | ||
94 | for f in files: | ||
95 | text += "\n{}: {}".format(f[0], f[1]) | ||
96 | self.send_message(mto=self.recipient, mbody=text, msubject=self.subject, mtype='message') | ||
97 | yield from asyncio.sleep(5) | ||
98 | self.disconnect() | ||
99 | |||
100 | @asyncio.coroutine | ||
101 | def message(self, msg): | ||
102 | if msg["type"] == "error": | ||
103 | self.got_error = True | ||
104 | |||
105 | logging.basicConfig(level=logging.DEBUG, format='%(levelname)-8s %(message)s') | ||
106 | xmpp = Bot(CONFIG["jid"], CONFIG["password"], body, html, subject, sender, recipient, files) | ||
107 | xmpp.connect() | ||
108 | xmpp.process(forever=False) | ||
109 | if xmpp.got_error: | ||
110 | sys.exit(1) | ||
111 | else: | ||
112 | sys.exit(0) | ||