plone / plone/plone.api

adopt_roles does not work as I expected

Open
#293 8 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

01 type: bug 21 status: confirmed 31 needs: help 43 lvl: complex
Dominant language
Python
Stars
101
Forks
62
Avg merge
15h 15m
Merged PRs (30d)
1

Description

I don't get what api.env.adopt_roles actually does. I expected it to either temporarily grant some roles to the current user and after executing the block restore the original roles. Alternatively I thought it might execute the block with a proxy-user that has the given roles. It seems to do neither of the two.

Testing for the roles of the current user:

>>> api.user.get_roles()
['Member']
>>> with api.env.adopt_roles(roles=['Manager']): api.user.get_roles()
['Member']
>>> execute_under_special_role(portal, 'Manager', api.user.get_roles)
['Member']

Instead I have to grant and revoke the role explicitly:

>>> api.user.get_roles()
['Member']
>>> current_user=api.user.get_current()
>>> api.user.grant_roles(user=current_user, roles=['Manager'])
>>> api.user.get_roles()
['Member', 'Manager']
>>> api.user.revoke_roles(user=current_user, roles=['Manager'])
>>> api.user.get_roles()
['Member']

Calls made within the block do not have the expected additional permissions. Here is one private item:

>>> catalog = api.portal.get_tool('portal_catalog')
>>> len(catalog(review_state='private'))
0
>>> len(catalog.unrestrictedSearchResults(review_state='private'))
1

adopt_roles does not grant access to the private item:

>>> with api.env.adopt_roles(roles=['Manager']): len(catalog(review_state='private'))
0

Even granting roles does not work during the same request. Only in the next request the results are found.

>>> api.user.grant_roles(user=current_user, roles=['Manager'])
>>> len(catalog(review_state='private'))
0

Next request:

>>> len(catalog(review_state='private'))
1

Only execute_under_special_role (from http://docs.plone.org/develop/plone/security/permissions.html#bypassing-permission-checks) allows access to otherwise inaccessible content in the same request:

>>> len(execute_under_special_role(portal, 'Manager', catalog, review_state='private'))
1

Is that the intended behavior? If yes the docs should really explain what adopt_roles actually does.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the api.env.adopt_roles entry point and the security/permissions documentation linked in the issue. Compare its documented contract with the catalog examples and execute_under_special_role behavior; done means the intended semantics and same-request permission behavior are clearly documented.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
api, documentation, security
Issue type
Documentation
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.