Skip to content

Commit

Permalink
SQL Table names are now plural (users, roles, user_emails, user_invit…
Browse files Browse the repository at this point in the history
…ations). Lots of docs changes.
  • Loading branch information
lingthio committed Sep 4, 2017
1 parent 5bfa8ad commit 1be1eb6
Show file tree
Hide file tree
Showing 21 changed files with 336 additions and 289 deletions.
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Flask-User v0.9
===============
Flask-User v0.9 (pre-alpha)
===========================
**Customizable User Authentication, User Management, and more.**

.. topic:: Attention
Expand Down
6 changes: 3 additions & 3 deletions docs/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ This class manages the sending of Flask-User emails.

.. autoclass:: flask_user.email_manager.EmailManager

.. seealso:: :ref:`CustomizeManagers` on how to customize this manager.
.. seealso:: :ref:`CustomizingManagers` on how to customize this manager.

--------

Expand All @@ -36,7 +36,7 @@ The PasswordManager generates and verifies hashed passwords.
.. autoclass:: flask_user.password_manager.PasswordManager
:no-undoc-members:

.. seealso:: :ref:`CustomizeManagers` on how to customize this manager.
.. seealso:: :ref:`CustomizingManagers` on how to customize this manager.

--------

Expand All @@ -56,4 +56,4 @@ These tokens are used in the following places:
.. autoclass:: flask_user.token_manager.TokenManager
:no-undoc-members:

.. seealso:: :ref:`CustomizeManagers` on how to customize this manager.
.. seealso:: :ref:`CustomizingManagers` on how to customize this manager.
110 changes: 24 additions & 86 deletions docs/source/authorization.rst
Original file line number Diff line number Diff line change
@@ -1,37 +1,20 @@
Authorization
=============
Role-based Authorization
========================
Authorization is the process of specifying and enforcing access rights of users to resources.

Flask-User offers role based authorization through the use of function decorators:
Flask-User offers role-based authorization through the use of the ``@roles_required`` decorator.

* `@login_required`_
* `@roles_required`_

@login_required
@roles_required
---------------
Decorate a view function with ``@login_required`` decorator to ensure that
the user is logged in before accessing that particular page
or an 'Unauthorized' error message will be shown.

::
If a view function is decorated with the ``@roles_required`` decorator, the user:

from flask_user import login_required
- must be logged in, and
- must be associated with the specified role names.

@route('/profile') # @route() must always be the outer-most decorator
@login_required
def profile_page():
# render the user profile page
If any of these conditions is not met, an 'Unauthorized access' error message will be shown
and the user will be redirected to the ``USER_UNAUTHORIZED_ENDPOINT``.

| Flask-User relies on Flask-Login to implement and offer the @login_required decorator along with its underlying current_user.is_authenticated() implementation.
| See the `Flask-Login Documentation <https://flask-login.readthedocs.org/en/latest/#flask.ext.login.login_required>`_
@roles_required
---------------
If a view function is decorated with the ``@roles_required`` decorator,
the use must be logged in to access that page
or an 'Unauthorized' error message will be shown.

In the example below the current user is required to have a role named 'Admin'::
In the example below the current user is required to be logged in and to be associated with the role named 'Admin'::

from flask_user import roles_required

Expand All @@ -46,76 +29,31 @@ Simple AND/OR operations
~~~~~~~~~~~~~~~~~~~~~~~~

The @roles_required decorator accepts one or more role names.
At this level, if multiple role names are specified,
the user is required to have **all** the specified roles.
At the decorator level, if multiple role names are specified here,
the user must have **all** the specified roles.
This is the AND operation.

Each list item at the previous level may be either a role name or a list or role names.
At this level, if a list of role names is specified,
the use is may have **any one** of the specified roles to gain access.
At the argument level, each item may be a role name or a list or role names.
If a list of role names is specified here,
the user mast have **any one** of the specified roles to gain access.
This is the OR operation.

In the example below, the user must always have the ``'Starving'`` role,
plus either the ``'Artist'`` role or the ``'Programmer'`` role::
AND either the ``'Artist'`` role OR the ``'Programmer'`` role::

# Ensures that the user is ('Starving' AND (an 'Artist' OR a 'Programmer'))
@roles_required('Starving', ['Artist', 'Programmer'])

Note: The nesting level only goes as deep as this example shows.


Required Tables
---------------

For @login_required only the User data-model is required

For @roles_required, the database must have the following data-models:

* The usual User data-model with an additional 'roles' relationship field
* A Role data-model with at least one string field called 'name'
* A UserRoles association data-model with a 'user_id' field and a 'role_id' field

Here's a SQLAlchemy example::

# Define User data-model
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(50), nullable=True, unique=True)
...
# Define the relationship to Role via UserRoles
roles = db.relationship('Role', secondary='user_roles')

# Define Role data-model
class Role(db.Model):
id = db.Column(db.Integer(), primary_key=True)
name = db.Column(db.String(50), unique=True)

# Define UserRoles data-model
class UserRoles(db.Model):
id = db.Column(db.Integer(), primary_key=True)
user_id = db.Column(db.Integer(), db.ForeignKey('user.id', ondelete='CASCADE'))
role_id = db.Column(db.Integer(), db.ForeignKey('role.id', ondelete='CASCADE'))

Roles are defined by adding rows to the role table with a specific Role.name value.

::

# Create 'user007' user with 'secret' and 'agent' roles
user1 = User(username='user007', email='[email protected]', is_enabled=True,
password=user_manager.password_manager.hash_password('Password1'))
role1 = Role(name='secret')
role2 = Role(name='agent')

Users are assigned one or more roles by adding a records to the 'user_roles' table,
binding a User to one or more Roles.

::

# Bind user to two roles
user1.roles.append(role1)
user1.roles.append(role2)
Required Role and UserRoles data-models
---------------------------------------
The @roles_required decorator depends the ``Role`` and ``UserRoles`` data-models
(in addition to the ``User`` data-model).

# Store user and roles
db.session.add(user1)
db.session.commit()
See the docs on :ref:`Role and UserRoles data-models<RoleAndUserRoleDataModels>`.

Example App
-----------
The :ref:`RolesRequiredApp` demonstrates the use of the ``@roles_required`` decorator.
16 changes: 8 additions & 8 deletions docs/source/customize.rst → docs/source/customization.rst
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
Customize
=========
Flask-User Customization
========================

Flask-User is designed to be **largely configurable**,

- :ref:`ConfigureSettings`

and **almost fully customizable**.

- :ref:`CustomizeForms`
- :ref:`CustomizeDbAdapter`
- :ref:`CustomizeEmailMailer`
- :ref:`CustomizeManagers`
- :ref:`CustomizingForms`
- :ref:`CustomizingValidators`
- :ref:`CustomizingDbAdapter`
- :ref:`CustomizingEmailMailer`
- :ref:`CustomizingManagers`


.. _CustomizeManagers:
.. _CustomizingManagers:

Customizing the EmailManager, PasswordManager or TokenManager
-------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.. _CustomizeDbAdapter:
.. _CustomizingDbAdapter:

Customizing the DbAdapter
=========================
Expand All @@ -7,16 +7,16 @@ Flask-User uses DbAdapters to manage user records in various databases.

Flask-User ships with the following DbAdapters:

- :ref:`CustomizeSQLAlchemyDbAdapter` for various SQL databases.
- :ref:`CustomizeMongoEngineDbAdapter` for MongoDB databases.
- :ref:`CustomizingSQLAlchemyDbAdapter` for various SQL databases.
- :ref:`CustomizingMongoEngineDbAdapter` for MongoDB databases.

and developers can define their own:

- :ref:`CustomDbAdapter`

--------

.. _CustomizeSQLAlchemyDbAdapter:
.. _CustomizingSQLAlchemyDbAdapter:

SQLAlchemyDbAdapter
-------------------
Expand All @@ -27,7 +27,7 @@ Configure the ``SQLALCHEMY_DATABASE_URI`` setting in your app config to point to

--------

.. _CustomizeMongoEngineDbAdapter:
.. _CustomizingMongoEngineDbAdapter:

MongoEngineDbAdapter
--------------------
Expand Down Expand Up @@ -64,7 +64,6 @@ and minor customization is required to use and configure the MongoEngineDbAdapte
last_name = db.StringField(default='')

# Relationships
# roles = ListField(StringField(), required=False, default_empty=True)
roles = db.ListField(db.StringField(), default=[])

# Setup Flask-User
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.. _CustomizeEmailMailer:
.. _CustomizingEmailMailer:

Customizing the EmailMailer
===========================
Expand All @@ -7,17 +7,17 @@ Flask-User uses EmailMailers to send email via various methods.

Flask-User ships with the following EmailMailers:

- :ref:`CustomizeSMTPEmailMailer` for sending email via SMTP.
- :ref:`CustomizeSendmailEmailMailer` for sending email via ``sendmail``.
- :ref:`CustomizeSendgridEmailMailer` for sending email via SendGrid.
- :ref:`CustomizingSMTPEmailMailer` for sending email via SMTP.
- :ref:`CustomizingSendmailEmailMailer` for sending email via ``sendmail``.
- :ref:`CustomizingSendgridEmailMailer` for sending email via SendGrid.

and developers can define their own:

- :ref:`CustomEmailMailer`.

--------

.. _CustomizeSMTPEmailMailer:
.. _CustomizingSMTPEmailMailer:

SMTPEmailMailer
---------------
Expand All @@ -28,7 +28,7 @@ Configure the ``MAIL_...`` settings in your app config to point to the desired S

--------

.. _CustomizeSendmailEmailMailer:
.. _CustomizingSendmailEmailMailer:

SendmailEmailMailer
-------------------
Expand All @@ -53,7 +53,7 @@ No configuration is required (other than setting up sendmail on your system).

---------

.. _CustomizeSendgridEmailMailer:
.. _CustomizingSendgridEmailMailer:

SendgridEmailMailer
-------------------
Expand Down
Loading

0 comments on commit 1be1eb6

Please sign in to comment.