Commit e7682beb by Luciano Barletta

Made more maintainable, not tested

1 parent b577f52e
* *
!.py
!.md
!templates
\ No newline at end of file \ No newline at end of file
!*.py
!*.md
!templates
!install.sh
\ No newline at end of file \ 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 ...@@ -9,6 +9,7 @@ from python_arptable import get_arp_table
app = Flask(__name__) app = Flask(__name__)
retry_timer = 10 retry_timer = 10
last_file = {}
@app.route('/') @app.route('/')
def main(): def main():
...@@ -24,10 +25,10 @@ def init(): ...@@ -24,10 +25,10 @@ def init():
return key(mac) return key(mac)
def key(dir): def key(dir):
os.system("openssl genrsa -out ./" + dir + "/rsa_key.pri 2048") # private 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 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() key = f.read()
f.close() f.close()
return key return key
...@@ -47,8 +48,9 @@ def data(): ...@@ -47,8 +48,9 @@ def data():
key = request.files.get('key') key = request.files.get('key')
if key != None: if key != None:
key.save("./" + dir + "/key") key.save(dir + "/key")
request.files['data'].save("./" + dir + "/data") request.files['data'].save(dir + "/" + request.files['data'].filename)
last_file[dir] = request.files['data'].filename
return "" return ""
@app.route('/msg', methods = ['POST']) @app.route('/msg', methods = ['POST'])
...@@ -60,22 +62,21 @@ def msg(): ...@@ -60,22 +62,21 @@ def msg():
return "Debe llamar a /init primero" return "Debe llamar a /init primero"
# symetric key was sent, decrypt data # 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 # 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 # 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 # delete key
os.system("rm ./" + dir + "/key") os.system("rm " + dir + "/key")
query = { query = {
'dir' : dir, 'file' : dir + "/" + last_file[dir],
'serv' : request.values['serv'], 'serv' : request.values['serv'],
'dest' : request.values['dest'], 'dest' : request.values['dest'],
'type' : request.values['type'] 'type' : request.values['type']
} }
id = process.store(query) id = process.store(query)
os.system("mv ./" + dir + "/data ./" + dir + "/" + id)
return str(id) return str(id)
@app.route('/cons', methods = ['POST']) @app.route('/cons', methods = ['POST'])
......
import sqlite3
from sqlite3 import Error
import ipdb import ipdb
import os import os
from services import serviceFactory, Datatypes, Services from services import serviceFactory, Datatypes, Services
from database import DBconnection, Table, States
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
class Process: class Process:
...@@ -67,28 +12,33 @@ class Process: ...@@ -67,28 +12,33 @@ class Process:
# stores the message and returns its id # stores the message and returns its id
def store(self,query): def store(self,query):
# service is wrong # service is wrong
if not Services.validate(query['serv']): if not Services.validate(query[Table.serv]):
return "No existe el servicio '" + query['serv'] + "'" return "No existe el servicio '" + query[Table.serv] + "'"
# message can't be sent by this service # message can't be sent by this service
if not serviceFactory(query['serv']).validate(query['type']): if not serviceFactory(query[Table.serv]).validate(query[Table.type]):
return "El servicio '" + query['serv'] + "' no puede enviar el tipo '" + query['type'] + "'" return "El servicio '" + query[Table.serv] + "' no puede enviar el tipo '" + query[Table.type] + "'"
entities = {
entities = (query['dir'],query['serv'],query['dest'],query['type'],'queued') Table.file : query[Table.file],
rows = self.conn.query("INSERT INTO msg(dir,serv,dest,type,state) VALUES(?,?,?,?,?)", entities) Table.dest : query[Table.dest],
return str(rows[0][0]) 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 # tries to send all messages available
def send(self): 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): for query in DBconnection.parseToTable(rows):
# if folder doesn't exists, erase the message request, it can't be read anyway # if file doesn't exist, erase the message request, it can't be read anyway
if not os.path.exists(query['dir']): if not os.path.exists(query[Table.file]):
self.conn.query("DELETE FROM msg WHERE id = ?",(query['id'],)) self.conn.query("DELETE FROM msg WHERE id = ?",(query[Table.id],))
serv = serviceFactory(query['serv']) serv = serviceFactory(query[Table.serv])
success = serv.send(query) success = serv.send(query)
if success: if success:
# save as delivered # 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 # returns the state of a message given its id
# stores the message to history if delivered # stores the message to history if delivered
...@@ -98,7 +48,14 @@ class Process: ...@@ -98,7 +48,14 @@ class Process:
return "El id " + str(id) + " no existe" return "El id " + str(id) + " no existe"
rows = DBconnection.parseToTable(rows) rows = DBconnection.parseToTable(rows)
row = rows[0] 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("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 \ 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 \ No newline at end of file
import requests import requests
import json import json
import os import os
from database import Table
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
class Services: class Services:
...@@ -57,16 +58,16 @@ class Wpp1(ServiceBase): ...@@ -57,16 +58,16 @@ class Wpp1(ServiceBase):
server = "https://archivos.hgtsa.com.ar/" server = "https://archivos.hgtsa.com.ar/"
def send(self,data): def send(self,data):
file_path = "./" + data['dir'] + "/" + str(data['id']) file_path = data[Table.file]
if data['type'] == Datatypes.text: if data[Table.type] == Datatypes.text:
f = open(file_path) f = open(file_path)
text = f.read() text = f.read()
f.close() 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'] return result.json()['success']
else: else:
path = requests.post(url = Wpp1.server, files = { 'data' : (str(data['id']),open(file_path,'rb')) }) 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['type']],params = {'token':Wpp1.token,'uid':Wpp1.uid,'to':data['dest'],'url':Wpp1.server + path.text}) 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'] return result.json()['success']
def validate(self,datatype): 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!