Commit e7682beb by Luciano Barletta

Made more maintainable, not tested

1 parent b577f52e
*
!.py
!.md
!*.py
!*.md
!templates
!install.sh
\ No newline at end of file
import sqlite3
class Table:
id = "id"
file = "file"
serv = "serv"
dest = "dest"
type = "type"
state = "state"
class States:
queued = "queued"
delivered = "delivered"
class DBconnection:
tables = ["msg","history"]
states = [States.queued,States.delivered]
structure = {
Table.id : "integer PRIMARY KEY"
Table.file : "text"
Table.serv : "text"
Table.dest : "text"
Table.type : "text"
Table.state : "text"
}
def __init__(self,db):
ipdb.set_trace()
self.db = db
query = "CREATE TABLE IF NOT EXISTS msg("
for column in DBconnection.structure:
query += column + " " + DBconnection.structure[column] + ","
query[-1] = ")"
# main table
self.query(query)
# delivered messages that were informed
self.query(query.replace("msg","history",1))
def query(self,query,*args):
if query.upper().find("INSERT") == 0:
return "Use la funcion insert() para insertar"
entities = None
for ar in args:
entities = ar
con = sqlite3.connect(self.db)
cursor = con.cursor()
if entities:
cursor.execute(query,entities)
else:
cursor.execute(query)
rows = cursor.fetchall()
con.commit()
con.close()
return rows
def insert(self,table,insertions):
if not table in DBconnection.tables:
return "La tabla " + table + " no existe o no está contemplada"
query = "INSERT INTO " table + "("
values = " VALUES("
for column in insertions:
if not check(column,insertions[column]):
return "El dato '" + insertions[column] + "' no es valido"
query += column + ","
values += insertions[column] + ","
query[-1] = ")"
values[-1] = ")"
con = sqlite3.connect(self.db)
cursor = con.cursor()
cursor.execute(query + values)
cursor.execute("SELECT last_insert_rowid()")
id = cursor.fetchall()[0][0]
con.commit()
con.close()
return id
def check(self,column,data):
if column == Table.serv:
return Services.validate(data)
if column == Table.dest and len(data) <= 13:
return True
if column == Table.type:
return Datatypes.validate(data)
if column == Table.state:
return (data in DBconnection.states)
return False
@staticmethod
def parseToTable(rows):
dictarray = []
for row in rows:
dictrow = {}
i = 0
for column in DBconnection.structure:
dictrow[column] = row[i]
i = i + 1
dictarray.append(dictrow)
return dictarray
......@@ -9,6 +9,7 @@ from python_arptable import get_arp_table
app = Flask(__name__)
retry_timer = 10
last_file = {}
@app.route('/')
def main():
......@@ -24,10 +25,10 @@ def init():
return key(mac)
def key(dir):
os.system("openssl genrsa -out ./" + dir + "/rsa_key.pri 2048") # private key
os.system("openssl rsa -in ./" + dir + "/rsa_key.pri -out ./" + dir + "/rsa_key.pub -outform PEM -pubout") # public key
os.system("openssl genrsa -out " + dir + "/rsa_key.pri 2048") # private key
os.system("openssl rsa -in " + dir + "/rsa_key.pri -out " + dir + "/rsa_key.pub -outform PEM -pubout") # public key
f = open("./" + dir + "/rsa_key.pub", "r")
f = open(dir + "/rsa_key.pub", "r")
key = f.read()
f.close()
return key
......@@ -47,8 +48,9 @@ def data():
key = request.files.get('key')
if key != None:
key.save("./" + dir + "/key")
request.files['data'].save("./" + dir + "/data")
key.save(dir + "/key")
request.files['data'].save(dir + "/" + request.files['data'].filename)
last_file[dir] = request.files['data'].filename
return ""
@app.route('/msg', methods = ['POST'])
......@@ -60,22 +62,21 @@ def msg():
return "Debe llamar a /init primero"
# symetric key was sent, decrypt data
if os.path.exists("./" + dir + "/key"):
if os.path.exists(dir + "/key"):
# decrypt random key with stored private key and store in host folder
os.system("openssl rsautl -decrypt -inkey ./" + dir + "/rsa_key.pri -in ./" + dir + "/key -out ./" + dir + "/key")
os.system("openssl rsautl -decrypt -inkey " + dir + "/rsa_key.pri -in " + dir + "/key -out " + dir + "/key")
# decrypt JSON with decrypted random key and store in dir folder
os.system("openssl enc -d -aes-256-cbc -in ./" + dir + "/data -out ./" + dir + "/data -pass file:./" + dir + "/key")
os.system("openssl enc -d -aes-256-cbc -in " + dir + "/" + last_file[dir] + " -out " + dir + "/" + last_file[dir] + " -pass file:" + dir + "/key")
# delete key
os.system("rm ./" + dir + "/key")
os.system("rm " + dir + "/key")
query = {
'dir' : dir,
'file' : dir + "/" + last_file[dir],
'serv' : request.values['serv'],
'dest' : request.values['dest'],
'type' : request.values['type']
}
id = process.store(query)
os.system("mv ./" + dir + "/data ./" + dir + "/" + id)
return str(id)
@app.route('/cons', methods = ['POST'])
......
import sqlite3
from sqlite3 import Error
import ipdb
import os
from services import serviceFactory, Datatypes, Services
class DBconnection:
def __init__(self,db):
# main table
self.db = db
self.query("CREATE TABLE IF NOT EXISTS msg(\
id integer PRIMARY KEY,\
dir text,\
serv text CHECK( serv IN ('wpp1', 'wwp2', 'telegram', 'sms') ),\
dest text CHECK( LENGTH(dest) <= 13 ),\
type text CHECK( type IN ('text', 'image', 'file', 'multimedia') ),\
state text CHECK( state IN ('delivered', 'queued') ) )")
# delivered messages that were informed
self.query("CREATE TABLE IF NOT EXISTS history(\
id integer PRIMARY KEY,\
dir text,\
serv text CHECK( serv IN ('wpp1', 'wwp2', 'telegram', 'sms') ),\
dest text CHECK( LENGTH(dest) <= 13 ),\
type text CHECK( type IN ('text', 'image', 'file', 'multimedia') ),\
state text CHECK( state IN ('delivered', 'queued') ) )")
def query(self,query,*args):
con = sqlite3.connect(self.db)
cursor = con.cursor()
entities = None
for ar in args:
entities = ar
if entities:
cursor.execute(query,entities)
else:
cursor.execute(query)
if query.find("INSERT") == 0:
cursor.execute("SELECT last_insert_rowid()")
rows = cursor.fetchall()
con.commit()
con.close()
return rows
@staticmethod
def parseToTable(rows):
dictarray = []
for row in rows:
dictarray.append(
{
'id' : row[0],
'dir' : row[1],
'serv' : row[2],
'dest' : row[3],
'type' : row[4],
'state' : row[5]
}
)
return dictarray
from database import DBconnection, Table, States
class Process:
......@@ -67,28 +12,33 @@ class Process:
# stores the message and returns its id
def store(self,query):
# service is wrong
if not Services.validate(query['serv']):
return "No existe el servicio '" + query['serv'] + "'"
if not Services.validate(query[Table.serv]):
return "No existe el servicio '" + query[Table.serv] + "'"
# message can't be sent by this service
if not serviceFactory(query['serv']).validate(query['type']):
return "El servicio '" + query['serv'] + "' no puede enviar el tipo '" + query['type'] + "'"
entities = (query['dir'],query['serv'],query['dest'],query['type'],'queued')
rows = self.conn.query("INSERT INTO msg(dir,serv,dest,type,state) VALUES(?,?,?,?,?)", entities)
return str(rows[0][0])
if not serviceFactory(query[Table.serv]).validate(query[Table.type]):
return "El servicio '" + query[Table.serv] + "' no puede enviar el tipo '" + query[Table.type] + "'"
entities = {
Table.file : query[Table.file],
Table.dest : query[Table.dest],
Table.serv : query[Table.serv],
Table.type : query[Table.type],
Table.state : query[Table.state]
}
id = self.conn.insert("msg",entities)
return str(id)
# tries to send all messages available
def send(self):
rows = self.conn.query("SELECT * FROM msg WHERE state = 'queued'")
rows = self.conn.query("SELECT * FROM msg WHERE state = ?",(States.queued,))
for query in DBconnection.parseToTable(rows):
# if folder doesn't exists, erase the message request, it can't be read anyway
if not os.path.exists(query['dir']):
self.conn.query("DELETE FROM msg WHERE id = ?",(query['id'],))
serv = serviceFactory(query['serv'])
# if file doesn't exist, erase the message request, it can't be read anyway
if not os.path.exists(query[Table.file]):
self.conn.query("DELETE FROM msg WHERE id = ?",(query[Table.id],))
serv = serviceFactory(query[Table.serv])
success = serv.send(query)
if success:
# save as delivered
self.conn.query("UPDATE msg SET state = 'delivered' WHERE id = ?",(query['id'],))
self.conn.query("UPDATE msg SET state = ? WHERE id = ?",(States.delivered,query[Table.id]))
# returns the state of a message given its id
# stores the message to history if delivered
......@@ -98,7 +48,14 @@ class Process:
return "El id " + str(id) + " no existe"
rows = DBconnection.parseToTable(rows)
row = rows[0]
if row['state'] == "delivered":
if row[Table.state] == States.delivered:
self.conn.query("DELETE FROM msg WHERE id = ?",(id,))
self.conn.query("INSERT INTO history(dir,serv,dest,type,state) VALUES(?,?,?,?,?)", (row['dir'],row['serv'],row['dest'],row['type'],row['state']))
return row['state']
\ No newline at end of file
entities = {
Table.file : row[Table.file],
Table.serv : row[Table.serv],
Table.dest : row[Table.dest],
Table.type : row[Table.type],
Table.state : row[Table.state],
}
self.conn.insert("history",entities)
return row[Table.state]
\ No newline at end of file
import requests
import json
import os
from database import Table
from abc import ABC, abstractmethod
class Services:
......@@ -57,16 +58,16 @@ class Wpp1(ServiceBase):
server = "https://archivos.hgtsa.com.ar/"
def send(self,data):
file_path = "./" + data['dir'] + "/" + str(data['id'])
if data['type'] == Datatypes.text:
file_path = data[Table.file]
if data[Table.type] == Datatypes.text:
f = open(file_path)
text = f.read()
f.close()
result = requests.get(url = Wpp1.URL + Wpp1.URLmode[data['type']],params = {'token':Wpp1.token,'uid':Wpp1.uid,'to':data['dest'],'text':text})
result = requests.get(url = Wpp1.URL + Wpp1.URLmode[data[Table.type]],params = {'token':Wpp1.token,'uid':Wpp1.uid,'to':data[Table.dest],'text':text})
return result.json()['success']
else:
path = requests.post(url = Wpp1.server, files = { 'data' : (str(data['id']),open(file_path,'rb')) })
result = requests.get(url = Wpp1.URL + Wpp1.URLmode[data['type']],params = {'token':Wpp1.token,'uid':Wpp1.uid,'to':data['dest'],'url':Wpp1.server + path.text})
path = requests.post(url = Wpp1.server, files = { 'data' : (str(data[Table.id]),open(file_path,'rb')) })
result = requests.get(url = Wpp1.URL + Wpp1.URLmode[data[Table.type]],params = {'token':Wpp1.token,'uid':Wpp1.uid,'to':data[Table.dest],'url':Wpp1.server + path.text})
return result.json()['success']
def validate(self,datatype):
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!