Adding Automatic Permissions for New Objects¶
When creating new objects in either viewsets or tasks it's important to have the right permissions.
It is important that the permissions new objects receive work with the AccessPolicy so that newly
created objects can be authorized by the AccessPolicy as expected. The AccessPolicy statements are
user-configurable and so the permissions to be created for new objects are too. Similar to the
requirements for the AccessPolicy statements
, plugin writers can define and ship a default
behavior for permissions on new objects, and then users can modify them as needed after migrations
are run.
Defining New Object Permission Behaviors¶
The AccessPolicy.creation_hooks
attribute defines a set of callables that are intended to be
run when new objects are created. These do not run automatically; your models should use the
pulpcore.plugin.models.AutoAddObjPermsMixin
on the model as described in the
enabling_new_object_permission_creation
section.
The AccessPolicy.creation_hooks
attribute is optional because not all AccessPolicy objects
create objects. If no objects are created by an endpoint, there does not need to be a
creation_hooks
attribute.
Permissions are associated to users via roles.
The most common auto-assignment of roles is to the creator of an object themselves. Here is an
example assigning the "core.task_owner"
role to the creator of an object:
{
"function": "add_roles_for_object_creator",
"parameters": {"roles": ["core.task_owner"]},
}
Another common auto-assignment of roles is to assign to one or more users explicitly. Here is an
example assigning the "core.task_owner"
role to the users ["alice", "bob"]
.
{
"function": "add_roles_for_users",
"parameters": {
"roles": "core.task_owner",
"users": ["alice", "bob"],
},
}
A third common auto-assignment of roles is to assign to one or more groups explicitly. Here is an
example assigning the "core.task_viewer"
role to the group "foo"
.
{
"function": "add_roles_for_groups",
"parameters": {
"roles": ["core.task_viewer"],
"groups": "foo",
},
}
Note
All the hooks shipped with pulpcore accept either a single item or list of items for their
arguments like roles
, users
or groups
.
Enabling New Object Permission Creation¶
To enable automatic permission creation for an object managed by an AccessPolicy, have your model use the pulpcore.plugin.models.AutoAddObjPermsMixin. See the example below as an example:
class MyModel(BaseModel, AutoAddObjPermsMixin):
...
Shipping a Default New Object Policy¶
In general, the default recommended is to use the add_roles_for_object_creator
to assign the
view, change, and delete permissions for the object created. Here is an example of a default policy
like this:
DEFAULT_ACCESS_POLICY = {
"statements": <...>
"creation_hooks": [
{
"function": "add_roles_for_object_creator",
"parameters": {"roles": "file.fileremote_owner"},
}
],
}
LOCKED_ROLES = {
"file.fileremote_owner": [
"file.view_fileremote", "file.change_fileremote", "file.delete_fileremote"
],
}
This effectively creates a "user isolation" policy which aligns with the examples from
shipping_default_access_policy
.
Defining Custom New Object Permission Callables¶
Plugin writers can use more than the built-in callables such as add_roles_for_object_creator
or
add_roles_for_users
by defining additional methods on the model itself. The callables defined in
the function
are method names on the Model that need to be registered with
REGISTERED_CREATION_HOOKS
:
class MyModel(BaseModel, AutoAddObjPermsMixin):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.REGISTERED_CREATION_HOOKS["my_custom_callable"] = self.my_custom_callable
def my_custom_callable(self, role, users, groups):
from pulpcore.app.util import assign_role
for user in users:
assign_role(role, user, self) # self is the object being assigned
for group in groups:
assign_role(role, group, self) # self is the object being assigned
This would be callable with a configuration like this one:
{
"function": "my_custom_callable",
"parameters": {
"role": "pulpcore.task_viewer",
"users": ["bob"],
"groups": [],
},
}
Note
The parameters
dict must actually match the creation hooks signature.
Reference¶
pulpcore.plugin.models.AutoAddObjPermsMixin(*args, **kwargs)
¶
A mixin that automatically adds roles based on the creation_hooks
data.
To use this mixin, your model must support django-lifecycle
.
This mixin adds an after_create
hook which properly interprets the creation_hooks
data and calls methods also provided by this mixin to add roles.
These hooks are provided by default:
add_roles_for_object_creator
will add the roles to the creator of the object.add_roles_for_users
will add the roles for one or more users by name.add_roles_for_groups
will add the roles for one or more groups by name.
add_roles_for_users(roles, users)
¶
Adds object-level roles for one or more users for this newly created object.
Parameters:
-
roles
(str or list
) –One or more roles to be added at object-level for the users. This can either be a single role as a string, or a list of role names.
-
users
(str or list
) –One or more users who will receive object-level roles. This can either be a single username as a string or a list of usernames.
Raises:
-
ObjectDoesNotExist
–If any of the users do not exist.
add_roles_for_groups(roles, groups)
¶
Adds object-level roles for one or more groups for this newly created object.
Parameters:
-
roles
(str or list
) –One or more object-level roles to be added for the groups. This can either be a single role as a string, or list of role names.
-
groups
(str or list
) –One or more groups who will receive object-level roles. This can either be a single group name as a string or a list of group names.
Raises:
-
ObjectDoesNotExist
–If any of the groups do not exist.
add_roles_for_object_creator(roles)
¶
Adds object-level roles for the user creating the newly created object.
If the get_current_authenticated_user
returns None because the API client did not
provide authentication credentials, no permissions are added and this passes silently.
This allows endpoints which create objects and do not require authorization to execute
without error.
Parameters:
-
roles
(list or str
) –One or more roles to be added at the object-level for the user. This can either be a single role as a string, or list of role names.