Commit 728d4367 authored by buttle's avatar buttle

More WTForms

parent 3444b9b9
......@@ -32,7 +32,7 @@ babel = Babel(app)
csrf = CSRFProtect()
csrf.init_app(app)
app.config['APP_VERSION'] = 35
app.config['APP_VERSION'] = 36
app.config['SCHEMA_VERSION'] = 13
app.config['RESERVED_SLUGS'] = ['login', 'static', 'admin', 'admins', 'user', 'users',
......
......@@ -117,20 +117,7 @@ class User(db.Document):
emails.append(rootUser['email'])
#print("new user notify: %s" % emails)
return emails
@classmethod
def isEmailAvailable(cls, email):
if not isValidEmail(email):
flash(gettext("Email address is not valid"), 'warning')
return False
if User.find(email=email):
flash(gettext("Email address is not available"), 'warning')
return False
if email in app.config['ROOT_USERS'] and Installation.isUser(email):
flash(gettext("Email address is not available"), 'warning')
return False
return True
@property
def enabled(self):
if not self.validatedEmail:
......
......@@ -12,20 +12,22 @@
</div>
<hr />
<p></p>
<form method="POST">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<label>{%trans%}New user's email{%endtrans%}</label>
<br />
<input type="text" name="email" class="form-control" required >
<br />
<label>{%trans%}Include message{%endtrans%}</label>
<br />
<textarea name="message" class="form-control" ></textarea>
<br />
<label>{%trans%}Make the new user an Admin{%endtrans%}</label>
<input style="vertical-align: -2px;" type="checkbox" name="admin" value="True" />
{{ wtform.csrf_token }}
<p>
{{ wtform.email.label }} <span class='required'></span><br />
{{ wtform.email(class_="form-control") }}
{% for error in wtform.email.errors %}
<span class="formError">{{ error }}</span><br />
{% endfor %}
</p>
<p>
{{ wtform.message.label }}<br />
{{ wtform.message(class_="form-control") }}
</p>
<p>
{{ wtform.admin.label }} {{ wtform.admin(style="vertical-align:-3px;") }}
</p>
{% if g.isRootUser %}
<p>&nbsp;</p>
<div style="font-size:1.2em">{%trans%}Root user options{%endtrans%}</div>
......@@ -33,14 +35,15 @@
<label>{%trans%}Invite to one of these sites{%endtrans%}</label>
{% for site in sites %}
<div class="radio radio-info">
<input style="margin-left:0;" type="radio" name="hostname" value="{{ site.hostname }}" {% if site.hostname == hostname %}checked{% endif %} >
<input style="margin-left:0;" type="radio" name="hostname" value="{{ site.hostname }}" {% if site.hostname == g.site.hostname %}checked{% endif %} >
<label style="margin-left:1em;">{{ site.hostname }}</label>
</div>
{% endfor %}
<br />
{% else %}
<input type="hidden" name="hostname" value="{{ g.site.hostname }}" />
{% endif %}
<p>&nbsp;</p>
<input class="btn-success btn" type="submit" value="{%trans%}Send email{%endtrans%}">
<input class="btn-primary btn" type="button" value="{%trans%}Cancel{%endtrans%}" onClick="location.href='/user/{{g.current_user.username}}'">
</form>
......
......@@ -11,11 +11,14 @@
<hr />
<form method="POST">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<label>{%trans%}Your email{%endtrans%}</label>
<br />
<input type="text" name="email" class="form-control" required ><br />
<p></p>
{{ wtform.csrf_token }}
<p>
{{ wtform.email.label }}<br />
{{ 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%}Recover{%endtrans%}">
<input class="btn-primary btn" type="button" value="{%trans%}Cancel{%endtrans%}" onClick="location.href='/'">
</form>
......
{% extends "base.html" %}
{% block content %}
<div class="container">
<div class="row col-md-4"></div>
<div class="row col-md-4">
......@@ -14,17 +12,22 @@
<hr />
<form method="POST">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<label>{%trans%}Password{%endtrans%}</label><br />
Use a passphrase, with spaces.<br />
<br />
<input type="password" name="password1" class="form-control" placeholder="{%trans%}eg: No holidays this year{%endtrans%}" required ><br />
<label>{%trans%}Password again{%endtrans%}</label><br />
<input type="password" name="password2" class="form-control" required ><br />
<p></p>
{{ wtform.csrf_token }}
<p>
{{ wtform.password.label }}<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 }}<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>
<input class="btn-success btn" type="submit" value="{%trans%}Reset password{%endtrans%}">
</form>
</div>
......
......@@ -77,13 +77,16 @@
{% endfor %}
<tr>
<form action="/forms/add-editor/{{form.id}}" method="POST">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<td>
<input name="email" type="text" placeholder="New editor's email" class="form-control" required >
</td>
<td class="text-right">
<input class="btn-primary btn btn-md" type="submit" value="{%trans%}Add{%endtrans%}" >
</td>
{{ wtform.csrf_token }}
<td>
{{ wtform.email(class_="form-control", placeholder=_("New editor's email")) }}
{% for error in wtform.email.errors %}
<span class="formError">{{ error }}</span><br />
{% endfor %}
</td>
<td class="text-right">
<input class="btn-primary btn btn-md" type="submit" value="{%trans%}Add{%endtrans%}" >
</td>
</form>
</tr>
</table>
......
{% extends "base.html" %}
{% block content %}
<style>
label { margin-top:0.25em }
</style>
<div class="container">
<div class="row col-md-4"></div>
<div class="row col-md-2"></div>
<div class="row col-md-4">
<div style="font-size:1.5em">{%trans%}Email server configuration{%endtrans%}</div>
<hr />
<form method="POST">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<label>{%trans%}Email server{%endtrans%}</label>
<span class='required'></span>
<br />
<input type="text" name="host" class="form-control" value="{{host}}" required />
<label>{%trans%}Port{%endtrans%}</label>
<span class='required'></span>
<br />
<input type="number" name="port" class="form-control" value="{{port}}" required />
<label>{%trans%}Encryption{%endtrans%}</label>
<span class='required'></span>
<br />
<select type="number" name="encryption" class="form-control" value="{{encryption}}" >
<option class="form-control" name="hello" {% if not encryption == "SSL" %}selected=True{% endif %} >{%trans%}None{%endtrans%}</option>
<option class="form-control" name="SSL" {% if encryption == "SSL" %}selected=True{% endif %} >SSL</option>
<option class="form-control" name="STARTTLS" {% if encryption == "STARTTLS" %}selected=True{% endif %} >STARTTLS (may work)</option>
</select>
<label>{%trans%}User{%endtrans%}</label>
<br />
<input type="text" name="user" class="form-control" value="{{user}}" />
<label>{%trans%}Password{%endtrans%}</label>
<br />
<input type="password" name="password" class="form-control" value="{{password}}" />
<label>{%trans%}Sender address{%endtrans%}</label>
<span class='required'></span>
<br />
<input type="email" name="noreplyAddress" class="form-control" value="{{noreplyAddress}}" required />
<form method="POST" action="/site/email/config">
{{ wtf_smtp.csrf_token }}
<p>
{{ wtf_smtp.host.label }} <span class='required'></span><br />
{{ wtf_smtp.host(class_="form-control") }}
{% for error in wtf_smtp.host.errors %}
<span class="formError">{{ error }}</span><br />
{% endfor %}
</p>
{{ wtf_smtp.port.label }} <span class='required'></span><br />
{{ wtf_smtp.port(class_="form-control") }}
{% for error in wtf_smtp.port.errors %}
<span class="formError">{{ error }}</span><br />
{% endfor %}
</p>
</p>
{{ wtf_smtp.encryption.label }} <span class='required'></span><br />
{{ wtf_smtp.encryption(class_="form-control") }}
</p>
</p>
{{ wtf_smtp.user.label }}<br />
{{ wtf_smtp.user(class_="form-control") }}
</p>
</p>
{{ wtf_smtp.password.label }}<br />
<input class="form-control" id="password" name="password" type="password" value="{{wtf_smtp.password.data}}">
</p>
</p>
{{ wtf_smtp.noreplyAddress.label }} <span class='required'></span><br />
{{ wtf_smtp.noreplyAddress(class_="form-control") }}
{% for error in wtf_smtp.noreplyAddress.errors %}
<span class="formError">{{ error }}</span><br />
{% endfor %}
</p>
<p></p>
<input class="btn-success btn" type="submit" value="{%trans%}Save changes{%endtrans%}">
<input class="btn-primary btn" type="button" value="{%trans%}Cancel{%endtrans%}" onClick="location.href='/user/{{g.current_user.username}}#site_settings'">
</form>
<p>&nbsp;</p>
<div style="font-size:1.25em">{%trans%}Test server configuration{%endtrans%}</div>
<table class="table">
<tr>
<td>
<input id="test-email" name="email" type="email" placeholder="[email protected]" class="form-control" required >
</td>
<td class="text-right">
<input id="test-email-button" class="btn-primary btn btn-md" type="button" value="{%trans%}Send{%endtrans%}" >
</td>
</tr>
</table>
</div>
<div class="row col-md-4"></div>
<div class="row col-md-1"></div>
<div class="row col-md-4">
<div style="font-size:1.5em">{%trans%}Test configuration{%endtrans%}</div>
<hr />
<form method="POST" action="/site/email/test-config">
<p>
{{ wtf_email.csrf_token }}
{{ wtf_email.email.label }}<br />
{{ wtf_email.email(class_="form-control", placeholder="[email protected]") }}
{% for error in wtf_email.email.errors %}
<span class="formError">{{ error }}</span><br />
{% endfor %}
</p>
<input class="btn-primary btn btn-md" type="submit" value="{%trans%}Send{%endtrans%}" >
</form>
</div>
<script>
document.getElementById('test-email-button').addEventListener('click', function(evt){
var email = $("#test-email").val();
if (email){
location.href="/site/email/test-config/"+email
}
});
</script>
<div class="row col-md-1"></div>
</div>
{% endblock %}
......@@ -24,7 +24,6 @@ from unidecode import unidecode
import time, re, string, random, datetime, csv
from passlib.hash import pbkdf2_sha256
from password_strength import PasswordPolicy
from validate_email import validate_email
import markdown, html.parser
from functools import wraps
......@@ -187,16 +186,6 @@ def verifyPassword(password, hash):
return pbkdf2_sha256.verify(password, hash)
def isValidPassword(password1, password2):
if password1 != password2:
#flash(gettext("Passwords do not match"), 'warning')
return False
if pwd_policy.test(password1):
#flash(gettext("Your password is weak"), 'warning')
return False
return True
""" ######## fieldIndex helpers ######## """
def getFieldByNameInIndex(index, name):
......@@ -219,7 +208,6 @@ def createToken(persistentClass, **kwargs):
tokenString = getRandomString(length=48)
while persistentClass.find(token=tokenString):
tokenString = getRandomString(length=48)
result={'token': tokenString, 'created': datetime.datetime.now()}
return {**result, **kwargs}
......@@ -248,11 +236,6 @@ def isFutureDate(date):
""" ######## Others ######## """
def isValidEmail(email):
if not validate_email(email):
flash(gettext("Email address is not valid"), 'warning')
return False
return True
def writeCSV(form):
fieldnames=[]
......
This diff is collapsed.
from flask_wtf import FlaskForm
from wtforms import StringField, TextAreaField, PasswordField, BooleanField, RadioField
from wtforms import StringField, TextAreaField, IntegerField, SelectField, PasswordField, BooleanField, RadioField
from wtforms.validators import ValidationError, DataRequired, Email, EqualTo
from flask import g
from flask_babel import lazy_gettext as _
......@@ -34,7 +34,7 @@ class NewUser(FlaskForm):
def validate_password(self, password):
if pwd_policy.test(password.data):
raise ValidationError(_("Your password is weak"), 'warning')
raise ValidationError(_("Your password is weak"))
class Login(FlaskForm):
......@@ -44,7 +44,11 @@ class Login(FlaskForm):
def validate_username(self, username):
if username.data != sanitizeUsername(username.data):
return False
class GetEmail(FlaskForm):
email = StringField(_("Email address"), validators=[DataRequired(), Email()])
class ChangeEmail(FlaskForm):
email = StringField(_("New email address"), validators=[DataRequired(), Email()])
......@@ -54,3 +58,37 @@ class ChangeEmail(FlaskForm):
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"))
class ResetPassword(FlaskForm):
password = PasswordField(_("Password"), validators=[DataRequired()])
password2 = PasswordField(_("Password again"), validators=[DataRequired(), EqualTo('password')])
def validate_password(self, password):
if pwd_policy.test(password.data):
raise ValidationError(_("Your password is weak"))
class smtpConfig(FlaskForm):
host = StringField(_("Email server"), validators=[DataRequired()])
port = IntegerField(_("Port"))
encryption = SelectField(_("Encryption"), choices=[ ('None', 'None'),
('SSL', 'SSL'),
('STARTTLS', 'STARTTLS (maybe)')])
user = StringField(_("User"))
password = StringField(_("Password"))
noreplyAddress = StringField(_("Sender address"), validators=[DataRequired(), Email()])
class NewInvite(FlaskForm):
email = StringField(_("New user's email"), validators=[DataRequired(), Email()])
message = TextAreaField(_("Include message"))
admin = BooleanField(_("Make the new user an Admin"))
hostname = StringField(_("hostname"), validators=[DataRequired()])
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