Skip to content

Commit

Permalink
Merge pull request #929 from nicozanf/master
Browse files Browse the repository at this point in the history
DOCS: typos and run options updates
  • Loading branch information
nicozanf authored Oct 12, 2024
2 parents f1ab8a6 + cdacb2f commit 542071b
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 69 deletions.
63 changes: 30 additions & 33 deletions docs/chapter-03.rst
Original file line number Diff line number Diff line change
Expand Up @@ -377,39 +377,36 @@ This currently gives an error on binaries installations and from source installa
Run the applications on apps_folder

Options:
-Y, --yes No prompt, assume yes to questions
[default: False]

-H, --host TEXT Host listening IP [default: 127.0.0.1]
-P, --port INTEGER Port number [default: 8000]
-A, --app_names TEXT List of apps to run, comma separated (all if omitted or
empty)
-p, --password_file TEXT File for the encrypted password [default:
password.txt]
-Q, --quiet Suppress server output
-R, --routes Write apps routes to file
-s, --server [default|wsgiref|tornado|gunicorn|gevent|waitress|gunicorn|gunicornGevent|gevent|
geventWebSocketServer|geventWs|wsgirefThreadingServer|wsgiTh|rocketServer]
Web server to use
-w, --number_workers INTEGER Number of workers [default: 0]
-d, --dashboard_mode TEXT Dashboard mode: demo, readonly, full, none
[default: full]

--watch [off|sync|lazy] Watch python changes and reload apps
automatically, modes: off, sync, lazy
[default: lazy]

--ssl_cert PATH SSL certificate file for HTTPS
--ssl_key PATH SSL key file for HTTPS
--errorlog TEXT Where to send error logs
(:stdout|:stderr|tickets_only|{filename})
[default: :stderr]
-L, --logging_level INTEGER The log level (0 - 50) [default: 30
(=WARNING)]
-D, --debug Debug switch [default: False]
-U, --url_prefix TEXT Prefix to add to all URLs in and out
-help, -h, --help Show this message and exit.

-Y, --yes No prompt, assume yes to questions
-H, --host TEXT Host listening IP [default: 127.0.0.1]
-P, --port INTEGER Port number [default: 8000]
-A, --app_names TEXT List of apps to run, comma separated (all if
omitted or empty)
-p, --password_file TEXT File for the encrypted password [default:
password.txt]
-Q, --quiet Suppress server output
-R, --routes Write apps routes to file
-s, --server [default|wsgiref|tornado|wsgiref+threaded|rocket|waitress|gunicorn|gevent|gunicorn+gevent|gevent+websockets]
Web server to use (unavailable: waitress,
gunicorn, gevent, gunicorn+gevent,
gevent+websockets)
-w, --number_workers INTEGER Number of workers [default: 0]
-d, --dashboard_mode TEXT Dashboard mode: demo, readonly, full, none
[default: full]
--watch [off|sync|lazy] Watch python changes and reload apps
automatically, modes: off, sync, lazy
[default: lazy]
--ssl_cert PATH SSL certificate file for HTTPS
--ssl_key PATH SSL key file for HTTPS
--errorlog TEXT Where to send error logs
(:stdout|:stderr|tickets_only|{filename})
[default: :stderr]
-L, --logging_level INTEGER The log level (0 - 50) [default: 30
(=WARNING)]
-D, --debug Debug switch
-U, --url_prefix TEXT Prefix to add to all URLs in and out
-m, --mode TEXT default or development [default: default]
-help, -h, --help Show this message and exit.

The ``app_names`` option lets you filter which specific apps you want to serve (comma separated). If absent or empty
all the apps in the APPS_FOLDER will be run.
Expand Down
38 changes: 23 additions & 15 deletions docs/chapter-05.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,14 @@ The newly created file will be accessible at
Notice that ``static`` is a special path for py4web and only files under
the ``static`` folder are served.

Important: internally py4web uses the ombott
(One More BOTTle) <https://github.com/valq7711/ombott>`__,
It supports streaming, partial content, range requests,
and if-modified-since. This is all
handled automatically based on the HTTP request headers.
.. important::

Internally py4web uses the
`ombott (One More BOTTle) web server <https://github.com/valq7711/ombott>`__,
which is a minimal and fast `bottlepy <https://bottlepy.org/>`__ spin-off.
It supports streaming, partial content, range requests,
and if-modified-since. This is all
handled automatically based on the HTTP request headers.

Dynamic Web Pages
-----------------
Expand Down Expand Up @@ -333,11 +336,10 @@ The scaffold app contains an example of a more complex action:
Notice the following:

- ``request``, ``response``, ``abort`` are defined by ``ombott``
which is a minimal and fast bottlepy spin-off.
- ``redirect`` and ``URL`` are similar to their web2py counterparts
- ``request``, ``response``, ``abort`` are defined by ``ombott``.
- ``redirect`` and ``URL`` are similar to their web2py counterparts.
- helpers (``A``, ``DIV``, ``SPAN``, ``IMG``, etc) must be imported
from ``yatl.helpers`` . They work pretty much as in web2py
from ``yatl.helpers`` . They work pretty much as in web2py.
- ``db``, ``session``, ``T``, ``cache``, ``auth`` are Fixtures. They
must be defined in ``common.py``.
- ``@action.uses(auth.user)`` indicates that this action expects a
Expand Down Expand Up @@ -465,12 +467,18 @@ a domain ``myapp.example.com`` might look like that:
}
}
This is an example ``server`` block of nginx configuraiton. One would have to create a separate such block for **each app/each domain** being served by py4web server. Note some important aspects:
This is an example ``server`` block of nginx configuration. One would have to create
a separate such block for **each app/each domain** being served by py4web server. Note some important aspects:

- ``server_name`` defines the domain mapped to the app ``myapp``,
- ``proxy_http_version 1.1;`` directive is optional, but highly recommended (otherwise nginx uses HTTP 1.0 to talk to the backend-server -- here py4web -- and it creates all kinds of issues with buffering and otherwise),
- ``proxy_http_version 1.1;`` directive is optional, but highly recommended (otherwise nginx uses HTTP 1.0 to talk
to the backend-server -- here py4web -- and it creates all kinds of issues with buffering and otherwise),
- ``proxy_set_header Host $host;`` directive ensures that the correct ``Host`` is passed to py4web -- here ``myapp.example.com``
- ``proxy_set_header X-PY4WEB-APPNAME /myapp;`` directive ensures that py4web (and ombott) knows which app to serve and **also** that this application is domain-mapped -- pay specific attention to the slash (``/``) in front of the ``myapp`` name -- it is **required** to ensure correct parsing of URLs on ombott level,
- finally ``proxy_pass http://127.0.0.1:8000/myapp$request_uri;`` ensures that the request is passed in its entirity (``$request_uri``) to py4web server (here: ``127.0.0.1:8000``) and the correct app (``/myapp``).

Such configuration ensures that all URL manipulation inside ombott and py4web - especially in modules such as ``Auth``, ``Form``, and ``Grid`` are done correctly using the domain to which the app is mapped to.
- ``proxy_set_header X-PY4WEB-APPNAME /myapp;`` directive ensures that py4web (and ombott) knows which app to serve
and **also** that this application is domain-mapped -- pay specific attention to the slash (``/``) in front of the ``myapp``
name -- it is **required** to ensure correct parsing of URLs on ombott level,
- finally ``proxy_pass http://127.0.0.1:8000/myapp$request_uri;`` ensures that the request is passed in its integrity (``$request_uri``)
to py4web server (here: ``127.0.0.1:8000``) and the correct app (``/myapp``).

Such configuration ensures that all URL manipulation inside ombott and py4web - especially in modules such as ``Auth``, ``Form``,
and ``Grid`` are done correctly using the domain to which the app is mapped to.
56 changes: 35 additions & 21 deletions docs/chapter-13.rst
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,11 @@ a logged in user and should redirect to login if no user is logged in.
Two Factor Authentication
~~~~~~~~~~~~~~~~~~~~~~~~~

Two factor authentication (or Two-step verification) is a way of improving authentication security. When activated an extra step is added in the login
process. In the first step, users are shown the standard username/password form. If they successfully pass this challenge by submitting the correct
username and password, and two factor authentication is enabled for the user, the server will present a second form before logging them in.
Two factor authentication (or Two-step verification) is a way of improving authentication security.
When activated an extra step is added in the login process. In the first step, users are shown the
standard username/password form. If they successfully pass this challenge by submitting the correct
username and password, and two factor authentication is enabled for the user, the server will
present a second form before logging them in.

There are a few Auth settings available to control how two factor authentication works.

Expand All @@ -168,8 +170,9 @@ The following can be specified on Auth instantiation:
two_factor_required
^^^^^^^^^^^^^^^^^^^

When you pass a method name to the ``two_factor_required`` parameter you are telling py4web to call that method to determine whether or not this login should
be use or bypass two factor authentication. If your method returns True, then this login requires two factor. If it returns False, two factor authentication
When you pass a method name to the ``two_factor_required`` parameter you are telling py4web to call
that method to determine whether or not this login should be use or bypass two factor authentication.
If your method returns True, then this login requires two factor. If it returns False, two factor authentication
is bypassed for this login.

Sample ``two_factor_required`` method
Expand All @@ -196,8 +199,9 @@ This example shows how to allow users that are on a specific network.
two_factor_send
^^^^^^^^^^^^^^^

When two factor authentication is active, py4web can generate a 6 digit code (using random.randint) and makes it possible to send it to the user. How this code is
sent, is up to you. The ``two_factor_send`` argument to the Auth class allows you to specify the method that sends the two factor code to the user.
When two factor authentication is active, py4web can generate a 6 digit code (using random.randint) and
makes it possible to send it to the user. How this code is sent, is up to you. The ``two_factor_send``
argument to the Auth class allows you to specify the method that sends the two factor code to the user.

This example shows how to send an email with the two factor code:

Expand Down Expand Up @@ -226,15 +230,22 @@ 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 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 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
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 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 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.
To accomplish such custom validation, the ``two_factor_validate`` method is available. It takes two arguments:

- the current user
- 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:

Expand All @@ -256,15 +267,17 @@ This example shows how to validate a time-based two factor code:
The ``validate_code`` method must return one of three values:

- ``True`` - if the validation succeded,
- ``True`` - if the validation succeeded,
- ``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. 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.
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. 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 decreased 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 All @@ -291,7 +304,8 @@ Once this is all setup, the flow for two factor authentication is:
- if ``two_factor_validate`` method has been defined - call it to validate the user-entered code
- upon successful verification, take user to _next_url that was passed to the login page

Important! If you filtered ``ALLOWED_ACTIONS`` in your app, make sure to whitelist the "two_factor" action so not to block the two factor API.
Important! If you filtered ``ALLOWED_ACTIONS`` in your app, make sure to whitelist the "two_factor" action
so not to block the two factor API.


Auth Plugins
Expand Down

0 comments on commit 542071b

Please sign in to comment.