189 lines
6.7 KiB
Python
189 lines
6.7 KiB
Python
# -*- coding: utf-8 -*-
|
|
import os
|
|
from flask import Flask, Blueprint, abort, session, g, current_app, request, render_template, send_from_directory, jsonify, flash, redirect
|
|
from flask_login import login_user, current_user, logout_user, login_required
|
|
|
|
from user_agents import parse
|
|
from webinterface import db, bcrypt
|
|
from sqlalchemy import func
|
|
from datetime import datetime, date
|
|
from webinterface.models.system import Persona, Ipaddr, Dispositivo, Identidad, Sesion, Registro, Conexion, Ruta, Sitio, Correo
|
|
from webinterface.content.forms import mMiCuenta, LoginForm, RequestResetForm, ResetPasswordForm
|
|
from webinterface.content.utils import clean_str, es_local
|
|
|
|
main = Blueprint('main', __name__)
|
|
|
|
if os.environ.get('COOKIE_DOMAIN'):
|
|
systemuri = "https://app.{}/".format(os.environ.get('COOKIE_DOMAIN'))
|
|
else:
|
|
systemuri = 'https://app.tpmc.ilab.cl/'
|
|
|
|
|
|
@main.route("/system/login", methods=['GET', 'POST'])
|
|
def login():
|
|
|
|
if current_user.is_authenticated:
|
|
return redirect(systemuri)
|
|
|
|
form = LoginForm()
|
|
if form.validate_on_submit():
|
|
form.login.data = clean_str(form.login.data.lower().strip())
|
|
user = Persona.query.filter(Persona.rut==form.login.data).first()
|
|
if user and bcrypt.check_password_hash(user.clave, form.clave.data):
|
|
login_user(user, remember=form.remember.data)
|
|
g.user = user
|
|
g.sesion.identidad = user
|
|
db.session.commit()
|
|
|
|
next_page = request.args.get('next')
|
|
current_app.logger.info('Acceso exitoso: IP({}), USER({}), UA({})'.format(g.ip.ipaddr,form.login.data, g.dispositivo.parsed_ua))
|
|
return redirect(next_page) if next_page else redirect(systemuri)
|
|
else:
|
|
flash(u'El nombre de usuario o la contraseña son incorrectos.', 'danger')
|
|
current_app.logger.warning('Intento de ingreso fallido: IP({}), USER({}), UA({})'.format(g.ip.ipaddr,form.login.data, g.dispositivo.parsed_ua))
|
|
return render_template('system/login.html', title='Ingreso de Usuarios del Sistema', form=form)
|
|
|
|
|
|
@main.route("/system/logout")
|
|
def logout():
|
|
|
|
logout_user()
|
|
session.pop('sid', None)
|
|
|
|
return redirect('https://tpmc.ilab.cl/')
|
|
|
|
@main.route("/system/me", methods=['GET', 'POST'])
|
|
@login_required
|
|
def micuenta():
|
|
form = mMiCuenta()
|
|
|
|
if form.validate_on_submit():
|
|
if form.clave.data:
|
|
hashed_password = bcrypt.generate_password_hash(form.clave.data).decode('utf-8')
|
|
current_user.clave = hashed_password
|
|
|
|
trimmed = form.correo.data.strip().lower()
|
|
|
|
correo = Correo.query.filter_by(correo=trimmed).first()
|
|
if correo is None:
|
|
correo = Correo(correo=trimmed, cuenta=current_user)
|
|
|
|
current_user.correodefecto=correo
|
|
current_user.telefono = form.fono.data.replace(" ", "")
|
|
db.session.commit()
|
|
|
|
flash(u'Los datos de tu cuenta han sido actualizados.', 'success')
|
|
return redirect(url_for('main.micuenta'))
|
|
|
|
elif request.method == 'GET':
|
|
|
|
if current_user.correodefecto is not None:
|
|
form.correo.data = current_user.correodefecto.correo
|
|
|
|
form.id.data = current_user.id
|
|
form.login.data = current_user.rut
|
|
form.nombrecompleto.data = current_user.nombrecompleto
|
|
form.fono.data = current_user.telefono
|
|
|
|
return render_template('system/me.html', title='Mi Cuenta', form=form)
|
|
|
|
|
|
@main.before_app_request
|
|
def registra_sesion():
|
|
if request.headers.getlist("X-Forwarded-For"):
|
|
remote_ip = request.headers.getlist("X-Forwarded-For")[0]
|
|
else:
|
|
remote_ip = request.environ['REMOTE_ADDR']
|
|
uadata = parse(request.user_agent.string)
|
|
|
|
ip = Ipaddr.query.filter_by(ipaddr=remote_ip).one_or_none()
|
|
if ip is None:
|
|
ip = Ipaddr(ipaddr=remote_ip)
|
|
db.session.add(ip)
|
|
db.session.commit()
|
|
|
|
if 'sid' in session:
|
|
sesion = Sesion.query.filter_by(id=session['sid']).one_or_none()
|
|
if sesion is None:
|
|
session.pop('sid', None)
|
|
else:
|
|
dispositivo = Dispositivo.query.filter_by(id=sesion.dispositivoid, parsed_ua=str(uadata)).one_or_none()
|
|
if dispositivo is None:
|
|
session.pop('sid', None)
|
|
else:
|
|
conexion = Conexion.query.filter_by(ipaddrid=ip.id, sesionid=sesion.id).one_or_none()
|
|
Ident = sesion.identidad
|
|
if conexion is None:
|
|
conexion = Conexion(ipaddr=ip, sesion=sesion)
|
|
db.session.add(conexion)
|
|
db.session.commit()
|
|
|
|
if 'sid' not in session:
|
|
|
|
dispositivo = Dispositivo.query.filter_by(useragent=request.user_agent.string).one_or_none()
|
|
if dispositivo is None:
|
|
dev = uadata.is_pc and "PC" or uadata.device.family
|
|
os = ("%s %s" % (uadata.os.family, uadata.os.version_string)).strip()
|
|
browser = ("%s %s" % (uadata.browser.family, uadata.browser.version_string)).strip()
|
|
|
|
dispositivo = Dispositivo(useragent=request.user_agent.string, dev=dev , os=os , browser=browser, parsed_ua=str(uadata))
|
|
db.session.add(dispositivo)
|
|
db.session.commit()
|
|
|
|
if uadata.is_bot:
|
|
Ident = Identidad.query.filter_by(login='Buscador').one()
|
|
elif es_local(remote_ip):
|
|
Ident = Identidad.query.filter_by(login='Intranet').one()
|
|
else:
|
|
Ident = Identidad.query.filter_by(login='Internet').one()
|
|
|
|
sesion = Sesion(identidad=Ident, dispositivo=dispositivo)
|
|
db.session.add(sesion)
|
|
db.session.commit()
|
|
|
|
conexion = Conexion(ipaddr=ip, sesion=sesion)
|
|
db.session.add(conexion)
|
|
db.session.commit()
|
|
|
|
|
|
# agregamos el registro asociado a la solicitud actual
|
|
# a la sesion que esta actualmente cargada. Dejamos la sesion guardada en
|
|
# la variable global g.
|
|
|
|
if '/reset_password' in str(request.path):
|
|
rpth = '/reset_password'
|
|
else:
|
|
rpth = str(request.path)
|
|
|
|
solicitud = Ruta.query.filter_by(ruta=rpth).first()
|
|
if solicitud is None:
|
|
solicitud = Ruta(ruta=str(request.path))
|
|
db.session.add(solicitud)
|
|
db.session.commit()
|
|
|
|
host = Sitio.query.filter_by(sitio=request.host).first()
|
|
if host is None:
|
|
host = Sitio(sitio=request.host)
|
|
db.session.add(host)
|
|
db.session.commit()
|
|
|
|
tamano = int(request.headers.get('Content-Length') or 0)
|
|
|
|
now = datetime.now()
|
|
|
|
registro = Registro(sitio=host, ruta=solicitud, sesion=sesion, ipaddr=ip, tamano=tamano)
|
|
db.session.add(registro)
|
|
db.session.commit()
|
|
|
|
conexion.ultimo = now
|
|
sesion.ultimo = now
|
|
db.session.commit()
|
|
|
|
g.ip = ip
|
|
g.user = Ident
|
|
g.sesion = sesion
|
|
g.conexion = conexion
|
|
g.registro = registro
|
|
g.dispositivo = dispositivo
|
|
session['sid'] = g.sesion.id
|