Commit ea8fec95 authored by buttle's avatar buttle

Included WTF. Added a custom.css

parent 0624eb6e
......@@ -32,7 +32,7 @@ babel = Babel(app)
csrf = CSRFProtect()
csrf.init_app(app)
app.config['APP_VERSION'] = 33
app.config['APP_VERSION'] = 34
app.config['SCHEMA_VERSION'] = 13
app.config['RESERVED_SLUGS'] = ['login', 'static', 'admin', 'admins', 'user', 'users',
......
......@@ -46,27 +46,6 @@ class HostnameQuerySet(QuerySet):
return self.filter(**kwargs)
def isNewUserRequestValid(form):
if not ('username' in form and 'email' in form and 'password1' in form and 'password2' in form):
flash(gettext("All fields are required"), 'warning')
return False
if form['username'] != sanitizeUsername(form['username']):
flash(gettext("Username is not valid"), 'warning')
return False
if form['username'] in app.config['RESERVED_USERNAMES']:
flash(gettext("Username is not available"), 'warning')
return False
user = User.find(username=form['username'])
if user:
flash(gettext("Username is not available"), 'warning')
return False
if not User.isEmailAvailable(form['email']):
return False
if not isValidPassword(form['password1'], form['password2']):
return False
return True
class User(db.Document):
meta = {'collection': 'users', 'queryset_class': HostnameQuerySet}
username = db.StringField(required=True)
......@@ -202,8 +181,8 @@ class User(db.Document):
self.save()
return self.isAdmin()
@classmethod
def defaultAdminSettings(cls):
@staticmethod
def defaultAdminSettings():
return {
"isAdmin": False,
"notifyNewUser": False,
......@@ -401,11 +380,6 @@ class Form(db.Document):
new_form.save()
return new_form
"""
def update(self, data):
db.forms.update_one({'_id': self.form['_id']}, {"$set": data})
"""
def deleteEntries(self):
self.entries=[]
self.save()
......
/* Add your custom css here */
......@@ -61,6 +61,10 @@ hr { margin-top: 5px }
padding: 0.5em 0 0.5em 0;
}
.formError {
color: #d9534f;
}
/* ######### Entries table ######### */
.delete-row-icon {
font-size: 1.15em !important;
......
......@@ -9,6 +9,7 @@
<script src="/static/jquery/jquery-ui.min.js"></script>
<link rel="stylesheet" href="/static/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/css/style.css">
<link rel="stylesheet" href="/static/css/custom.css">
</head>
<body>
......
{% extends "base.html" %}
{% block content %}
<div class="container">
<div class="row col-md-4"></div>
<div class="row col-md-4">
<div style="font-size:1.5em">
{%trans%}Change email address{%endtrans%}
</div>
<hr />
<p></p>
<form method="POST">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<label>{%trans%}New email address{%endtrans%}</label>
<br />
<input type="text" name="email" class="form-control" required ><br />
<p></p>
{{ wtform.csrf_token }}
<p>
{{ wtform.email.label }}<br />
<span class="hint"></span>
{{ wtform.email(class_="form-control") }}
{% for error in wtform.email.errors %}
<span class="formError">{{ error }}</span><br />
{% endfor %}
</p>
<input class="btn-success btn" type="submit" value="{%trans%}Submit{%endtrans%}">
</form>
</div>
<div class="row col-md-4"></div>
</div>
{% endblock %}
......@@ -37,18 +37,20 @@
</div>
<div class="row col-md-1"></div>
<div class="row col-md-3">
<form action="/site/login" method="POST" style="margin-top:1.5em">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
{{ wtform.csrf_token }}
<p>
<label>{%trans%}Username{%endtrans%}</label><br />
<input name="username" class="form-control" value="" />
</p>
{{ wtform.username.label }}<br />
{{ wtform.username(class_="form-control") }}
</p>
<p>
<label>{%trans%}Password{%endtrans%}</label><br />
<input type="password" name="password" class="form-control" value="" />
{{ wtform.password.label }}<br />
{{ wtform.password(class_="form-control") }}
</p>
<input class="btn-success btn" type="submit" value="{%trans%}Login{%endtrans%}" {% if g.current_user %}disabled{%endif%} />
</form>
<br />
{% if g.current_user %}
<a href="/site/reset-password">{%trans%}Forgot your password?{%endtrans%}</a>
......
......@@ -13,23 +13,39 @@
<hr />
<form method="POST">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<label>{%trans%}Username{%endtrans%}</label><br />
<input type="text" name="username" class="form-control" placeholder="{%trans%}Letters and numbers. No accents.{%endtrans%}" required >
<br />
<label>{%trans%}Email{%endtrans%}</label><br />
<input type="email" name="email" class="form-control" required ><br />
<br />
<label>{%trans%}Password{%endtrans%}</label><br />
{%trans%}Use a passphrase, with spaces{%endtrans%}<br />
<input type="password" name="password1" class="form-control" placeholder="{%trans%}eg: No holidays this year{%endtrans%}" required ><br />
<label>Password again</label><br />
<input type="password" name="password2" class="form-control" placeholder="{%trans%}Another eg: My dog has fleas{%endtrans%}" required ><br />
<p></p>
{{ wtform.csrf_token }}
<p>
{{ wtform.username.label }} <span class='required'></span><br />
{{ wtform.username(class_="form-control", placeholder=_('Letters and numbers. No accents.')) }}
{% for error in wtform.username.errors %}
<span class="formError">{{ error }}</span><br />
{% endfor %}
</p>
<p>
{{ wtform.email.label }} <span class='required'></span><br />
<span class="hint"></span>
{{ wtform.email(class_="form-control") }}
{% for error in wtform.email.errors %}
<span class="formError">{{ error }}</span><br />
{% endfor %}
</p>
<p>
{{ wtform.password.label }} <span class='required'></span><br />
<span class="hint">{%trans%}Use a passphrase, with spaces{%endtrans%}</span>
{{ wtform.password(class_="form-control", placeholder=_('eg: No holidays this year')) }}
{% for error in wtform.password.errors %}
<span class="formError">{{ error }}</span><br />
{% endfor %}
</p>
<p>
{{ wtform.password2.label }} <span class='required'></span><br />
{{ wtform.password2(class_="form-control", placeholder=_('Another eg: My dog has fleas')) }}
{% for error in wtform.password2.errors %}
<span class="formError">{{ error }}</span><br />
{% endfor %}
</p>
<p>&nbsp;</p>
<input class="btn-success btn" type="submit" value="{%trans%}Submit{%endtrans%}">
<input class="btn-primary btn" type="button" value="{%trans%}Cancel{%endtrans%}" onclick="window.location.href='/';">
</form>
......
......@@ -164,7 +164,7 @@ def markdown2HTML(MDtext):
""" ######## Password ######## """
policy = PasswordPolicy.from_names(
pwd_policy = PasswordPolicy.from_names(
length=8, # min length: 8
uppercase=0, # need min. 2 uppercase letters
numbers=0, # need min. 2 digits
......@@ -182,10 +182,10 @@ def verifyPassword(password, hash):
def isValidPassword(password1, password2):
if password1 != password2:
flash(gettext("Passwords do not match"), 'warning')
#flash(gettext("Passwords do not match"), 'warning')
return False
if policy.test(password1):
flash(gettext("Your password is weak"), 'warning')
if pwd_policy.test(password1):
#flash(gettext("Your password is weak"), 'warning')
return False
return True
......
......@@ -27,6 +27,7 @@ from flask_babel import gettext, refresh
from GNGforms.persistence import *
from GNGforms.session import *
from GNGforms.utils import *
import GNGforms.wtf as wtf
import GNGforms.email as smtp
from form_templates import formTemplates
......@@ -41,9 +42,9 @@ def before_request():
g.current_user=None
g.isRootUser=False
g.isAdmin=False
g.site=Site.find(hostname=urlparse(request.host_url).hostname)
if '/static' in request.path:
return
g.site=Site.find(hostname=urlparse(request.host_url).hostname)
if 'user_id' in session and session["user_id"] != None:
g.current_user=User.find(id=session["user_id"], hostname=g.site.hostname)
if not g.current_user:
......@@ -63,6 +64,8 @@ def get_locale():
@app.errorhandler(404)
def page_not_found(error):
if not g.site:
g.site=Site.find(hostname=urlparse(request.host_url).hostname)
return render_template('page-not-found.html'), 400
@app.errorhandler(500)
......@@ -75,8 +78,8 @@ def handle_csrf_error(e):
return redirect(make_url_for('index'))
@app.route('/', methods=['GET'])
def index():
return render_template('index.html',site=g.site)
def index():
return render_template('index.html', site=g.site, wtform=wtf.Login())
@app.route('/<string:slug>', methods=['GET', 'POST'])
@sanitized_slug_required
......@@ -781,15 +784,13 @@ def user_settings(username):
@app.route('/user/change-email', methods=['GET', 'POST'])
@login_required
def change_email():
if request.method == 'POST':
if 'email' in request.form and isValidEmail(request.form['email']):
g.current_user.setToken(email=request.form['email'])
smtp.sendConfirmEmail(g.current_user, request.form['email'])
flash(gettext("We've sent an email to %s") % request.form['email'], 'info')
return redirect(make_url_for('user_settings', username=g.current_user.username))
return render_template('change-email.html')
wtform=wtf.ChangeEmail()
if wtform.validate_on_submit():
g.current_user.setToken(email=wtform.email.data)
smtp.sendConfirmEmail(g.current_user, wtform.email.data)
flash(gettext("We've sent an email to %s") % wtform.email.data, 'info')
return redirect(make_url_for('user_settings', username=g.current_user.username))
return render_template('change-email.html', wtform=wtform)
@app.route('/user/send-validation', methods=['GET'])
......@@ -835,16 +836,13 @@ def new_user(token=None):
flash(gettext("Your petition has expired"), 'warning')
invite.delete()
return redirect(make_url_for('index'))
if request.method == 'POST':
if not isNewUserRequestValid(request.form):
return render_template('new-user.html')
wtform=wtf.NewUser()
if wtform.validate_on_submit():
validatedEmail=False
adminSettings=User.defaultAdminSettings()
adminSettings=User.defaultAdminSettings()
if invite:
if invite.email == request.form['email']:
if invite.email == wtform.email.data:
validatedEmail=True
if invite.admin == True:
adminSettings['isAdmin']=True
......@@ -852,15 +850,14 @@ def new_user(token=None):
# when validatedEmail=False, a validation email fails to be sent because SMTP is not congifured.
if not g.site.admins:
validatedEmail=True
if request.form['email'] in app.config['ROOT_USERS']:
if wtform.email.data in app.config['ROOT_USERS']:
adminSettings["isAdmin"]=True
validatedEmail=True
newUserData = {
"username": request.form['username'],
"email": request.form['email'],
"password": encryptPassword(request.form['password1']),
"username": wtform.username.data,
"email": wtform.email.data,
"password": encryptPassword(wtform.password.data),
"language": app.config['DEFAULT_LANGUAGE'],
"hostname": g.site.hostname,
"blocked": False,
......@@ -890,9 +887,8 @@ def new_user(token=None):
return render_template('new-user.html', site=g.site, created=True)
if "user_id" in session:
#session["user_id"]=None
session.pop("user_id")
return render_template('new-user.html')
return render_template('new-user.html', wtform=wtform)
......@@ -901,16 +897,17 @@ def new_user(token=None):
@app.route('/site/login', methods=['POST'])
@anon_required
def login():
if 'username' in request.form and 'password' in request.form:
user=User.find(hostname=g.site.hostname, username=request.form['username'], blocked=False)
if user and verifyPassword(request.form['password'], user.password):
wtform=wtf.Login()
if wtform.validate_on_submit():
user=User.find(hostname=g.site.hostname, username=wtform.username.data, blocked=False)
if user and verifyPassword(wtform.password.data, user.password):
session["user_id"]=str(user.id)
if not user.validatedEmail:
return redirect(make_url_for('user_settings', username=user.username))
else:
return redirect(make_url_for('my_forms'))
if "user_id" in session:
session.pop("user_id")
if "user_id" in session:
session.pop("user_id")
flash(gettext("Bad credentials"), 'warning')
return redirect(make_url_for('index'))
......@@ -995,11 +992,10 @@ def validate_email(token):
flash(gettext("Your petition has expired"), 'warning')
user.deleteToken()
return redirect(make_url_for('index'))
# On a Change email request, the new email address is saved in the token.
if 'email' in user.token:
user.email = user.token['email']
user.deleteToken()
user.validatedEmail=True
user.save()
......
from flask_wtf import FlaskForm
from wtforms import StringField, TextAreaField, PasswordField, BooleanField, RadioField
from wtforms.validators import ValidationError, DataRequired, Email, EqualTo
from flask import g
from flask_babel import lazy_gettext as _
from GNGforms import app
from GNGforms.persistence import User, Installation
from GNGforms.utils import sanitizeUsername, pwd_policy
class NewUser(FlaskForm):
username = StringField(_("Username"), validators=[DataRequired()])
email = StringField(_("Email"), validators=[DataRequired(), Email()])
password = PasswordField(_("Password"), validators=[DataRequired()])
password2 = PasswordField(_("Password again"), validators=[DataRequired(), EqualTo('password')])
def validate_username(self, username):
if username.data != sanitizeUsername(username.data):
raise ValidationError(_("Username is not valid"))
return False
if username.data in app.config['RESERVED_USERNAMES']:
raise ValidationError(_("Please use a different username"))
return False
if User.find(username=username.data):
raise ValidationError(_("Please use a different username"))
def validate_email(self, email):
if User.find(email=email.data):
raise ValidationError(_("Please use a different email address"))
elif email.data in app.config['ROOT_USERS'] and Installation.isUser(email.data):
# a root_user email can only be used once across all sites.
raise ValidationError(_("Please use a different email address"))
def validate_password(self, password):
if pwd_policy.test(password.data):
raise ValidationError(_("Your password is weak"), 'warning')
class Login(FlaskForm):
username = StringField(_("Username"), validators=[DataRequired()])
password = PasswordField(_("Password"), validators=[DataRequired()])
def validate_username(self, username):
if username.data != sanitizeUsername(username.data):
return False
class ChangeEmail(FlaskForm):
email = StringField(_("New email address"), validators=[DataRequired(), Email()])
def validate_email(self, email):
if User.find(email=email.data):
raise ValidationError(_("Please use a different email address"))
elif email.data in app.config['ROOT_USERS'] and Installation.isUser(email.data):
# a root_user email can only be used once across all sites.
raise ValidationError(_("Please use a different email address"))
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment