flask_allows API

Extension

class flask_allows.allows.Allows(app=None, identity_loader=None, throws=<class 'werkzeug.exceptions.Forbidden'>, on_fail=None)[source]

The Flask-Allows extension object used to control defaults and drive behavior.

Parameters:
  • app – Optional. Flask application instance.
  • identity_loader – Optional. Callable that will load the current user
  • throws – Optional. Exception type to raise by default when authorization fails.
  • on_fail – Optional. A value to return or function to call when authorization fails.
clear_all_additional()[source]

Helper method to remove all additional contexts, this is called automatically during the after request phase in Flask. However it is provided here if additional contexts need to be cleared independent of the request cycle.

If an additional context is found that originated from an AdditionalManager instance not controlled by the Allows object, a RuntimeError will be raised.

clear_all_overrides()[source]

Helper method to remove all override contexts, this is called automatically during the after request phase in Flask. However it is provided here if override contexts need to be cleared independent of the application context.

If an override context is found that originated from an OverrideManager instance not controlled by the Allows object, a RuntimeError will be raised.

fulfill(requirements, identity=None)[source]

Checks that the provided or current identity meets each requirement passed to this method.

This method takes into account both additional and overridden requirements, with overridden requirements taking precedence:

allows.additional.push(Additional(Has('foo')))
allows.overrides.push(Override(Has('foo')))

allows.fulfill([], user_without_foo)  # return True
Parameters:
  • requirements – The requirements to check the identity against.
  • identity – Optional. Identity to use in place of the current identity.
identity_loader(f)[source]

Used to provide an identity loader after initialization of the extension.

Can be used as a method:

allows.identity_loader(lambda: a_user)

Or as a decorator:

@allows.identity_loader
def load_user():
    return a_user

If an identity loader is provided at initialization, this method will overwrite it.

Parameters:f – Callable to load the current user
init_app(app)[source]

Initializes the Flask-Allows object against the provided application

requires(*requirements, **opts)[source]

Decorator to enforce requirements on routes

Parameters:
  • requirements – Collection of requirements to impose on view
  • throws – Optional, keyword only. Exception to throw for this route, if provided it takes precedence over the exception stored on the instance
  • on_fail – Optional, keyword only. Value or function to use as the on_fail for this route, takes precedence over the on_fail configured on the instance.
run(requirements, identity=None, throws=None, on_fail=None, f_args=(), f_kwargs={}, use_on_fail_return=True)[source]

Used to preform a full run of the requirements and the options given, this method will invoke on_fail and/or throw the appropriate exception type. Can be passed arguments to call on_fail with via f_args (which are passed positionally) and f_kwargs (which are passed as keyword).

Parameters:
  • requirements – The requirements to check
  • identity – Optional. A specific identity to use for the check
  • throws – Optional. A specific exception to throw for this check
  • on_fail – Optional. A callback to invoke after failure, alternatively a value to return when failure happens
  • f_args – Positional arguments to pass to the on_fail callback
  • f_kwargs – Keyword arguments to pass to the on_fail callback
  • use_on_fail_return – Boolean (default True) flag to determine if the return value should be used. If true, the return value will be considered, else failure will always progress to exception raising.

Permission Helper

class flask_allows.permission.Permission(*requirements, **opts)[source]

Used to check requirements as a boolean or context manager. When used as a boolean, it only runs the requirements and returns the raw boolean result:

p = Permission(is_admin)

if p:
    print("Welcome to the club!")

When used as a context manager, it runs both the check and the failure handlers if the requirements are not met:

p = Permission(is_admin)

with p:
    # will run on_fail and throw before reaching if the
    # requirements on p return False
    print("Welcome to the club!")

Note

Both the context manager and boolean usages require an active application context to use.

Parameters:
  • requirements – The requirements to check against
  • throws – Optional, keyword only. Exception to throw when used as a context manager, if provided it takes precedence over the exception stored on the current application’s registered Allows instance
  • on_fail – Optional, keyword only. Value or function to use as the on_fail when used as a context manager, if provided takes precedence over the on_fail configured on current application’s registered Allows instance
  • identity – Optional, keyword only. An identity to verify against instead of the using the loader configured on the current application’s registered Allows instance

Requirements Base Classes

class flask_allows.requirements.Requirement[source]

Base for object based Requirements in Flask-Allows. This is quite useful for requirements that have complex logic that is too much to fit inside of a single function.

fulfill(user, request=None)[source]

Abstract method called to verify the requirement against the current user and request.

Changed in version 0.5.0: Passing request is now deprecated, pending removal in version 1.0.0

Parameters:
  • user – The current identity
  • request – The current request.
class flask_allows.requirements.ConditionalRequirement(*requirements, **kwargs)[source]

Used to combine requirements together in ways other than all-or-nothing, such as with an or-reducer (any requirement must be True):

from flask_allows import Or

requires(Or(user_is_admin, user_is_moderator))

or negating a requirement:

from flask_allows import Not

requires(Not(user_logged_in))

Combinations may also nested:

Or(user_is_admin, And(user_is_moderator, HasPermission('view_admin')))

Custom combinators may be built by creating an instance of ConditionalRequirement and supplying any combination of its keyword parameters

This class is also exported under the C alias.

Parameters:
  • requirements – Collection of requirements to combine into one logical requirement
  • op – Optional, Keyword only. A binary operator that accepts two booleans and returns a boolean.
  • until – Optional, Keyword only. A boolean to short circuit on (e.g. if provided with True, then the first True evaluation to return from a requirement ends verification)
  • negated – Optional, Keyword only. If true, then the ConditionalRequirement will return the opposite of what it actually evaluated to (e.g. ConditionalRequirement(user_logged_in, negated=True) returns False if the user is logged in)
classmethod And(*requirements)[source]

Short cut helper to construct a combinator that uses operator.and_() to reduce requirement results and stops evaluating on the first False.

This is also exported at the module level as And

classmethod Not(*requirements)[source]

Shortcut helper to negate a requirement or requirements.

This is also exported at the module as Not

classmethod Or(*requirements)[source]

Short cut helper to construct a combinator that uses operator.or_() to reduce requirement results and stops evaluating on the first True.

This is also exported at the module level as Or

fulfill(user, request)[source]

Abstract method called to verify the requirement against the current user and request.

Changed in version 0.5.0: Passing request is now deprecated, pending removal in version 1.0.0

Parameters:
  • user – The current identity
  • request – The current request.

Override Management

class flask_allows.overrides.Override(*requirements)[source]

Container object that allows selectively disabling requirements.

Requirements can be disabled by passing them to the constructor or by calling the add method. They can be re-enabled by calling the remove method. To check if a requirement is currently disabled, you may call either is_overridden or use in.

Override objects can be combined and compared to each other with the following operators:

+ creates a new overide object by combining two others, the new override overrides all requirements that both parents did.

+= similar to + except it is an inplace update.

- creates a new override instance by removing any overrides from the first instance that are contained in the second instance.

-= similar to - except it is an inplace update

== compares two overrides and returns true if both have the same disabled requirements.

!= similar to == except returns true if both have different disabled requirements.

add(requirement, *requirements)[source]

Adds one or more requirements to the override context.

is_overridden(requirement)[source]

Checks if a particular requirement is current overridden. Can also be used as in:

override = Override()
override.add(is_admin)
override.is_overridden(is_admin)  # True
is_admin in override  # True
remove(requirement, *requirements)[source]

Removes one or more requirements from the override context.

class flask_allows.overrides.OverrideManager[source]

Used to manage the process of overriding and removing overrides. This class shouldn’t be used directly, instead use allows.overrides to access these controls.

current

Returns the current override context if set otherwise None

override(override, use_parent=False)[source]

Allows temporarily pushing an override context, yields the new context into the following block.

pop()[source]

Pops the latest override context.

If the override context was pushed by a different override manager, a RuntimeError is raised.

push(override, use_parent=False)[source]

Binds an override to the current context, optionally use the current overrides in conjunction with this override

If use_parent is true, a new override is created from the parent and child overrides rather than manipulating either directly.

class flask_allows.additional.Additional(*requirements)[source]

Container object that allows to run extra requirements on checks. These additional requirements will be run at most once per check and will occur in no guarenteed order.

Requirements can be added by passing them into the constructor or by calling the add method. They can be removed from this object by calling the remove method. To check if a requirement has been added to the current conext, you may call is_added or use in:

some_req in additional
additional.is_added(some)req)

Additional objects can be iterated and length checked:

additional = Additional(some_req)
assert len(additional) == 1
assert list(additional) == [some_req]

Additional objects may be combined and compared to each other with the following operators:

+ creates a new additional object by combining two others, the new additional supplies all requirements that both parents did.

+= similar to + except it is an inplace update.

- creates a new additional instance by removing any requirements from the first instance that are contained in the second instance.

-= similar to - except it is an inplace update.

== compares two additional instances and returns true if both have the same added requirements.

!= similar to != except returns true if both have different requirements contained in them.

class flask_allows.additional.AdditionalManager[source]

Used to manage the process of adding and removing additional requirements to be run. This class shouldn’t be used directly, instead use allows.additional to access these controls.

additional(additional, use_parent=False)[source]

Allows temporarily pushing an additional context, yields the new context into the following block.

current

Returns the current additional context if set otherwise None

pop()[source]

Pops the latest additional context.

If the additional context was pushed by a different additional manager, a RuntimeError is raised.

push(additional, use_parent=False)[source]

Binds an additional to the current context, optionally use the current additionals in conjunction with this additional

If use_parent is true, a new additional is created from the parent and child additionals rather than manipulating either directly.

Utilities

flask_allows.views.requires(*requirements, **opts)[source]

Standalone decorator to apply requirements to routes, either function handlers or class based views:

@requires(MyRequirement())
def a_view():
    pass

class AView(View):
    decorators = [requires(MyRequirement())]
Parameters:
  • requirements – The requirements to apply to this route
  • throws – Optional. Exception or exception instance to throw if authorization fails.
  • on_fail – Optional. Value or function to use when authorization fails.
  • identity – Optional. An identity to use in place of the currently loaded identity.
flask_allows.views.exempt_from_requirements(f)[source]

Used to exempt a route handler from ambient requirement handling unless it is explicitly decorated with a requirement runner:

@bp.route('/')
@exempt_from_requirements
def greeting_area():
    return "Hello!"

To use with a class based view, apply it to the class level decorators attribute:

class SomeCBV(View):
    decorators = [exempt_from_requirements]

    def get(self):
        return "Hello!"

Note

You cannot exempt individual methods of a class based view with this decorator, e.g. the follow will not work:

class SomeCBV(MethodView):

    @exempt_from_requirements
    def get(self):
        return "Hello!"

Any permissioning applied at the blueprint level would still affect this route.

Parameters:f – The route handler to be decorated.

New in version 0.7.0.

flask_allows.views.guard_entire(requirements, identity=None, throws=None, on_fail=None)[source]

Used to protect an entire blueprint with a set of requirements. If a route handler inside the blueprint should be exempt, then it may be decorated with the exempt_from_requirements() decorator.

This function should be registered as a before_request handler on the blueprint and provided with the requirements to guard the blueprint with:

my_bp = Blueprint(__name__, 'namespace')
my_bp.before_request(guard_entire(MustBeLoggedIn()))

identity, on_fail and throws may also be provided but are optional. If on_fails returns a non-None result, that will be considered the return value of the routing:

from flask import flash, redirect

def flash_and_redirect(message, level, endpoint):
    def _(*a, **k):
        flash(message, level)
        return redirect(endpoint)
    return _

bp = Blueprint(__name__, 'namespace')
bp.before_request(
    guard_entire(
        [MustBeLoggedIn()],
        on_fail=flash_and_redirect(
            "Please login in first",
            "warning",
            "login"
        )
    )
)

on_fail will also receive anything found in flask.request.view_args as keyword arguments.

If needed, this guard may be applied multiple times. This may be useful if different conditions should result in different on_fail mechanisms being invoked:

bp = Blueprint(__name__, "admin_panel")
bp.before_request(
    guard_entire(
        [MustBeLoggedIn()],
        on_fail=flash_and_redirect(
            "Please login in first",
            "warning",
            "login"
        )
    )
)
bp.before_request(
    guard_entire(
        [MustBeAdmin()],
        on_fail=flash_and_redirect(
            "You are not an admin.",
            "danger",
            "index"
        )
    )
)
Parameters:
  • requirements – An iterable of requirements to apply to every request routed to the blueprint.
  • identity – Optional. The identity that should be used for fulfilling requirements on the blueprint level.
  • throws – Optional. Exception or exception type to be thrown if authorization fails.
  • on_fail – Optional. Value or function to use if authorization fails.
flask_allows.requirements.wants_request(f)[source]

Helper decorator for transitioning to user-only requirements, this aids in situations where the request may be marked optional and causes an incorrect flow into user-only requirements.

This decorator causes the requirement to look like a user-only requirement but passes the current request context internally to the requirement.

This decorator is intended only to assist during a transitionary phase and will be removed in flask-allows 1.0

See: #20, #27