Ferris uses the concept of authorization chains to control access to controllers and their actions. The concept is simple: A authorization chain consists of a series of functions (or callables). When trying to determine to allow or deny a request each function in the chain is called. If any of the functions return False then the request is rejected. Chains are specified using Controller.Meta.authorizations and the add_authorizations() decorator.
Here’s an example of requiring a user to be logged in to access a controller:
from ferris import Controller
def require_user(controller):
return True if controller.user else False
class Protected(Controller):
class Meta:
authorizations = (require_user,)
...
You can also use add_authorizations() instead:
@route
@add_authorizations(require_user)
def protected_action(self):
...
Adds additional authorization chains to a particular action. These are executed after the chains set in Controller.Meta.
To add authorizations globally use the global event bus.
As shown above a simple authorization function is rather trivial:
def require_user(controller):
return True if controller.user else False
Note that you can also include a message:
def require_user(controller):
return True if controller.user else (False, "You must be logged in!")
Or if you’d like to redirect or present your own error page you can return any valid response:
def require_user(controller):
if controller.user:
return True
url = users.create_login_url(dest_url=controller.request.url)
return controller.redirect(url)
The module ferris.core.auth includes some built-in useful authorization functions and utilities.
Requires that a user is logged in and that the user is and administrator on the App Engine Application
There are a few function generators that use predicates. These are useful shortcut authorization functions.
Generates an authorization function that requires that users are logged in for the given prefix.
Generates an authorization function that requires that the user is an App Engine admin for the given prefix.
You can also create your own generators using precidates.
Then use predicate_chain to combine them with your authorization function.