agregar página de cambio de clave. corrección de links
parent
a1b84a93d6
commit
19c0887bc5
|
|
@ -1,9 +1,9 @@
|
||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
from wtforms import StringField, PasswordField, SubmitField, BooleanField
|
from wtforms import StringField, PasswordField, SubmitField, BooleanField, HiddenField
|
||||||
from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError
|
from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
from webinterface.models.system import Persona
|
from webinterface.models.system import Persona, Correo
|
||||||
import pwnedpasswords
|
import pwnedpasswords
|
||||||
|
|
||||||
class LoginForm(FlaskForm):
|
class LoginForm(FlaskForm):
|
||||||
|
|
@ -53,3 +53,32 @@ class RegistrationForm(FlaskForm):
|
||||||
def validate_password(self, clave):
|
def validate_password(self, clave):
|
||||||
if pwnedpasswords.check(clave.data):
|
if pwnedpasswords.check(clave.data):
|
||||||
raise ValidationError(u'La clave ingresada es insegura. Verifíquelo en <a href="https://haveibeenpwned.com/Passwords">\';--have i been pwned?</a>')
|
raise ValidationError(u'La clave ingresada es insegura. Verifíquelo en <a href="https://haveibeenpwned.com/Passwords">\';--have i been pwned?</a>')
|
||||||
|
|
||||||
|
|
||||||
|
class mMiCuenta(FlaskForm):
|
||||||
|
id = HiddenField()
|
||||||
|
login = StringField('Usuario', render_kw={'readonly': True})
|
||||||
|
nombrecompleto = StringField('Nombre', render_kw={'readonly': True})
|
||||||
|
|
||||||
|
|
||||||
|
correo = StringField('Correo Principal', validators=[DataRequired(), Email()])
|
||||||
|
clave = PasswordField('Clave')
|
||||||
|
fono = StringField('Telefono', render_kw={"placeholder": "+569 8765 4321"})
|
||||||
|
|
||||||
|
submit = SubmitField('Modificar')
|
||||||
|
|
||||||
|
def validate_fono(self, field):
|
||||||
|
parsed = field.data.replace(" ", "")
|
||||||
|
|
||||||
|
if not parsed:
|
||||||
|
raise ValidationError(u'Debe ingresar un número de teléfono.')
|
||||||
|
if not parsed.startswith('+'):
|
||||||
|
raise ValidationError(u'Ingrese el número completo "+569XYZWABCD".')
|
||||||
|
if len(parsed) < 11:
|
||||||
|
raise ValidationError(u'Ingrese el número completo "+569XYZWABCD".')
|
||||||
|
if not parsed[1:].isdigit():
|
||||||
|
raise ValidationError(u'El número ingresado no es válido, contiene caracteres no-numéricos.')
|
||||||
|
|
||||||
|
def validate_clave(self, field):
|
||||||
|
if field.data and pwnedpasswords.check(field.data):
|
||||||
|
raise ValidationError(u'La clave ingresada es insegura. Verifíque la seguridad de su clave en <a href="https://haveibeenpwned.com/Passwords" target="_blank">\';--have i been pwned?</a>')
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ from webinterface import db, bcrypt
|
||||||
from sqlalchemy import func
|
from sqlalchemy import func
|
||||||
from datetime import datetime, date
|
from datetime import datetime, date
|
||||||
from webinterface.models.system import Persona, Ipaddr, Dispositivo, Identidad, Sesion, Registro, Conexion, Ruta, Sitio, Correo
|
from webinterface.models.system import Persona, Ipaddr, Dispositivo, Identidad, Sesion, Registro, Conexion, Ruta, Sitio, Correo
|
||||||
from webinterface.content.forms import RegistrationForm, LoginForm, RequestResetForm, ResetPasswordForm
|
from webinterface.content.forms import mMiCuenta, LoginForm, RequestResetForm, ResetPasswordForm
|
||||||
from webinterface.content.utils import clean_str, es_local
|
from webinterface.content.utils import clean_str, es_local
|
||||||
|
|
||||||
main = Blueprint('main', __name__)
|
main = Blueprint('main', __name__)
|
||||||
|
|
@ -23,7 +23,7 @@ else:
|
||||||
def login():
|
def login():
|
||||||
|
|
||||||
if current_user.is_authenticated:
|
if current_user.is_authenticated:
|
||||||
return redirect(url_for('main.dashboard'))
|
return redirect(systemuri)
|
||||||
|
|
||||||
form = LoginForm()
|
form = LoginForm()
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
|
|
@ -52,12 +52,41 @@ def logout():
|
||||||
|
|
||||||
return redirect('https://tpmc.ilab.cl/')
|
return redirect('https://tpmc.ilab.cl/')
|
||||||
|
|
||||||
@main.route("/me")
|
@main.route("/system/me", methods=['GET', 'POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def me():
|
def micuenta():
|
||||||
image_file = url_for('static', filename='profile_pics/' + current_user.foto)
|
form = mMiCuenta()
|
||||||
return render_template('system/me.html', title=u'¿Quién soy?',
|
|
||||||
image_file=image_file)
|
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
|
@main.before_app_request
|
||||||
def registra_sesion():
|
def registra_sesion():
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,65 @@
|
||||||
{% extends "layout.html" %}
|
{% extends "layout.html" %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="card-header bg-primary"><h4 class="text-white"><i class="fas fa-user-circle mr-2"></i>{{ title }}</h4></div>
|
|
||||||
<div class="content-section">
|
<div class="content-section">
|
||||||
<div class="media">
|
|
||||||
<img class="rounded-circle account-img" src="{{ image_file }}">
|
|
||||||
<div class="media-body">
|
|
||||||
{% if not current_user.alias %}
|
|
||||||
<h2 class="account-heading">{{ current_user.nombrecompleto }}</h2>
|
|
||||||
{% else %}
|
|
||||||
<h2 class="account-heading">{{ current_user.alias }}</h2>
|
|
||||||
{% endif %}
|
|
||||||
<p class="text-secondary">{{ current_user.correodefecto.correo }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<fieldset class="form-group">
|
|
||||||
<legend class="border-bottom mb-4">Información de la Cuenta</legend>
|
|
||||||
<div class="form-group">
|
|
||||||
Nombre:
|
|
||||||
{{ current_user.nombrecompleto }}
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
Login:
|
|
||||||
{{ current_user.login }}
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
Correo:
|
|
||||||
{{ current_user.correodefecto.correo }}
|
|
||||||
</div>
|
|
||||||
<legend class="border-bottom mb-4">Personalización</legend>
|
|
||||||
<div class="form-group">
|
|
||||||
Alias:
|
|
||||||
{{ current_user.alias }}
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
|
|
||||||
|
<form method="POST" action="" enctype="multipart/form-data">
|
||||||
|
{{ form.hidden_tag() }}
|
||||||
|
<fieldset class="form-group">
|
||||||
|
<legend class="border-bottom mb-4">Datos del usuario</legend>
|
||||||
|
<div class="form-group">
|
||||||
|
{{ form.nombrecompleto.label() }}
|
||||||
|
{{ form.nombrecompleto(class="form-control form-control-lg") }}
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
{{ form.login.label(class="form-control-label") }}
|
||||||
|
{{ form.login(class="form-control form-control-lg") }}
|
||||||
|
</div>
|
||||||
|
<legend class="border-bottom mb-4">Actualizar Información</legend>
|
||||||
|
<div class="form-group">
|
||||||
|
{{ form.correo.label(class="form-control-label") }} <span class='text-danger'>(obligatorio)</span>
|
||||||
|
{% if form.correo.errors %}
|
||||||
|
{{ form.correo(class="form-control form-control-lg is-invalid") }}
|
||||||
|
<div class="invalid-feedback">
|
||||||
|
{% for error in form.correo.errors %}
|
||||||
|
<span>{{ error }}</span>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
{{ form.correo(class="form-control form-control-lg") }}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
{{ form.fono.label(class="form-control-label") }} <span class='text-danger'>(obligatorio)</span>
|
||||||
|
{% if form.fono.errors %}
|
||||||
|
{{ form.fono(class="form-control form-control-lg is-invalid") }}
|
||||||
|
<div class="invalid-feedback">
|
||||||
|
{% for error in form.fono.errors %}
|
||||||
|
<span>{{ error }}</span>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
{{ form.fono(class="form-control form-control-lg") }}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
{{ form.clave.label(class="form-control-label") }}
|
||||||
|
{% if form.clave.errors %}
|
||||||
|
{{ form.clave(class="form-control form-control-lg is-invalid") }}
|
||||||
|
<div class="invalid-feedback">
|
||||||
|
{% for error in form.clave.errors %}
|
||||||
|
<span>{{ error|safe }}</span>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
{{ form.clave(class="form-control form-control-lg") }}
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
<div class="form-group justify-content-end d-flex">
|
||||||
|
{{ form.submit(class="btn btn-lg btn-primary") }}
|
||||||
|
<a href="https://app.tpmc.ilab.cl/" class="btn btn-lg btn-secondary">Volver</a>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<a href="{{ url_for('main.dashboard') }}" class="btn btn-info btn-lg btn-block mt-2"><i class="fas fa-undo-alt mr-2"></i>Volver</a>
|
|
||||||
|
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,9 @@
|
||||||
<meta name="author" content="">
|
<meta name="author" content="">
|
||||||
|
|
||||||
{% if title %}
|
{% if title %}
|
||||||
<title>iLab Gestión Académica - {{ title }}</title>
|
<title>Gestión del Transporte Público del Gran Concepción - {{title}}</title>
|
||||||
{% else %}
|
{% else %}
|
||||||
<title>iLab Gestión Académica</title>
|
<title>Gestión del Transporte Público del Gran Concepción</title>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<link rel="icon" href="/static/favicon.svg" sizes="any" type="image/svg+xml">
|
<link rel="icon" href="/static/favicon.svg" sizes="any" type="image/svg+xml">
|
||||||
<link href="/static/googlefonts.css" rel="stylesheet">
|
<link href="/static/googlefonts.css" rel="stylesheet">
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
<div class="sidebar-brand-icon">
|
<div class="sidebar-brand-icon">
|
||||||
<i class="fas fa-bus"></i>
|
<i class="fas fa-bus"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="sidebar-brand-text mx-1">Gestión del Transporte Público del Gran Concepción</div>
|
<div class="sidebar-brand-text mx-1">TPMC</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<!-- Divider -->
|
<!-- Divider -->
|
||||||
|
|
@ -111,7 +111,7 @@
|
||||||
</a>
|
</a>
|
||||||
<!-- Dropdown - User Information -->
|
<!-- Dropdown - User Information -->
|
||||||
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
|
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
|
||||||
<a class="dropdown-item" href="/system/me">
|
<a class="dropdown-item" href="https://tpmc.ilab.cl/system/me">
|
||||||
<i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
|
<i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||||
Mis Datos
|
Mis Datos
|
||||||
</a>
|
</a>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue