From 464687d51afc6e16c3497ad70bb375f9a8be8419 Mon Sep 17 00:00:00 2001 From: Noga Osin Date: Tue, 28 Sep 2021 16:42:16 +0300 Subject: [PATCH 1/5] added the login form, and tons of notes --- lms/lmsweb/forms/login.py | 17 +++++++++ lms/lmsweb/views.py | 41 +++++++++++--------- lms/templates/login.html | 79 +++++++++++++++++++-------------------- lms/templates/signup.html | 47 ++++++++++++----------- 4 files changed, 103 insertions(+), 81 deletions(-) create mode 100644 lms/lmsweb/forms/login.py diff --git a/lms/lmsweb/forms/login.py b/lms/lmsweb/forms/login.py new file mode 100644 index 00000000..af069fab --- /dev/null +++ b/lms/lmsweb/forms/login.py @@ -0,0 +1,17 @@ +from flask_babel import gettext as _ # type: ignore +from flask_wtf import FlaskForm +from lms.lmsweb.tools.validators import UniqueUsernameRequired +from wtforms import PasswordField, StringField +from wtforms.fields.simple import PasswordField +from wtforms.validators import InputRequired, Length + + +class LoginForm(FlaskForm): + username = StringField( + 'Username', validators=[ + InputRequired(), UniqueUsernameRequired, Length(min=4, max=20), + ], + ) + password = PasswordField( + 'Password', validators=[InputRequired(), Length(min=8)], id='password', + ) diff --git a/lms/lmsweb/views.py b/lms/lmsweb/views.py index 49ffdc3f..349e6fad 100644 --- a/lms/lmsweb/views.py +++ b/lms/lmsweb/views.py @@ -28,6 +28,7 @@ ) from lms.lmsweb.forms.change_password import ChangePasswordForm from lms.lmsweb.forms.register import RegisterForm +from lms.lmsweb.forms.login import LoginForm from lms.lmsweb.forms.reset_password import RecoverPassForm, ResetPassForm from lms.lmsweb.manifest import MANIFEST from lms.lmsweb.redirections import ( @@ -92,7 +93,7 @@ def ratelimit_handler(e): ) -@webapp.route('/login', methods=['GET', 'POST']) +@webapp.route('/login', methods=['GET', 'POST']) # TODO: change this to use WTForms, like '/signup' @limiter.limit( f'{LIMITS_PER_MINUTE}/minute;{LIMITS_PER_HOUR}/hour', deduct_when=lambda response: response.status_code != 200, @@ -101,24 +102,28 @@ def login(login_message: Optional[str] = None): if current_user.is_authenticated: return get_next_url(request.args.get('next')) - username = request.form.get('username') - password = request.form.get('password') - next_page = request.form.get('next') - login_message = request.args.get('login_message') + form = LoginForm() # above the is.auth...? + if not form.validate_on_submit(): + return render_template('login.html', form=form) - if request.method == 'POST': - try: - user = auth(username, password) - except (ForbiddenPermission, UnauthorizedError) as e: - error_message, _ = e.args - error_details = {'next': next_page, 'login_message': error_message} - return redirect(url_for('login', **error_details)) - else: - login_user(user) - session['_invalid_password_tries'] = 0 - return get_next_url(next_page) - - return render_template('login.html', login_message=login_message) + username = form.username.data + password = form.password.data + next_page = request.form.get('next') # TODO: what is this? what's the best way to do it on WTForms? + login_message = request.args.get('login_message') # maybe move those to inside the `if` statement? + + # if request.method == 'POST': + try: + user = auth(username, password) + except (ForbiddenPermission, UnauthorizedError) as e: + error_message, _ = e.args + error_details = {'next': next_page, 'login_message': error_message} + return redirect(url_for('login', **error_details)) + else: + login_user(user) + session['_invalid_password_tries'] = 0 + return get_next_url(next_page) + + # return render_template('login.html', login_message=login_message) # form=form? @webapp.route('/signup', methods=['GET', 'POST']) diff --git a/lms/templates/login.html b/lms/templates/login.html index f76945de..9dfc2a7c 100644 --- a/lms/templates/login.html +++ b/lms/templates/login.html @@ -1,45 +1,42 @@ {% extends 'base.html' %} +{% from "_formhelpers.html" import render_field %} {% block page_content %} -
-
-
- -

{{ _('התחברות') }}

-

- {{ _('ברוכים הבאים למערכת התרגילים!') }}
- {{ _('הזינו את שם המשתמש והסיסמה שלכם:') }} -

- {% if login_message %} -
-

- {{ login_message }} -

-
- {% endif %} -
-
- -
- -
-
-
- -
- -
-
- - - - {{ _('שכחת את הסיסמה?') }} -
- {% if config.REGISTRATION_OPEN %} -
- {{ _('הירשם') }} - {% endif %} -
-
-
+
+
+
+ +

{{ _('התחברות') }}

+

+ {{ _('ברוכים הבאים למערכת התרגילים!') }}
+ {{ _('הזינו את שם המשתמש והסיסמה שלכם:') }} +

+ {% if login_message %} +
+

+ {{ login_message }} +

+
+ {% endif %} + +
+ {{ render_field(form.username, cls="form-control form-control-lg", placeholder=_('שם משתמש')) }} + {{ render_field(form.password, cls="form-control form-control-lg", placeholder=_('סיסמה')) }} + + + + {{ _('שכחת את + הסיסמה?') }} +
+ + {% if config.REGISTRATION_OPEN %} +
+ {{ _('הירשם') }} + {% endif %} +
+
+
{% endblock %} diff --git a/lms/templates/signup.html b/lms/templates/signup.html index 226478fa..086c9726 100644 --- a/lms/templates/signup.html +++ b/lms/templates/signup.html @@ -2,28 +2,31 @@ {% from "_formhelpers.html" import render_field %} {% block page_content %} -
-
-
- -

{{ _('הרשמה') }}

-

- {{ _('ברוכים הבאים למערכת התרגילים!') }}
- {{ _('הזינו אימייל וסיסמה לצורך רישום למערכת:') }} -

-
- {{ render_field(form.email, cls="form-control form-control-lg", placeholder=_('כתובת אימייל')) }} - {{ render_field(form.username, cls="form-control form-control-lg", placeholder=_('שם משתמש')) }} - {{ render_field(form.fullname, cls="form-control form-control-lg", placeholder=_('שם מלא')) }} - {{ render_field(form.password, cls="form-control form-control-lg", placeholder=_('סיסמה')) }} - {{ render_field(form.confirm, cls="form-control form-control-lg", placeholder=_('אימות סיסמה')) }} - - - -
-
- {{ _('חזרה לדף ההתחברות') }} -
+
+
+
+ +

{{ _('הרשמה') }}

+

+ {{ _('ברוכים הבאים למערכת התרגילים!') }}
+ {{ _('הזינו אימייל וסיסמה לצורך רישום למערכת:') }} +

+
+ {{ render_field(form.email, cls="form-control form-control-lg", placeholder=_('כתובת אימייל')) }} + {{ render_field(form.username, cls="form-control form-control-lg", placeholder=_('שם משתמש')) }} + {{ render_field(form.fullname, cls="form-control form-control-lg", placeholder=_('שם מלא')) }} + {{ render_field(form.password, cls="form-control form-control-lg", placeholder=_('סיסמה')) }} + {{ render_field(form.confirm, cls="form-control form-control-lg", placeholder=_('אימות סיסמה')) }} + + + +
+
+ {{ _('חזרה לדף ההתחברות') }}
+
{% endblock %} From 5abe6cda651324ba58976a383abed4d181e9601f Mon Sep 17 00:00:00 2001 From: Noga Osin Date: Fri, 1 Oct 2021 23:38:05 +0300 Subject: [PATCH 2/5] minor changes --- lms/lmsweb/forms/login.py | 3 +-- lms/templates/login.html | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lms/lmsweb/forms/login.py b/lms/lmsweb/forms/login.py index af069fab..2937c086 100644 --- a/lms/lmsweb/forms/login.py +++ b/lms/lmsweb/forms/login.py @@ -1,6 +1,5 @@ from flask_babel import gettext as _ # type: ignore from flask_wtf import FlaskForm -from lms.lmsweb.tools.validators import UniqueUsernameRequired from wtforms import PasswordField, StringField from wtforms.fields.simple import PasswordField from wtforms.validators import InputRequired, Length @@ -9,7 +8,7 @@ class LoginForm(FlaskForm): username = StringField( 'Username', validators=[ - InputRequired(), UniqueUsernameRequired, Length(min=4, max=20), + InputRequired(), Length(min=4, max=20), ], ) password = PasswordField( diff --git a/lms/templates/login.html b/lms/templates/login.html index 9dfc2a7c..00e5a525 100644 --- a/lms/templates/login.html +++ b/lms/templates/login.html @@ -20,7 +20,7 @@

{{ _('התחברות') }}

{% endif %} -
+ {{ render_field(form.username, cls="form-control form-control-lg", placeholder=_('שם משתמש')) }} {{ render_field(form.password, cls="form-control form-control-lg", placeholder=_('סיסמה')) }} Date: Fri, 1 Oct 2021 23:58:56 +0300 Subject: [PATCH 3/5] final touch ups --- lms/lmsweb/views.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/lms/lmsweb/views.py b/lms/lmsweb/views.py index 349e6fad..842af47e 100644 --- a/lms/lmsweb/views.py +++ b/lms/lmsweb/views.py @@ -93,25 +93,26 @@ def ratelimit_handler(e): ) -@webapp.route('/login', methods=['GET', 'POST']) # TODO: change this to use WTForms, like '/signup' +@webapp.route('/login', methods=['GET', 'POST']) @limiter.limit( f'{LIMITS_PER_MINUTE}/minute;{LIMITS_PER_HOUR}/hour', deduct_when=lambda response: response.status_code != 200, ) def login(login_message: Optional[str] = None): + next_page = request.form.get('next') if current_user.is_authenticated: - return get_next_url(request.args.get('next')) + return get_next_url(next_page) - form = LoginForm() # above the is.auth...? + form = LoginForm() + login_message = request.args.get('login_message') if not form.validate_on_submit(): - return render_template('login.html', form=form) + return render_template( + 'login.html', form=form, login_message=login_message + ) username = form.username.data password = form.password.data - next_page = request.form.get('next') # TODO: what is this? what's the best way to do it on WTForms? - login_message = request.args.get('login_message') # maybe move those to inside the `if` statement? - # if request.method == 'POST': try: user = auth(username, password) except (ForbiddenPermission, UnauthorizedError) as e: @@ -123,8 +124,6 @@ def login(login_message: Optional[str] = None): session['_invalid_password_tries'] = 0 return get_next_url(next_page) - # return render_template('login.html', login_message=login_message) # form=form? - @webapp.route('/signup', methods=['GET', 'POST']) @limiter.limit(f'{LIMITS_PER_MINUTE}/minute;{LIMITS_PER_HOUR}/hour') From b2e4a42986bb16fbb6c6228e7fdf4c91eed4b4b3 Mon Sep 17 00:00:00 2001 From: Noga Osin Date: Sat, 2 Oct 2021 00:28:42 +0300 Subject: [PATCH 4/5] flake8 fixes --- lms/lmsweb/forms/login.py | 1 - lms/lmsweb/forms/reset_password.py | 2 +- lms/lmsweb/views.py | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lms/lmsweb/forms/login.py b/lms/lmsweb/forms/login.py index 2937c086..d5160e67 100644 --- a/lms/lmsweb/forms/login.py +++ b/lms/lmsweb/forms/login.py @@ -1,4 +1,3 @@ -from flask_babel import gettext as _ # type: ignore from flask_wtf import FlaskForm from wtforms import PasswordField, StringField from wtforms.fields.simple import PasswordField diff --git a/lms/lmsweb/forms/reset_password.py b/lms/lmsweb/forms/reset_password.py index 1785eaa8..96fafac2 100644 --- a/lms/lmsweb/forms/reset_password.py +++ b/lms/lmsweb/forms/reset_password.py @@ -2,7 +2,7 @@ from flask_babel import gettext as _ # type: ignore from flask_wtf import FlaskForm from wtforms import StringField -from wtforms.fields.simple import PasswordField +from wtforms import PasswordField from wtforms.validators import Email, EqualTo, InputRequired, Length diff --git a/lms/lmsweb/views.py b/lms/lmsweb/views.py index 6a36a950..67d95631 100644 --- a/lms/lmsweb/views.py +++ b/lms/lmsweb/views.py @@ -107,7 +107,7 @@ def login(login_message: Optional[str] = None): login_message = request.args.get('login_message') if not form.validate_on_submit(): return render_template( - 'login.html', form=form, login_message=login_message + 'login.html', form=form, login_message=login_message, ) username = form.username.data From 5715c515712feb081ba44539a2e7af2a09776b30 Mon Sep 17 00:00:00 2001 From: Noga Osin Date: Sat, 2 Oct 2021 00:36:51 +0300 Subject: [PATCH 5/5] summore flake8 fixes --- lms/lmsweb/forms/login.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lms/lmsweb/forms/login.py b/lms/lmsweb/forms/login.py index d5160e67..9b48a6e4 100644 --- a/lms/lmsweb/forms/login.py +++ b/lms/lmsweb/forms/login.py @@ -1,6 +1,5 @@ from flask_wtf import FlaskForm from wtforms import PasswordField, StringField -from wtforms.fields.simple import PasswordField from wtforms.validators import InputRequired, Length