I'm 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
3 and the back-end but only return
True if the registration is valid otherwise,
validate_registration (currently a
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.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
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
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