mirror of
https://github.com/chillout2k/gulag.git
synced 2025-12-13 16:00:18 +00:00
resource routing
This commit is contained in:
parent
e1dcba19c1
commit
6c23eda022
144
app/Entities.py
144
app/Entities.py
@ -1,5 +1,149 @@
|
|||||||
|
import re
|
||||||
|
|
||||||
|
class MailboxException(Exception):
|
||||||
|
message = None
|
||||||
|
def __init__(self,message):
|
||||||
|
self.message = message
|
||||||
|
|
||||||
class Mailbox:
|
class Mailbox:
|
||||||
|
email_address = None
|
||||||
|
name = None
|
||||||
|
imap_server = None
|
||||||
|
imap_security = None
|
||||||
|
imap_user = None
|
||||||
|
imap_pass = None
|
||||||
|
imap_mailbox = None
|
||||||
|
imap_mailbox_fp = None
|
||||||
|
imap_separator = None
|
||||||
|
comment = None
|
||||||
|
href = None
|
||||||
|
|
||||||
|
def __init__(self,mb_ref):
|
||||||
|
if 'email_address' not in mb_ref:
|
||||||
|
raise MailboxException("'email_address' is mandatory!")
|
||||||
|
self.email_address = mb_ref['email_address']
|
||||||
|
if 'name' not in mb_ref:
|
||||||
|
raise MailboxException("'name' is mandatory!")
|
||||||
|
self.name = mb_ref['name']
|
||||||
|
if 'imap_server' not in mb_ref:
|
||||||
|
raise MailboxException("'imap_server' is mandatory!")
|
||||||
|
self.imap_server = mb_ref['imap_server']
|
||||||
|
if 'imap_security' in mb_ref:
|
||||||
|
if re.match("^(plain|starttls|tls)$", mb_ref['imap_security']) is not None:
|
||||||
|
self.imap_security = mb_ref['imap_security']
|
||||||
|
else:
|
||||||
|
raise MailboxException('imap_security: {} is invalid! '+
|
||||||
|
'Valid values: plain,starttls,tls'.format(mb_ref['imap_security'])
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise MailboxException("'imap_security' is a mandatory!")
|
||||||
|
if 'imap_user' not in mb_ref:
|
||||||
|
raise MailboxException("'imap_user' is mandatory!")
|
||||||
|
self.imap_user = mb_ref['imap_user']
|
||||||
|
if 'imap_pass' not in mb_ref:
|
||||||
|
raise MailboxException("'imap_pass' is mandatory!")
|
||||||
|
self.imap_pass = mb_ref['imap_pass']
|
||||||
|
if 'imap_mailbox' not in mb_ref:
|
||||||
|
raise MailboxException("'imap_mailbox' is mandatory!")
|
||||||
|
self.imap_mailbox = mb_ref['imap_mailbox']
|
||||||
|
if 'imap_mailbox_fp' not in mb_ref:
|
||||||
|
raise MailboxException("'imap_mailbox_fp' is mandatory!")
|
||||||
|
self.imap_mailbox_fp = mb_ref['imap_mailbox_fp']
|
||||||
|
if 'imap_separator' not in mb_ref:
|
||||||
|
raise MailboxException("'imap_separator' is mandatory!")
|
||||||
|
self.imap_seperator = mb_ref['imap_separator']
|
||||||
|
if 'comment' in mb_ref:
|
||||||
|
self.comment = mb_ref['comment']
|
||||||
|
if 'href' in mb_ref:
|
||||||
|
self.href = mb_ref['href']
|
||||||
|
|
||||||
|
class QuarMailException(Exception):
|
||||||
|
message = None
|
||||||
|
def __init__(self,message):
|
||||||
|
self.message = message
|
||||||
|
|
||||||
class QuarMail:
|
class QuarMail:
|
||||||
|
id = None
|
||||||
|
ctime = None
|
||||||
|
mx_queue_id = None
|
||||||
|
env_from = None
|
||||||
|
env_rcpt = None
|
||||||
|
hdr_cf = None
|
||||||
|
hdr_from = None
|
||||||
|
hdr_subject = None
|
||||||
|
hdr_msgid = None
|
||||||
|
hdr_date = None
|
||||||
|
cf_meta = None
|
||||||
|
mailbox_id = None
|
||||||
|
imap_uid = None
|
||||||
|
msg_size = None
|
||||||
|
href = None
|
||||||
|
|
||||||
|
def __init__(self,qm_ref):
|
||||||
|
if 'id' not in qm_ref:
|
||||||
|
raise QuarMailException("'id' is mandatory!")
|
||||||
|
self.id = qm_ref['id']
|
||||||
|
if 'ctime' not in qm_ref:
|
||||||
|
raise QuarMailException("'ctime' is mandatory!")
|
||||||
|
self.ctime = qm_ref['ctime']
|
||||||
|
if 'mx_queue_id' not in qm_ref:
|
||||||
|
raise QuarMailException("'mx_queue_id' is mandatory!")
|
||||||
|
self.mx_queue_id = qm_ref['mx_queue_id']
|
||||||
|
if 'env_from' not in qm_ref:
|
||||||
|
raise QuarMailException("'env_from' is mandatory!")
|
||||||
|
self.env_from = qm_ref['env_from']
|
||||||
|
if 'env_rcpt' not in qm_ref:
|
||||||
|
raise QuarMailException("'env_rcpt' is mandatory!")
|
||||||
|
self.env_rcpt = qm_ref['env_rcpt']
|
||||||
|
if 'hdr_cf' in qm_ref:
|
||||||
|
self.hdr_cf = qm_ref['hdr_cf']
|
||||||
|
if 'hdr_from' in qm_ref:
|
||||||
|
self.hdr_from = qm_ref['hdr_from']
|
||||||
|
if 'hdr_subject' in qm_ref:
|
||||||
|
self.hdr_subject = qm_ref['hdr_subject']
|
||||||
|
if 'hdr_msgid' in qm_ref:
|
||||||
|
self.hdr_msgid = qm_ref['hdr_msgid']
|
||||||
|
if 'hdr_date' in qm_ref:
|
||||||
|
self.hdr_date = qm_ref['hdr_date']
|
||||||
|
if 'cf_meta' in qm_ref:
|
||||||
|
self.cf_meta = qm_ref['cf_meta']
|
||||||
|
if 'mailbox_id' not in qm_ref:
|
||||||
|
raise QuarMailException("'mailbox_id' is mandatory!")
|
||||||
|
self.mailbox_id = qm_ref['mailbox_id']
|
||||||
|
if 'imap_uid' not in qm_ref:
|
||||||
|
raise QuarMailException("'imap_uid' is mandatory!")
|
||||||
|
self.imap_uid = qm_ref['imap_uid']
|
||||||
|
if 'msg_size' not in qm_ref:
|
||||||
|
raise QuarMailException("'msg_size' is mandatory!")
|
||||||
|
self.msg_size = qm_ref['msg_size']
|
||||||
|
if 'href' in qm_ref:
|
||||||
|
self.href = qm_ref['href']
|
||||||
|
|
||||||
|
|
||||||
|
class AttachmentException(Exception):
|
||||||
|
message = None
|
||||||
|
def __init__(self,message):
|
||||||
|
self.message = message
|
||||||
|
|
||||||
class Attachment:
|
class Attachment:
|
||||||
|
id = None
|
||||||
|
filename = None
|
||||||
|
content_type = None
|
||||||
|
comment = None
|
||||||
|
href = None
|
||||||
|
|
||||||
|
def __init__(self,at_ref):
|
||||||
|
if 'id' not in at_ref:
|
||||||
|
raise AttachmentException("'id' is mandatory!")
|
||||||
|
self.id = at_ref['id']
|
||||||
|
if 'filename' not in at_ref:
|
||||||
|
raise AttachmentException("'filename' is mandatory!")
|
||||||
|
self.filename = at_ref['filename']
|
||||||
|
if 'content_type' not in at_ref:
|
||||||
|
raise AttachmentException("'content_type' is mandatory!")
|
||||||
|
self.content_type = at_ref['content_type']
|
||||||
|
if 'comment' in at_ref:
|
||||||
|
self.comment = at_ref['comment']
|
||||||
|
if 'href' in at_ref:
|
||||||
|
self.href = at_ref['href']
|
||||||
|
|
||||||
|
|||||||
25
app/Gulag.py
25
app/Gulag.py
@ -27,7 +27,8 @@ class Gulag:
|
|||||||
self.config['db']['server'],
|
self.config['db']['server'],
|
||||||
self.config['db']['user'],
|
self.config['db']['user'],
|
||||||
self.config['db']['password'],
|
self.config['db']['password'],
|
||||||
self.config['db']['name']
|
self.config['db']['name'],
|
||||||
|
self.config['uri_prefixes']
|
||||||
)
|
)
|
||||||
except GulagDBException as e:
|
except GulagDBException as e:
|
||||||
raise GulagException(e.message) from e
|
raise GulagException(e.message) from e
|
||||||
@ -54,8 +55,18 @@ class Gulag:
|
|||||||
msg = unseen['msg']
|
msg = unseen['msg']
|
||||||
msg_size = len(str(msg))
|
msg_size = len(str(msg))
|
||||||
r5321_from = email.header.decode_header(msg['Return-Path'])[0][0]
|
r5321_from = email.header.decode_header(msg['Return-Path'])[0][0]
|
||||||
|
r5321_rcpts = None
|
||||||
|
try:
|
||||||
r5321_rcpts = email.header.decode_header(msg['X-Envelope-To-Blocked'])[0][0]
|
r5321_rcpts = email.header.decode_header(msg['X-Envelope-To-Blocked'])[0][0]
|
||||||
|
except:
|
||||||
|
print("Failed to extract envelope recipients! Skipping mail")
|
||||||
|
continue
|
||||||
|
r5322_from = None
|
||||||
|
try:
|
||||||
r5322_from = email.header.decode_header(msg['From'])[0][0]
|
r5322_from = email.header.decode_header(msg['From'])[0][0]
|
||||||
|
except:
|
||||||
|
print("Failed to extract from header! Skipping mail")
|
||||||
|
continue
|
||||||
subject = email.header.decode_header(msg['Subject'])[0][0]
|
subject = email.header.decode_header(msg['Subject'])[0][0]
|
||||||
msg_id = None
|
msg_id = None
|
||||||
try:
|
try:
|
||||||
@ -117,3 +128,15 @@ class Gulag:
|
|||||||
))
|
))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_mailboxes(self):
|
||||||
|
try:
|
||||||
|
return self.db.get_mailboxes()
|
||||||
|
except GulagDBException as e:
|
||||||
|
raise GulagException("GulagDBException: " + e.message) from e
|
||||||
|
|
||||||
|
def get_quarmails(self):
|
||||||
|
try:
|
||||||
|
return self.db.get_quarmails()
|
||||||
|
except GulagDBException as e:
|
||||||
|
raise GulagException("GulagDBException: " + e.message) from e
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import mysql.connector as mariadb
|
import mysql.connector as mariadb
|
||||||
|
from Entities import Mailbox,MailboxException,QuarMail,QuarMailException,Attachment,AttachmentException
|
||||||
|
|
||||||
class GulagDBException(Exception):
|
class GulagDBException(Exception):
|
||||||
message = None
|
message = None
|
||||||
@ -7,15 +8,18 @@ class GulagDBException(Exception):
|
|||||||
|
|
||||||
class GulagDB:
|
class GulagDB:
|
||||||
conn = None
|
conn = None
|
||||||
|
uri_prefixes = None
|
||||||
|
|
||||||
def __init__(self, server, user, password, name):
|
def __init__(self, server, user, password, name, uri_prefixes):
|
||||||
try:
|
try:
|
||||||
self.conn = mariadb.connect(
|
self.conn = mariadb.connect(
|
||||||
host=server,
|
host=server,
|
||||||
user=user,
|
user=user,
|
||||||
password=password,
|
password=password,
|
||||||
database=name
|
database=name,
|
||||||
|
autocommit=True
|
||||||
)
|
)
|
||||||
|
self.uri_prefixes = uri_prefixes
|
||||||
except mariadb.Error as e:
|
except mariadb.Error as e:
|
||||||
raise GulagDBException(e) from e
|
raise GulagDBException(e) from e
|
||||||
|
|
||||||
@ -35,7 +39,12 @@ class GulagDB:
|
|||||||
dict = {}
|
dict = {}
|
||||||
for (name, value) in zip(desc, tuple):
|
for (name, value) in zip(desc, tuple):
|
||||||
dict[name[0]] = value
|
dict[name[0]] = value
|
||||||
results.append(dict)
|
dict['href'] = self.uri_prefixes['mailboxes'] + dict['email_address']
|
||||||
|
try:
|
||||||
|
results.append(Mailbox(dict).__dict__)
|
||||||
|
except MailboxException as e:
|
||||||
|
print("MailboxException: " + e.message)
|
||||||
|
continue
|
||||||
return results
|
return results
|
||||||
except mariadb.Error as e:
|
except mariadb.Error as e:
|
||||||
raise GulagDBException(e) from e
|
raise GulagDBException(e) from e
|
||||||
@ -55,8 +64,9 @@ class GulagDB:
|
|||||||
quarmail['mailbox_id'],quarmail['imap_uid'],quarmail['msg_size']
|
quarmail['mailbox_id'],quarmail['imap_uid'],quarmail['msg_size']
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.conn.commit()
|
id = cursor.lastrowid
|
||||||
return cursor.lastrowid
|
cursor.close()
|
||||||
|
return id
|
||||||
except mariadb.Error as e:
|
except mariadb.Error as e:
|
||||||
raise GulagDBException(e) from e
|
raise GulagDBException(e) from e
|
||||||
|
|
||||||
@ -64,28 +74,35 @@ class GulagDB:
|
|||||||
try:
|
try:
|
||||||
cursor = self.conn.cursor()
|
cursor = self.conn.cursor()
|
||||||
cursor.execute("delete from QuarMails where id=%s;", (id))
|
cursor.execute("delete from QuarMails where id=%s;", (id))
|
||||||
self.conn.commit()
|
cursor.close()
|
||||||
return cursor.lastrowid
|
return True
|
||||||
except mariadb.Error as e:
|
except mariadb.Error as e:
|
||||||
raise GulagDBException(e) from e
|
raise GulagDBException(e) from e
|
||||||
|
|
||||||
def get_quarmails(self, mailbox_id):
|
# def get_quarmails(self,mailbox_id):
|
||||||
|
def get_quarmails(self):
|
||||||
try:
|
try:
|
||||||
cursor = self.conn.cursor()
|
cursor = self.conn.cursor()
|
||||||
cursor.execute(
|
# cursor.execute(
|
||||||
"select * from QuarMails where mailbox_id='%s';",
|
# "select * from QuarMails where mailbox_id='%s';",
|
||||||
(mailbox_id)
|
# (mailbox_id)
|
||||||
)
|
# )
|
||||||
|
cursor.execute("select * from QuarMails;")
|
||||||
results = []
|
results = []
|
||||||
data = cursor.fetchall()
|
data = cursor.fetchall()
|
||||||
if data == None:
|
if data == None:
|
||||||
return results
|
return results
|
||||||
desc = cursor.description
|
desc = cursor.description
|
||||||
|
cursor.close()
|
||||||
for tuple in data:
|
for tuple in data:
|
||||||
dict = {}
|
dict = {}
|
||||||
for (name, value) in zip(desc, tuple):
|
for (name, value) in zip(desc, tuple):
|
||||||
|
if(name[0] == 'ctime'):
|
||||||
|
dict[name[0]] = value.strftime('%Y-%m-%d %H:%M:%S')
|
||||||
|
else:
|
||||||
dict[name[0]] = value
|
dict[name[0]] = value
|
||||||
results.append(dict)
|
dict['href'] = self.uri_prefixes['quarmails'] + str(dict['id'])
|
||||||
|
results.append(QuarMail(dict).__dict__)
|
||||||
return results
|
return results
|
||||||
except mariadb.Error as e:
|
except mariadb.Error as e:
|
||||||
raise GulagDBException(e) from e
|
raise GulagDBException(e) from e
|
||||||
@ -104,7 +121,7 @@ class GulagDB:
|
|||||||
dict = {}
|
dict = {}
|
||||||
for (name, value) in zip(desc, tuple):
|
for (name, value) in zip(desc, tuple):
|
||||||
dict[name[0]] = value
|
dict[name[0]] = value
|
||||||
results.append(dict)
|
results.append(QuarMail(dict).__dict__)
|
||||||
return results
|
return results
|
||||||
except mariadb.Error as e:
|
except mariadb.Error as e:
|
||||||
raise GulagDBException(e) from e
|
raise GulagDBException(e) from e
|
||||||
@ -116,7 +133,6 @@ class GulagDB:
|
|||||||
"(filename, content_type) values (%s,%s)",
|
"(filename, content_type) values (%s,%s)",
|
||||||
(attach['filename'], attach['content_type'])
|
(attach['filename'], attach['content_type'])
|
||||||
)
|
)
|
||||||
self.conn.commit()
|
|
||||||
return cursor.lastrowid
|
return cursor.lastrowid
|
||||||
except mariadb.Error as e:
|
except mariadb.Error as e:
|
||||||
raise GulagDBException(e) from e
|
raise GulagDBException(e) from e
|
||||||
@ -128,7 +144,6 @@ class GulagDB:
|
|||||||
"(quarmail_id, attachment_id) values (%s,%s)",
|
"(quarmail_id, attachment_id) values (%s,%s)",
|
||||||
(quarmail_id, attachment_id)
|
(quarmail_id, attachment_id)
|
||||||
)
|
)
|
||||||
self.conn.commit()
|
|
||||||
except mariadb.Error as e:
|
except mariadb.Error as e:
|
||||||
raise GulagDBException(e) from e
|
raise GulagDBException(e) from e
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
from flask import request
|
from flask import request
|
||||||
from flask_restful import Resource, abort
|
from flask_restful import Resource, abort
|
||||||
import json
|
from Entities import Mailbox,MailboxException,QuarMail,QuarMailException,Attachment,AttachmentException
|
||||||
|
from Gulag import GulagException
|
||||||
|
|
||||||
class GulagResource(Resource):
|
class GulagResource(Resource):
|
||||||
gulag = None
|
gulag = None
|
||||||
@ -33,7 +34,10 @@ class ResRoot(GulagResource):
|
|||||||
|
|
||||||
class ResMailboxes(GulagResource):
|
class ResMailboxes(GulagResource):
|
||||||
def get(self):
|
def get(self):
|
||||||
return {"resource": "Mailboxes"}
|
try:
|
||||||
|
return self.gulag.get_mailboxes()
|
||||||
|
except GulagException as e:
|
||||||
|
abort(500, message=e.message)
|
||||||
|
|
||||||
class ResMailbox(GulagResource):
|
class ResMailbox(GulagResource):
|
||||||
def get(self,id):
|
def get(self,id):
|
||||||
@ -41,7 +45,10 @@ class ResMailbox(GulagResource):
|
|||||||
|
|
||||||
class ResQuarMails(GulagResource):
|
class ResQuarMails(GulagResource):
|
||||||
def get(self):
|
def get(self):
|
||||||
return {"resource": "QuarMails"}
|
try:
|
||||||
|
return self.gulag.get_quarmails()
|
||||||
|
except GulagException as e:
|
||||||
|
abort(500, message=e.message)
|
||||||
|
|
||||||
class ResQuarMail(GulagResource):
|
class ResQuarMail(GulagResource):
|
||||||
def get(self,id):
|
def get(self,id):
|
||||||
|
|||||||
@ -1,37 +0,0 @@
|
|||||||
{
|
|
||||||
"daemon":{
|
|
||||||
"listen_host": "127.0.0.1",
|
|
||||||
"listen_port": 5001
|
|
||||||
},
|
|
||||||
"trusted_proxies": {
|
|
||||||
"rprx01":[
|
|
||||||
"172.16.100.5", "fd00:100::5"
|
|
||||||
],
|
|
||||||
"rprx02":[
|
|
||||||
"172.16.100.6", "fd00:100::6"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"api_keys": {
|
|
||||||
"HIGHLY_SECURE_API_KEY": {
|
|
||||||
"user": "GULAG APP"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"uri_prefixes": {
|
|
||||||
"root": "https://<fqdn>/api/v1/",
|
|
||||||
"quarmails": "https://<fqdn>/api/v1/quarmails/",
|
|
||||||
"attachments": "https://<fqdn>/api/v1/attachments/"
|
|
||||||
},
|
|
||||||
"db":{
|
|
||||||
"server": "127.0.0.1",
|
|
||||||
"user": "root",
|
|
||||||
"password": "",
|
|
||||||
"name": "Gulag"
|
|
||||||
},
|
|
||||||
"cleaner":{
|
|
||||||
"retention_period": "12 hour",
|
|
||||||
"interval": 10
|
|
||||||
},
|
|
||||||
"importer":{
|
|
||||||
"interval": 10
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
[uwsgi]
|
|
||||||
processes = 4
|
|
||||||
cheaper = 1
|
|
||||||
cheaper-initial = 1
|
|
||||||
cheaper-step = 1
|
|
||||||
python-path = /app
|
|
||||||
wsgi-file = /app/uwsgi.py
|
|
||||||
pyargv = --config /config/config.json
|
|
||||||
socket = /socket/gulag_uwsgi.sock
|
|
||||||
@ -1,5 +1,7 @@
|
|||||||
create database Gulag;
|
create database Gulag;
|
||||||
|
|
||||||
|
use Gulag;
|
||||||
|
|
||||||
create table Mailboxes(
|
create table Mailboxes(
|
||||||
email_address varchar(767) not null primary key collate 'ascii_general_ci',
|
email_address varchar(767) not null primary key collate 'ascii_general_ci',
|
||||||
name varchar(256) not null,
|
name varchar(256) not null,
|
||||||
@ -9,10 +11,10 @@ create table Mailboxes(
|
|||||||
imap_pass varchar(256) not null,
|
imap_pass varchar(256) not null,
|
||||||
imap_mailbox varchar(256) not null default 'INBOX',
|
imap_mailbox varchar(256) not null default 'INBOX',
|
||||||
imap_mailbox_fp varchar(256) not null default 'false-positives',
|
imap_mailbox_fp varchar(256) not null default 'false-positives',
|
||||||
imap_separator varchar(4) not null default '/'
|
imap_separator varchar(4) not null default '/',
|
||||||
comment varchar(256) default null
|
comment varchar(256) default null
|
||||||
)ENGINE = InnoDB;
|
)ENGINE = InnoDB;
|
||||||
insert into Mailboxes (email_address,name,imap_user,imap_pass,)
|
insert into Mailboxes (email_address,name,imap_user,imap_pass)
|
||||||
values('quarantine-in@example.org','E-Mail inbound quarantine','quarantine-in','quarantine-in_secure_password');
|
values('quarantine-in@example.org','E-Mail inbound quarantine','quarantine-in','quarantine-in_secure_password');
|
||||||
insert into Mailboxes (email_address,name,imap_user,imap_pass)
|
insert into Mailboxes (email_address,name,imap_user,imap_pass)
|
||||||
values('quarantine-out@example.org','E-Mail outbound quarantine','quarantine-out','quarantine-out_secure_password');
|
values('quarantine-out@example.org','E-Mail outbound quarantine','quarantine-out','quarantine-out_secure_password');
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user