diff --git a/docs/chapter-03.rst b/docs/chapter-03.rst index e4167c0a..117d61f6 100644 --- a/docs/chapter-03.rst +++ b/docs/chapter-03.rst @@ -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. diff --git a/docs/chapter-05.rst b/docs/chapter-05.rst index 3ce7d52d..5ced55be 100644 --- a/docs/chapter-05.rst +++ b/docs/chapter-05.rst @@ -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) `__, -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 `__, + which is a minimal and fast `bottlepy `__ 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 ----------------- @@ -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 @@ -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. diff --git a/docs/chapter-13.rst b/docs/chapter-13.rst index 2322f359..f0cf4894 100644 --- a/docs/chapter-13.rst +++ b/docs/chapter-13.rst @@ -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. @@ -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 @@ -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: @@ -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: @@ -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 @@ -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