deploy.py 4.9 KB
#-*- coding: utf-8 -*-
from flask import Flask, render_template, json, request, url_for, jsonify
from werkzeug.datastructures import FileStorage
from process import Process
from python_arptable import get_arp_table
from enums import States, Table
from Wpp1State import StatePhoneWs, StateMail
import os, ipdb, time, threading, random, datetime, config


app = Flask(__name__)
TelState = StatePhoneWs()
MailState = StateMail()
# carpeta de los mensajes
msgfolder = config.folder#"msg/"
# id mínimo para una tabla
minid = 1
# id máximo para una tabla
maxid = 2**63
# tiempo para reintentar mensajhes
retry_timer = 10
# tiempo para limpieza
clean_timer = 20
# largo de los nombres de las carpetas bajo msg/
prefix_lenght = 16
# tiempo límite que debe pasar para eliminar cosas
operation_timer = 86400
# conección a base de datos
process = Process(config.db, TelState, MailState)
#Cache de estado de telefonos


@app.route('/')
def main():
  return render_template('index.html')

# Devuelve la llave pública del server
@app.route('/key', methods = ['GET', 'POST'])
def key():
  f = open("rsa_key.pub", "r")
  key = f.read()
  f.close()
  return key

@app.route("/state/<tel>", methods = ['GET'])
def estadoWabox(tel):
  if tel == "default":
    xi = TelState.ChequearTelefono(config.WS_uid)
  else:
    xi = TelState.ChequearTelefono(tel)
  return(xi)

@app.route("/state/mail", methods = ['POST'])
def estadoMail():
  datos = request.json
  #print(datos)
  test = MailState.ChequearMailServer(datos["user"], datos["pass"], int(datos["port"]), datos["host"])
  return(str(test))

# Guarda archivos del emisor en una nueva carpeta (desencriptados)
# Pide guardar en base de datos una preinstancia del mensaje
@app.route('/data', methods = ['POST'])
def data():
  prefix = newprefix()
  path = msgfolder + prefix + "/"
  os.mkdir(path)

  key = request.files.get('key')
  #if key:
  #  print("desencripto deploy.py 70")
  #  request.files['key'].save(path + "rand.key.enc")
    # denecripto llave simétrica con mi llave privada y la guardo en la carpeta del emisor
  #  os.system("openssl rsautl -decrypt -inkey rsa_key.pri -in " + path + "rand.key.enc -out " + path + "rand.key")
  #  os.remove(path + "rand.key.enc")

  for file in request.files:
    # si hay llave y no es esta
    filepath = path + file
    #if key and file != "key":
    #  request.files[file].save(filepath + ".enc")
      # desencripto archivo con la llave simétrica y lo guardo en la carpeta del emisor 
    #  os.system("openssl enc -d -aes-256-cbc -in " + filepath + ".enc -out " + filepath + " -pass file:" + path + "rand.key")
    #  os.remove(filepath + ".enc")
    #else:
    request.files[file].save(filepath)

  #if key:
  #  os.remove(path + "rand.key")
  
  return str(process.datastore(
    random.randrange(minid,maxid),
    path))

# Devuelve un string al azar entre [0-9,a-z,A-Z]
def newprefix():
  prefix = ""
  i = 0
  while i < prefix_lenght:
    range = random.randrange(3)
    if range == 0:
      prefix += chr(random.randrange(48,58))
    if range == 1:
      prefix += chr(random.randrange(65,91))
    if range == 2:
      prefix += chr(random.randrange(97,123))
    i += 1
  return prefix

# Guarda los parámetros de los archivos enviados en /data
@app.route('/msg', methods = ['POST'])
def msg():
  id = request.values['id']
  query = {
    Table.id : id,
    Table.serv : request.values['serv'],
    Table.dest : request.values['dest'],
    Table.type : request.values['type'],
    Table.info : request.values.get('info')
  }
  state = process.paramstore(query)
  return state

# Consulta el estado de un mensaje dado su id
@app.route('/cons', methods = ['POST'])
def cons():
  id_query = request.values['id']
  row = process.lookup(id_query)
  if type(row) == str:  # error
    return row 
  if row[Table.state] == States.delivered:
    os.system("rm -r " + row[Table.path])
  return str(row[Table.state])

# Intenta enviar mensajes
def attempt():
  p = Process(config.db, TelState, MailState)
  p.send()
  threading.Timer(retry_timer, attempt).start()

# Limpia basura
def clean():
  p = Process(config.db, TelState, MailState)
  paths = p.paths()
  now = datetime.datetime.now()

  for folder in paths:
    # carpeta no existe, borrar mensaje
    if not os.path.exists(folder):
      p.deletepath(folder)
      continue

    mtime = os.path.getmtime(folder)
    # Si la carpeta existe por más de X segundos, borrala
    if int(now.strftime("%Y%m%d%H%M%S")) - int(time.strftime("%Y%m%d%H%M%S")) > operation_timer:
      os.system("rm -r " + folder)

  threading.Timer(clean_timer, clean).start()

# Inicio del servicio
if __name__ == "__main__":
  # Genero llaves
  #os.system("openssl genrsa -out rsa_key.pri 4096") # private key
  #os.system("openssl rsa -in rsa_key.pri -out rsa_key.pub -outform PEM -pubout") # public key
  # Demonio attempt
  attempt()
  # Demonio clean
  clean()
  # creo msg/ si no existe
  if not os.path.exists(msgfolder):
    os.mkdir(msgfolder)
  app.run(host="0.0.0.0", port=8080)