I am working on a personal project (Flask CRUD app) and I am currently building the user service. I am trying to use as less as libraries as possible (that’s why I do not use WTF-forms for example, just for learning purposes). I am really not sure about a couple of things.
I am aware that form validation should be handled in both front and back-end (or at the very least on the back-end). In order to validate a new user, I am (currently) checking 3 things:
1)
email does not already exist on the db (can only be verified on the back-end)
2)
password is strong enough (can be done in both front and back end)
3)
password and password_confirm matches (can be done in both front and back end)
My goal is to display a small error message on the registration page if either at least one those errors appears. Currently, I am checking option 1
, 2
and 3
and the back-end but only return True
if the registration is valid otherwise, False
.
Since case 1
and 2
can directly be handle also on the front-end, can I display the error message using JavaScript and not from the back-end? I am still confused on what would be the best return for validate_registration
(currently a Boolean
).
Also, I am not quite sure my code is over-engineered, I made a RegistrationForm
class just to validate a registration form. I did that because I am able to pick validations methods from my validators.py
which may be used in other Classes as well.
So this is what I did so for for the registration form:
user/blueprints/routes.py
@user.route('/new-user',methods = ('POST'))
def register_user():
form_email = request.form.get('email')
form_password = request.form.get('psw')
form_password_repeat = request.form.get('psw-repeat')
registration_form = RegistrationForm(form_email, form_password, form_password_repeat).validate_registration()
if registration_form:
new_user = UserService().register_user(form_email, form_password)
user_repository = UserRepository(conn, 'users')
user_repository.add_user(new_user)
user_repository.save()
return "ok" #will probably change return statements later on
return "not ok" #will probably change return statements later on
user/blueprints/forms.py
from prepsmarter.blueprints.user.validators import email_already_in_use, password_matching
class RegistrationForm():
def __init__(self, email, pwd_1, pwd_2):
self.email = email
self.pwd_1 = pwd_1
self.pwd_2 = pwd_2
def validate_registration(self):
is_valid = email_already_in_use(self.email) and is_strong_password(self.pwd_1) and password_matching(self.pwd_1, self.pwd_2)
return is_valid
class LoginForm():
# to do
user/blueprints/validators.py
import re
from email_validator import validate_email, EmailNotValidError
from prepsmarter.extensions import conn
def is_strong_password(password):
length_error = len(password) < 8
digit_error = re.search(r"d", password) is None
uppercase_error = re.search(r"(A-Z)", password) is None
return length_error and digit_error and uppercase_error
def is_email_formated_correctly(email):
is_correct = True
try:
validate_email(email)
except EmailNotValidError:
is_correct = False
return is_correct
def password_matching(pwd_1, pwd_2):
return pwd_1 == pwd_2
def email_already_in_use(email):
sql = "SELECT CASE WHEN EXISTS ( SELECT * FROM users WHERE email = (%s)) THEN 1 ELSE 0 END;"
cursor = conn.cursor()
cursor.execute(sql, (email))
res = cursor.fetchall()
return res == 1