Skip to content

Commit

Permalink
Correct the documentation following additional changes in the code
Browse files Browse the repository at this point in the history
  • Loading branch information
kszys committed Sep 29, 2024
1 parent 6c664a0 commit 5f1ea30
Showing 1 changed file with 22 additions and 15 deletions.
37 changes: 22 additions & 15 deletions docs/chapter-13.rst
Original file line number Diff line number Diff line change
Expand Up @@ -226,38 +226,45 @@ Also notice this method can override the code and return a new one.
two_factor_validate
^^^^^^^^^^^^^^^^^^^

By default, py4web will validate the user input in the two factor form by comparing the number entered by the user with the code generated and sent using
By default, py4web will validate the user input in the two factor form by comparing the code entered by the user with the code generated and sent using
``two_factor_send``. However, sometimes it may be useful to define a custom validation of this user-entered code. For instance, if one would like to use the
TOTP (or the Time-Based One-Time-Passwords) as the two factor authentication method, the validation requires comparing the code entered by the user with the
value generated at the same time at the server side. Hence, it is not sufficient to generate that value when showing the form (using for instance
value generated at the same time at the server side. Hence, it is not sufficient to generate that value earlier when showing the form (using for instance
``two_factor_send`` method), because by the time the user submits the form, the current valid value may already be different. Instead, this value should be
generated when validating the form submitted by the user.

To accomplish such custom validation, the ``two_factor_validate`` method is available. It takes one argument ``form``, which is the two factor authentication
form. The primary use-case for this method is validation of time-based passwords.
To accomplish such custom validation, the ``two_factor_validate`` method is available. It takes two arguments - the current user and the code that was entered
by the user into the two factor authentication form. The primary use-case for this method is validation of time-based passwords.

This example shows how to validate a time-based two factor code with an optional fallback to using the code returned by the ``two_factor_send`` method:
This example shows how to validate a time-based two factor code:

.. code:: python
def validate_code(form):
# get the user id
user_id = auth.session.get("auth.2fa_user")
def validate_code(user, code):
try:
# get the correct code from an external function
correct_code = generate_time_based_code(user_id)
except Exception as e:
# otherwise use the code that was returned by two_factor_send method
correct_code = auth.session.get("auth.2fa_code")
# return None to indicate that validation could not be performed
return None
# compare the value entered in the auth form with the correct code
if form.vars['authentication_code'] != correct_code:
form.errors['authentication_code'] = "Incorrect code."
if code == correct_code:
return True
else:
return False
The ``validate_code`` method must return one of three values:

- ``True`` - if the validation succeded,
- ``False`` - if the validation failed,
- ``None`` - if the validation was not possible for any reason

Notice that - if defined - this method is _always_ called to validate the two factor authentication form. It is up to you to decide what kind of validation it
does, but if it is used in conjunction with ``two_factor_send`` method, it also needs to be able to validate the user input against the code that was sent to
the user.
does. If the returned value is ``True``, the user input will be accepted as valid. If the returned value is ``False`` then the user input will be rejected as
invalid, number of tries will be decresed by one, and user will be asked to try again. If the returned value is ``None`` the user input will be checked against
the code generated with the use of ``two_factor_send`` method and the final result will depend on that comparison. In this case authentication will fail if ``two_factor_send``
method was not defined, and hence no code was sent to the user.

.. code:: python
Expand Down

0 comments on commit 5f1ea30

Please sign in to comment.