1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
==================================================================
:mod:`bps.security.policy` -- Lightweight Access Control Framework
==================================================================
.. module:: bps.security.policy
:synopsis: lightweight access control framework
Overview
========
This module provides a framework for applications
to build complex permission and security policies,
centered around the common "user -> role -> permission" pattern.
This framework is derived from one deployed in a few web applications,
which in turn was inspired by Roundup's `access control mechanism <http://www.roundup-tracker.org/docs/design.html#access-control>`_.
Never-the-less, it's generic enough that it should be suitable for use
by gui and command line applications as well.
An application can make use of this framework by:
* creating a :class:`Policy` instance for the application.
* registering all potential roles with the policy
* registering all permissions, as expressed
in terms of actions, roles, and optional guard functions.
* querying the policy either to enumerate a given user's permissions,
or check if the user has permission to perform a specific action.
.. _permission-question:
Framing a Permission Question
=============================
.. todo:: finish write up the structure of the "permission question"
When an application needs to test whether a user has permission
to perform a given action, the first thing that must be done
to use any policy framework is to encode the question in a format
the permission system understands. This module encodes
permission questions using the following 5 parameters:
* ``action`` - a string, usually a verb such as ``"update"``,
which represents the action permission is being requested for.
* ``klass`` - optional string, usually a noun such as ``"BlogEntry"``
which the action will be acting upon. (Some actions
act globally, and won't have a class specified).
* ``item`` - optional object, usually an instance of the class identified by ``klass``.
This is generally used when the permission applies to only certain instances
of the class, which must be decided on a case-by-case basis.
* ``attr`` - optional string, usually a attribute of ``klass`` such as ``"date"``.
This is typically used when the action is restricted on a per-attribute basis.
* ``scope`` - optional object, usually the owner of the instance
being acted on, or a composite object which the action is being
performed inside of. This is needed very rarely, but there are
some cases, such as when requesting permission to create
a new instance of class which will be stored inside a particular
object, and that object affects the outcome of the permission check.
Combinations of 1 or more of these parameters can be put together
in order to encode the following questions:
1. ``Does {user} have permission to {action}?``
2. ``Does {user} have permission to {action} an object of type {klass}?``.
3. ``Does {user} have permission to {action} the object {item} of type {klass}?``
4. ``Does {user} have permission to {action} the attribute {attr} of an object of type {klass}?``
5. ``Does {user} have permission to {action} the attribute {attr} of the object {item} of type {klass}?``
6. ``Does {user} have permission to {action} an object of type {klass} as part of {scope}?``.
As an exmaple: does the user have permission to *create* an object of type
*entry* as part of *<a specific journal instance>*?
Usage Example
=============
.. todo:: write usage example for sec policy
The Policy Class
================
.. autoclass:: Policy
The Support Classes
===================
The following classes are used internally by :class:`Policy`,
and generally the programmer will not need to create them directly
(though they may need to examine them if preparing a list of
the user's permissions for display).
.. autoclass:: Role
.. autoclass:: Permission
..
Not documenting these right now, the system is usuable without
knowledge of this bit, although they could be usuable by the guard func,
but no use-case has needed this just yet:
.. _permissions-constants:
.. autoclass:: PERM
|