Update texts and Fixbugs

This commit is contained in:
Andros Fenollosa 2017-05-18 18:25:54 +02:00
parent f056300d27
commit e09c4abf8c
15 changed files with 166 additions and 131 deletions

35
app.py
View File

@ -4,8 +4,8 @@ from functools import wraps
from forms import LoginForm, SignupForm, EmailResetPasswordForm, ResetPasswordForm from forms import LoginForm, SignupForm, EmailResetPasswordForm, ResetPasswordForm
from models import db, User from models import db, User
from flask_mail import Mail, Message from flask_mail import Mail, Message
import uuid from uuid import uuid4
import crypt from crypt import crypt, mksalt, METHOD_SHA512
# CONFIGURATIONS # CONFIGURATIONS
# Flask # Flask
@ -59,9 +59,13 @@ def signup():
''' '''
form = SignupForm() form = SignupForm()
if form.validate_on_submit(): if form.validate_on_submit():
if User.query.filter_by(email=form.email.data).all(): if not User.query.filter_by(email=form.email.data).all():
my_user = User() my_user = User()
form.populate_obj(my_user) form.populate_obj(my_user)
# Encrypt password
my_user.password = crypt(
form.password.data, mksalt(METHOD_SHA512)
)
db.session.add(my_user) db.session.add(my_user)
# Prepare the account activation email # Prepare the account activation email
msg = Message( msg = Message(
@ -69,15 +73,15 @@ def signup():
sender='no-repy@' + getenv('DOMAIN'), sender='no-repy@' + getenv('DOMAIN'),
recipients=[my_user.email] recipients=[my_user.email]
) )
link = 'http://' + getenv('DOMAIN') + url_for('activate_account') link = 'http://' + getenv('DOMAIN') + url_for('activate_account', token=my_user.token)
msg.body = render_template( msg.body = render_template(
'emails/activate.txt', username=my_user.username, 'emails/activate.txt', username=my_user.username,
token=link + my_user.token token=link
) )
msg.html = render_template( msg.html = render_template(
'emails/activate.html', 'emails/activate.html',
username=my_user.username, username=my_user.username,
token=link + my_user.token token=link
) )
try: try:
# Save new User # Save new User
@ -128,13 +132,16 @@ def forgot_password():
my_user = User.query.filter_by(email=form.email.data).first() my_user = User.query.filter_by(email=form.email.data).first()
if my_user: if my_user:
# Generate new token # Generate new token
token = str(uuid.uuid4()).replace('-', '') token = str(uuid4()).replace('-', '')
# Update user token # Update user token
my_user.token = token my_user.token = token
db.session.add(my_user) db.session.add(my_user)
db.session.commit() db.session.commit()
# Send email with token # Send email with token
link = 'http://' + getenv('DOMAIN') + url_for('update_password') link = 'http://' + getenv('DOMAIN') + url_for(
'update_password',
email=my_user.email, token=token
)
msg = Message( msg = Message(
'Recover password', 'Recover password',
sender='no-repy@' + getenv('DOMAIN'), sender='no-repy@' + getenv('DOMAIN'),
@ -142,12 +149,12 @@ def forgot_password():
) )
msg.body = render_template( msg.body = render_template(
'emails/forgot_password.txt', username=my_user.username, 'emails/forgot_password.txt', username=my_user.username,
token=link + my_user.token token=link
) )
msg.html = render_template( msg.html = render_template(
'emails/forgot_password.html', 'emails/forgot_password.html',
username=my_user.username, username=my_user.username,
token=link + my_user.token token=link
) )
mail.send(msg) mail.send(msg)
flash(''' flash('''
@ -172,8 +179,8 @@ def update_password(email, token):
if my_user: if my_user:
if form.validate_on_submit(): if form.validate_on_submit():
# Encrypt password # Encrypt password
my_user.password = crypt.crypt( my_user.password = crypt(
form.password.data, crypt.mksalt(crypt.METHOD_SHA512) form.password.data, mksalt(METHOD_SHA512)
) )
# Update password # Update password
db.session.add(my_user) db.session.add(my_user)
@ -194,8 +201,8 @@ def login():
if form.validate_on_submit(): if form.validate_on_submit():
# Validate email and password # Validate email and password
email = form.email.data email = form.email.data
password = crypt.crypt( password = crypt(
form.password.data, crypt.mksalt(crypt.METHOD_SHA512) form.password.data, mksalt(METHOD_SHA512)
) )
my_user = User.query.filter_by(email=email, password=password).first() my_user = User.query.filter_by(email=email, password=password).first()
if my_user: if my_user:

Binary file not shown.

7
envExample Normal file
View File

@ -0,0 +1,7 @@
export DOMAIN='example.com'
export SECRET_KEY='my secret'
export DEBUG=True
export SQLALCHEMY_DATABASE_URI='sqlite:///database.sqlite'
export MAIL_SERVER=''
export MAIL_USERNAME=''
export MAIL_PASSWORD=''

View File

@ -2,24 +2,91 @@ from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField from wtforms import StringField, PasswordField, BooleanField
from wtforms.validators import DataRequired, Email, Length, EqualTo from wtforms.validators import DataRequired, Email, Length, EqualTo
class LoginForm(FlaskForm): class LoginForm(FlaskForm):
email = StringField('E-mail', validators=[DataRequired('Necesito un E-mail'), Email('Debe tener un formato válido')]) '''
password = PasswordField('Contraseña', validators=[DataRequired('No me has indicado una contraseña')]) Form Login
'''
email = StringField(
'Email',
validators=[
DataRequired(),
Email()
]
)
password = PasswordField(
'Password',
validators=[
DataRequired()
]
)
class SignupForm(FlaskForm): class SignupForm(FlaskForm):
username = StringField('Nombre de usuario', validators=[DataRequired('Debes indicarnos un nombre de usuario'), Length(5, 30, 'Debe estar entre 5 y 30 carácteres')]) '''
email = StringField('E-mail', validators=[DataRequired('Necesito un E-mail'), Email('Debe tener un formato válido'), Length(1, 254, 'Es demasiado largo')]) Form signup
password = PasswordField('Contraseña', validators=[DataRequired('No me has indicado una contraseña'), EqualTo('password_confirm', 'No coinciden las contraseñas')]) '''
password_confirm = PasswordField('Repetir contraseña') username = StringField(
accept_tos = BooleanField('Aceptar condiciones', validators=[DataRequired('Necesito que aceptes mis condiciones. Aqui mando yo.')]) 'Username',
validators=[
DataRequired(),
Length(5, 30, '''
You can not have less than 5 characters or more 30.
''')
]
)
email = StringField(
'Email',
validators=[
DataRequired(),
Email(),
Length(1, 254, 'Too long.')
]
)
password = PasswordField(
'Password',
validators=[
DataRequired(),
EqualTo(
'password_confirm',
'Passwords are not the same.'
)
]
)
password_confirm = PasswordField('Repeat password')
accept_tos = BooleanField(
'I accept the terms and conditions.',
validators=[
DataRequired('Please accept the terms and conditions.')
]
)
class EmailResetPasswordForm(FlaskForm): class EmailResetPasswordForm(FlaskForm):
email = StringField('E-mail', validators=[DataRequired('Necesito un E-mail'), Email('Debe tener un formato válido')]) '''
Form send email reset password
'''
email = StringField(
'Email',
validators=[
DataRequired(),
Email()
]
)
class ResetPasswordForm(FlaskForm): class ResetPasswordForm(FlaskForm):
password = PasswordField('Contraseña', validators=[DataRequired('No me has indicado una contraseña'), EqualTo('password_confirm', 'No coinciden las contraseñas')]) '''
password_confirm = PasswordField('Repetir contraseña') Form update password
'''
password = PasswordField(
'Password',
validators=[
DataRequired(),
EqualTo(
'password_confirm',
'Passwords are not the same.'
)
]
)
password_confirm = PasswordField('Repeat password')

View File

@ -3,8 +3,7 @@ from flask import Flask
from flask_sqlalchemy import SQLAlchemy from flask_sqlalchemy import SQLAlchemy
from flask_script import Manager from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand from flask_migrate import Migrate, MigrateCommand
import crypt from uuid import uuid4
import uuid
app = Flask(__name__) app = Flask(__name__)
@ -18,7 +17,9 @@ manager.add_command('db', MigrateCommand)
class User(db.Model): class User(db.Model):
'''
Table user
'''
__tablename__ = 'users' __tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
@ -28,15 +29,13 @@ class User(db.Model):
is_active = db.Column(db.Boolean) is_active = db.Column(db.Boolean)
token = db.Column(db.String(32), nullable=False, unique=False) token = db.Column(db.String(32), nullable=False, unique=False)
def __init__(self, username, email, password): def __init__(self):
self.username = username
self.email = email
self.password = crypt.crypt(password, crypt.mksalt(crypt.METHOD_SHA512))
self.is_active = False self.is_active = False
self.token = str(uuid.uuid4()).replace('-', '') self.token = str(uuid4()).replace('-', '')
def __repr__(self): def __repr__(self):
return '<User %r>' % self.username return '<User %r>' % self.username
if __name__ == '__main__': if __name__ == '__main__':
manager.run() manager.run()

View File

@ -3,7 +3,7 @@
<head> <head>
<meta name="viewport" content="width=device-width" /> <meta name="viewport" content="width=device-width" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Activar cuenta</title> <title>Activate account</title>
<style> <style>
/* ------------------------------------- /* -------------------------------------
GLOBAL RESETS GLOBAL RESETS
@ -286,8 +286,8 @@
<table border="0" cellpadding="0" cellspacing="0"> <table border="0" cellpadding="0" cellspacing="0">
<tr> <tr>
<td> <td>
<p>Hola {{ username }},</p> <p>Hi {{ username }}!,</p>
<p>Gracias por registrarte en nuestro ejemplo. Activa tu cuenta pulsando en el siguiente botón.</p> <p>Thank you for registering you in our example. Activate your account by clicking on the button below.</p>
<table border="0" cellpadding="0" cellspacing="0" class="btn btn-primary"> <table border="0" cellpadding="0" cellspacing="0" class="btn btn-primary">
<tbody> <tbody>
<tr> <tr>
@ -295,7 +295,7 @@
<table border="0" cellpadding="0" cellspacing="0"> <table border="0" cellpadding="0" cellspacing="0">
<tbody> <tbody>
<tr> <tr>
<td> <a href="{{ token }}" target="_blank">Activar</a> </td> <td> <a href="{{ token }}" target="_blank">Activate</a> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@ -303,7 +303,7 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
<p>En caso que no te funcione el botón, pulsa el siguiente enlace.</p> <p>In the event that the button will not work, click the following link.</p>
<p>{{ token }}</p> <p>{{ token }}</p>
</td> </td>
</tr> </tr>

View File

@ -1,7 +1,6 @@
Hola {{ username }}, Hi {{ username }}!,
restablece tu contraseña. thank you for registering you in our example. Activate your account by clicking on the link below.
Pulsa en el siguiente enlace
{{ token }} {{ token }}
Example team.

View File

@ -3,7 +3,7 @@
<head> <head>
<meta name="viewport" content="width=device-width" /> <meta name="viewport" content="width=device-width" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Recuperar contraseña</title> <title>Forgot password</title>
<style> <style>
/* ------------------------------------- /* -------------------------------------
GLOBAL RESETS GLOBAL RESETS
@ -286,8 +286,8 @@
<table border="0" cellpadding="0" cellspacing="0"> <table border="0" cellpadding="0" cellspacing="0">
<tr> <tr>
<td> <td>
<p>Hola {{ username }},</p> <p>Hi {{ username }}!,</p>
<p>Para actualizar tu contraseña pulse en el boton.</p> <p>To update your password, click on the button.</p>
<table border="0" cellpadding="0" cellspacing="0" class="btn btn-primary"> <table border="0" cellpadding="0" cellspacing="0" class="btn btn-primary">
<tbody> <tbody>
<tr> <tr>
@ -295,7 +295,7 @@
<table border="0" cellpadding="0" cellspacing="0"> <table border="0" cellpadding="0" cellspacing="0">
<tbody> <tbody>
<tr> <tr>
<td> <a href="{{ token }}" target="_blank">Restablecer contraseña</a> </td> <td> <a href="{{ token }}" target="_blank">Reset password</a> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@ -303,7 +303,7 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
<p>En caso que no te funcione el botón, pulsa el siguiente enlace.</p> <p>In the event that the button will not work, click the following link.</p>
<p>{{ token }}</p> <p>{{ token }}</p>
</td> </td>
</tr> </tr>

View File

@ -1,6 +1,6 @@
Activa tu cuenta {{ username }} Hi {{ username }}!,
to update your password, click on the link.
Pulsa en el siguiente enlace
{{ token }} {{ token }}
Example team.

View File

@ -0,0 +1,19 @@
{% macro generate_fields(form) -%}
{% for field in form %}
{% if field.type != 'CSRFTokenField' %}
<div class="form-group{%if field.errors %} has-error{% endif %}">
{{ field.label }}
{% if field.type in ('StringField', 'PasswordField') %}
{{ field(class='form-control') }}
{% else %}
{{ field() }}
{% endif %}
{% for error in field.errors %}
<span class="help-block">{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ field() }}
{% endif %}
{% endfor %}
{%- endmacro %}

View File

@ -1,9 +1,10 @@
{% from 'helpers/_forms.html' import generate_fields with context %}
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}{% endblock %} | Login example</title> <title>{% block title %}{% endblock %} | Login system example</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/bootstrap.min.css') }}"> <link rel="stylesheet" href="{{ url_for('static', filename='css/bootstrap.min.css') }}">
</head> </head>
<body> <body>
@ -17,7 +18,7 @@
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
</button> </button>
<a class="navbar-brand" href="#">Example Login</a> <a class="navbar-brand" href="/">Example Login</a>
</div> </div>
<!-- Collect the nav links, forms, and other content for toggling --> <!-- Collect the nav links, forms, and other content for toggling -->

View File

@ -1,28 +1,12 @@
{% extends 'layouts/master.html' %} {% extends 'layouts/master.html' %}
{% block title %}Restablecer contraseña{% endblock %} {% block title %}Restablecer contraseña{% endblock %}
{% block body %} {% block body %}
<h1>Restablece tu contraseña</h1> <h1>Forgot password</h1>
<p>Te enviaremos un email para cambiar la contraseña</p> <p>We will send you an email to change your password.</p>
<p> <p>
<form action="" method="post"> <form action="" method="post">
{% for campo in form %} {{ generate_fields(form) }}
{% if campo.type != 'CSRFTokenField' %} <input type="submit" class="btn btn-success">
<div class="form-group{%if campo.errors %} has-error{% endif %}">
{{ campo.label }}
{% if campo.type in ('StringField', 'PasswordField') %}
{{ campo(class='form-control') }}
{% else %}
{{ campo() }}
{% endif %}
{% for error in campo.errors %}
<span class="help-block">{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ campo() }}
{% endif %}
{% endfor %}
<input type="submit" class="btn btn-success" value="Enviar">
</form> </form>
</p> </p>
{% endblock %} {% endblock %}

View File

@ -4,30 +4,14 @@
<h1>Login</h1> <h1>Login</h1>
<p> <p>
<form action="" method="post"> <form action="" method="post">
{% for campo in form %} {{ generate_fields(form) }}
{% if campo.type != 'CSRFTokenField' %} <input type="submit" class="btn btn-success" value="Enter">
<div class="form-group{%if campo.errors %} has-error{% endif %}">
{{ campo.label }}
{% if campo.type in ('StringField', 'PasswordField') %}
{{ campo(class='form-control') }}
{% else %}
{{ campo() }}
{% endif %}
{% for error in campo.errors %}
<span class="help-block">{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ campo() }}
{% endif %}
{% endfor %}
<input type="submit" class="btn btn-success" value="Entrar">
</form> </form>
</p> </p>
<p> <p>
<a href="{{ url_for('signup') }}" class="btn btn-primary">Regístrate</a> <a href="{{ url_for('signup') }}" class="btn btn-primary">Signup</a>
</p> </p>
<p> <p>
<a href="{{ url_for('forgot_password') }}" class="btn btn-warning">Me he olvidado la contraseña</a> <a href="{{ url_for('forgot_password') }}" class="btn btn-warning">Forgot password</a>
</p> </p>
{% endblock %} {% endblock %}

View File

@ -3,23 +3,7 @@
{% block body %} {% block body %}
<h1>Signup</h1> <h1>Signup</h1>
<form action="" method="post"> <form action="" method="post">
{% for campo in form %} {{ generate_fields(form) }}
{% if campo.type != 'CSRFTokenField' %} <input type="submit" class="btn btn-success" value="Signup">
<div class="form-group{%if campo.errors %} has-error{% endif %}">
{{ campo.label }}
{% if campo.type in ('StringField', 'PasswordField') %}
{{ campo(class='form-control') }}
{% else %}
{{ campo() }}
{% endif %}
{% for error in campo.errors %}
<span class="help-block">{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ campo() }}
{% endif %}
{% endfor %}
<input type="submit" class="btn btn-success" value="Registrarse">
</form> </form>
{% endblock %} {% endblock %}

View File

@ -1,26 +1,10 @@
{% extends 'layouts/master.html' %} {% extends 'layouts/master.html' %}
{% block title %}Cambiar contraseña{% endblock %} {% block title %}Update password{% endblock %}
{% block body %} {% block body %}
<h1>Cambia tu contraseña</h1> <h1>Update password</h1>
<form action="" method="post"> <form action="" method="post">
{{ generate_fields(form) }}
<input type="hidden" name="email" value="{{ email }}"> <input type="hidden" name="email" value="{{ email }}">
{% for campo in form %} <input type="submit" class="btn btn-success" value="Update">
{% if campo.type != 'CSRFTokenField' %}
<div class="form-group{%if campo.errors %} has-error{% endif %}">
{{ campo.label }}
{% if campo.type in ('StringField', 'PasswordField') %}
{{ campo(class='form-control') }}
{% else %}
{{ campo() }}
{% endif %}
{% for error in campo.errors %}
<span class="help-block">{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ campo() }}
{% endif %}
{% endfor %}
<input type="submit" class="btn btn-success" value="Actualizar">
</form> </form>
{% endblock %} {% endblock %}