utils.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. # -*- coding: utf-8 -*-
  2. '''
  3. Gestor de nodos para LaOtraRed La Paz - El Alto
  4. Copyright (C) 2017 Rodrigo Garcia
  5. This program is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU Affero General Public License as
  7. published by the Free Software Foundation, either version 3 of the
  8. License, or (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU Affero General Public License for more details.
  13. You should have received a copy of the GNU Affero General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. '''
  16. # Este archivo contiene utilidades en general
  17. import hashlib
  18. import uuid
  19. from database.database import init_db, db_session
  20. from database.database import engine
  21. from .models import Nodo, Ubicacion
  22. from gestor.configs import RUTA_SCRIPT_GENERADOR_FIRMWARES, RUTA_IMAGENES_FIRMWARE_GENERADAS
  23. SeleccionValidaDireccionesPublicas = (14,30,62,126,254)
  24. SeleccionValidaDireccionesPrivadas = (30,62,126)
  25. def listas_routers():
  26. ''' Busca en la ruta del script para generar firmware los archivos
  27. `modelos_2.4Ghz.txt' y `modelos_dualBand.txt'
  28. Retorna dos listas una lista con los modelos de routers en el archivo de 2.4Ghz
  29. y otra con los modelos dualBand
  30. '''
  31. archivo_2_4Ghz = RUTA_SCRIPT_GENERADOR_FIRMWARES + "modelos_2.4Ghz.txt"
  32. archivo_dualBand = RUTA_SCRIPT_GENERADOR_FIRMWARES + "modelos_dualBand.txt"
  33. modelos_2_4Ghz = []
  34. try:
  35. fil = open(archivo_2_4Ghz, 'r')
  36. for modelo in fil.readlines():
  37. modelos_2_4Ghz.append(modelo[:-1]) # omitiendo posible \n
  38. except:
  39. return ("Error interno, con archivo de modelos <b>2.4Ghz</b>")
  40. modelos_dualBand = []
  41. try:
  42. fil = open(archivo_dualBand, 'r')
  43. for modelo in fil.readlines():
  44. modelos_dualBand.append(modelo[:-1]) # omitiendo posible \n
  45. except:
  46. return ("Error interno, con archivo de modelos <b>DUAL BAND</b>")
  47. return (modelos_2_4Ghz, modelos_dualBand)
  48. # funciones de comprobacion de formulario para el chef
  49. def comprobar_modelo(modelo_router):
  50. ''' Comprueba que `modelo_router' este en la lista de routers soportados por
  51. el script, devolviendo True en caso de exito y False si no.
  52. '''
  53. listasRouters = listas_routers()
  54. if modelo_router in listasRouters[0] or \
  55. modelo_router in listasRouters[1]:
  56. return True
  57. return False
  58. def comprobar_numeroDireccionesPublicas(num):
  59. return int(num) in SeleccionValidaDireccionesPublicas
  60. def comprobar_numeroDireccionesPrivadas(num):
  61. return int(num) in SeleccionValidaDireccionesPrivadas
  62. def comprobar_nombresResponsable(nombres=None):
  63. if not nombres or len(nombres) < 4 or len(nombres) > 200:
  64. return False
  65. return True
  66. def comprobar_apellidosResponsable(apellidos=None):
  67. if not apellidos or len(apellidos) < 4 or len(apellidos) > 200:
  68. return False
  69. return True
  70. def comprobar_emailResponsable(email=None):
  71. if not email or len(email) < 5 or len(email) > 254 or \
  72. email.count('@') == 0 or email.count('@') > 2:
  73. return False
  74. # TODO: Analizar agregar comprobacion de existencia de email
  75. # Aunque tambien se puede comprobar generando la imagen
  76. # de firmware y controlando que esta se descargue 1 vez en
  77. # maximo 12 horas. Cuando el proceso de generacion de
  78. # imagenes termine se le envia un email al responsable con
  79. # una url privada donde el(la) puede descargarla.
  80. # El envio de email deberia ser cada 2 horas si no ingresa
  81. # a la url al cabo de 12, se libera este bloque de ips.
  82. return True
  83. def comprobar_telefonoResponsable(telefono=None):
  84. if telefono is not None and len(telefono) > 20:
  85. return False
  86. return True
  87. def comprobar_nombreNodo(nombre=None):
  88. if not nombre or len(nombre) < 3 or len(nombre) > 200:
  89. return False
  90. return True
  91. def comprobar_descripcionNodo(desc=None):
  92. if desc is not None and len(desc) > 2599:
  93. return False
  94. return True
  95. def comprobar_claveEdicion(clave=None):
  96. if not clave or len(clave) < 4:
  97. return False
  98. return True
  99. def comprobar_ubicacionEsPublica(is_public=None):
  100. if is_public == u"SI" or is_public == "NO":
  101. return True
  102. return False
  103. def comprobar_postAgregarNodo(request, errores_detalle=False):
  104. ''' Comprueba que el POST contenga campos validos para introducirlos
  105. en la base de datos y comenzar el proceso de construccion de firmware
  106. Si errores_detalle=False
  107. Retorna True si los campos son correctos y False en otro caso
  108. Si errores_detalle=True:
  109. Retorna un diccionario con los errores detectados
  110. Retorna una lista vacia en caso de que los campos seran correctos
  111. '''
  112. # TODO: agregar log
  113. print ("--- Agregando Nuevo Nodo --- ")
  114. for k,v in request.form.iteritems():
  115. if k != "clave":
  116. print (k,":",v)
  117. else:
  118. h = hashlib.sha256()
  119. h.update(v.encode('utf-8'))
  120. print (k,":",h.hexdigest())
  121. print ("--------------------------- ")
  122. errores = {}
  123. try:
  124. if not comprobar_modelo(request.form["modelos"]):
  125. errores['modelo'] = u"Modelo de enrutador inválido"
  126. if not comprobar_numeroDireccionesPublicas(request.form["ips_publicas"]):
  127. errores['ips_publicas'] = u"Número de direcciones IP públicas no autorizadas"
  128. if not comprobar_numeroDireccionesPrivadas(request.form["ips_privadas"]):
  129. errores['ips_privadas'] = u"Número de direcciones IP privadas no autorizadas"
  130. if not comprobar_nombresResponsable(request.form["nombres"]):
  131. errores['nombres'] = u"Nombre(s) no permitido"
  132. if not comprobar_apellidosResponsable(request.form["apellidos"]):
  133. errores['apellidos'] = u"Apellido(s) no permitido"
  134. if not comprobar_emailResponsable(request.form["email"]):
  135. errores['email'] = u"email no permitido"
  136. if not comprobar_telefonoResponsable(request.form["telf"]):
  137. errores['telf'] = u"Teléfono no reconocido"
  138. if not comprobar_nombreNodo(request.form["nombre_nodo"]):
  139. errores['nombre_nodo'] = u"Nombre del nodo no valido"
  140. if not comprobar_descripcionNodo(request.form["descripcion"]):
  141. errores['descripcion'] = u"Descripción no valida"
  142. if not comprobar_claveEdicion(request.form["clave"]):
  143. errores['clave'] = u"Clave introducida no valida"
  144. if not comprobar_ubicacionEsPublica(request.form['compartir_ubicacion']):
  145. errores['compartir_ubicacion'] = u"Permiso de revelar ubicacion no valido"
  146. except:
  147. errores['excepcion'] = u"Excepcion ocurrida"
  148. print ("Excepcion ocurrida")
  149. if not errores_detalle:
  150. if len(errores) > 0:
  151. return False
  152. return True
  153. else:
  154. return errores
  155. # base de datos
  156. def comprobar_nodoSimilar(request):
  157. ''' Hace una consulta en la tabla Nodo y verifica que no exista un
  158. nodo similar, si existe retorna el id del nodo, si no retorna False
  159. '''
  160. nombres = request.form['nombres'].lower()
  161. apellidos = request.form['apellidos'].lower()
  162. email = request.form['email'].lower()
  163. n = db_session.query(Nodo).\
  164. filter(Nodo.email == email).\
  165. filter(Nodo.nombres_responsable == nombres).\
  166. filter(Nodo.apellidos_responsable == apellidos).first()
  167. print ("buscando nodo similar"+str(n))
  168. if n is not None:
  169. return n.id
  170. return False
  171. def comprobar_responsableNodo(request):
  172. ''' TODO: analizar la utilidad de esta funcion
  173. Hace un query en la tabla Nodo que alguien no trate de suplantar
  174. a otra persona colocando nombres o apellidos distintos a los que ya
  175. se tengan registrados para un email dado.
  176. Retorna el id del nodo similar o None si no se encuentra
  177. '''
  178. nombres = request.form['nombres'].lower()
  179. apellidos = request.form['apellidos'].lower()
  180. email = request.form['email'].lower()
  181. n = db_session.query(Nodo).\
  182. filter(Nodo.email == email).first()
  183. # existe registro de ese email
  184. print ("buscando email:"+str(n))
  185. if n is not None:
  186. if n.nombres_responsable != nombres or \
  187. n.apellidos_responsable != apellidos:
  188. print ("Ya existe registro del email <"+n.email+\
  189. "> dado con datos:"+\
  190. n.nombres_responsable+" "+n.apellidos_responsable)
  191. print ("Se introdujo: "+nombres+" "+apellidos)
  192. return n.id
  193. return None
  194. def obtener_ubicacionResumida(id_ubicacion):
  195. ''' Retorna tupla con algunos datos de la ubicacion resumida
  196. la tupla retornada es:
  197. (id, localidad, zona, direccion, is_public)'''
  198. u = db_session.query(Ubicacion).\
  199. filter(Ubicacion.id == id_ubicacion).first()
  200. if u is not None:
  201. return (id_ubicacion, u.localidad, u.zona, u.direccion, u.is_public)
  202. return ()
  203. def obtener_ubicacionDetallada(id_ubicacion):
  204. ''' Retorna tupla con detalles de ubicacion en orden:
  205. (localidad, zona, direccion, url_mapa, iframe,
  206. elevacion_aproximada, latitud, longitud, is_public)'''
  207. u = db_session.query(Ubicacion).\
  208. filter(Ubicacion.id == id_ubicacion).first()
  209. if u is not None:
  210. return (id_ubicacion, u.localidad, u.zona, u.direccion,
  211. u.url_mapa, u.iframe_mapa, u.elevacion_aproximada,\
  212. u.latitud, u.longitud, u.is_public)
  213. return ()
  214. def crear_ubicacionDummy(is_public=True):
  215. ''' Crea una ubicacion vacia y retorna su id
  216. '''
  217. u = Ubicacion(localidad='No especificada', direccion="No especificada",\
  218. is_public=is_public)
  219. try:
  220. db_session.add(u)
  221. db_session.commit()
  222. except:
  223. return None
  224. print ("Creando ubicacion DUMMY:"+str(u.id))
  225. return u.id
  226. def num_nodosActivos():
  227. ''' Retorna el numero de nodos activos '''
  228. return db_session.query(Nodo).filter(Nodo.is_active==True).count()
  229. def num_nodosProyectados():
  230. ''' Retorna el numero de nodos proyectados '''
  231. return db_session.query(Nodo).filter(Nodo.is_active==False).count()
  232. # return db_session.query(Nodo).filter(Nodo.is_confirmed==True).\
  233. # filter(Nodo.is_active==False).count()
  234. # otras utiliadades
  235. def get_randomToken():
  236. token = uuid.uuid4().hex
  237. return token
  238. def hash_claveEdicion(clave):
  239. h = hashlib.sha256()
  240. h.update(clave.encode('utf-8'))
  241. return h.hexdigest()