agregar página de cambio de clave. corrección de links
parent
a1b84a93d6
commit
19c0887bc5
|
|
@ -1,9 +1,9 @@
|
|||
# coding: utf-8
|
||||
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 flask_login import current_user
|
||||
from webinterface.models.system import Persona
|
||||
from webinterface.models.system import Persona, Correo
|
||||
import pwnedpasswords
|
||||
|
||||
class LoginForm(FlaskForm):
|
||||
|
|
@ -53,3 +53,32 @@ class RegistrationForm(FlaskForm):
|
|||
def validate_password(self, clave):
|
||||
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>')
|
||||
|
||||
|
||||
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 datetime import datetime, date
|
||||
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
|
||||
|
||||
main = Blueprint('main', __name__)
|
||||
|
|
@ -23,7 +23,7 @@ else:
|
|||
def login():
|
||||
|
||||
if current_user.is_authenticated:
|
||||
return redirect(url_for('main.dashboard'))
|
||||
return redirect(systemuri)
|
||||
|
||||
form = LoginForm()
|
||||
if form.validate_on_submit():
|
||||
|
|
@ -52,12 +52,41 @@ def logout():
|
|||
|
||||
return redirect('https://tpmc.ilab.cl/')
|
||||
|
||||
@main.route("/me")
|
||||
@main.route("/system/me", methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def me():
|
||||
image_file = url_for('static', filename='profile_pics/' + current_user.foto)
|
||||
return render_template('system/me.html', title=u'¿Quién soy?',
|
||||
image_file=image_file)
|
||||
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():
|
||||
|
|
|
|||
|
|
@ -1,43 +1,65 @@
|
|||
{% extends "layout.html" %}
|
||||
{% 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="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>
|
||||
</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>
|
||||
</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 %}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@
|
|||
<meta name="author" content="">
|
||||
|
||||
{% if title %}
|
||||
<title>iLab Gestión Académica - {{ title }}</title>
|
||||
<title>Gestión del Transporte Público del Gran Concepción - {{title}}</title>
|
||||
{% else %}
|
||||
<title>iLab Gestión Académica</title>
|
||||
<title>Gestión del Transporte Público del Gran Concepción</title>
|
||||
{% endif %}
|
||||
<link rel="icon" href="/static/favicon.svg" sizes="any" type="image/svg+xml">
|
||||
<link href="/static/googlefonts.css" rel="stylesheet">
|
||||
|
|
@ -34,7 +34,7 @@
|
|||
<div class="sidebar-brand-icon">
|
||||
<i class="fas fa-bus"></i>
|
||||
</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>
|
||||
|
||||
<!-- Divider -->
|
||||
|
|
@ -111,7 +111,7 @@
|
|||
</a>
|
||||
<!-- Dropdown - User Information -->
|
||||
<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>
|
||||
Mis Datos
|
||||
</a>
|
||||
|
|
|
|||
Loading…
Reference in New Issue