The previous test ensured that a permission whose has_permission returned
False but didn't implement has_object_permission didn't cause an OR to
suceed regardless of other conditions. However, if a permission doesn't
implement has_object_permission but has_permission returns True, that should
count as having permission on all objects.
Previously has_object_permission defaulted to returning True when
unimplemented because it was assumed that has_permission had already returned
true, but when composed with OR, this might not be the case. Take for example
the case where you want an object to be accessible by the user that created it
or any admin. If you have a permission IsOwner that implements
has_object_permission and IsAdminUser which doesn't, then if you OR them
together an have a user that is neither the owner nor the admin they should
get denied but instead IsOwner will pass has_permission and IsAdminUser will
pass has_object_permission even though it didn't pass has_permission.
One solution would be to default has_object_permission to calling
has_permission but that would potentially cause redundant database lookups.
Alternatively this could be done only in the OR class, but the redundant
calls will still happen.
Also, incorrect behavior can still occur using more complicated compositions
including NOT. For example, the IsOwner permission above only implemented
has_object_permission and not has_permission, but ~IsOwner will always fail,
even on objects that the authenticated user doesn't own, because the default
True from BasePermission.has_permission() will also be inverted.
My solution is to be more explicit about when a permission subclass doesn't
implement has_permission or has_object_permission by returning NotImplemented.
NotImplemented is truthy in a boolean context, so by default everything will
continue to work the same as long as code is not expecting the result to
literally be True or False. I modified AND and OR so that if one side returns
NotImplemented, it defers to the other. If both sides return NotImplemented,
NotImplmented will be returned to propogate upwards. NOT will also propagate
NotImplmented instead of inverting it. If NotImplemented propagates
all the way up to APIView.check_permissions or
APIView.check_object_permissions, it is considered a pass (truthy).
* Add distinction between request and response serializers
* Add docs
* document new functions in schemas.md
* add a test case for different request vs response objects
* Correct formatting for flake8
Co-authored-by: Shaun Gosse <shaun.gosse@emburse.com>
* Use `--strict-markers` instead of `--strict`, as per this warning:
```
/.../_pytest/config/__init__.py:1183: PytestDeprecationWarning: The --strict option is deprecated, use --strict-markers instead.
```
* Remove config option 'testspath' - pytest is logging a warning about this being unknown:
```
/.../_pytest/config/__init__.py:1233: PytestConfigWarning: Unknown config option: testspath
```
I can't find any reference to it in the pytest docs or changelog.
The template has not been maintained for six years, so it's out of date on versions and various "best practices" (e.g. pre-commit). I also think any template should be documented on its own repo rather than here, especially if it's not an official maintained project.
The contributing guide from `docs/community/contributing.md` was copy-pasted to `CONTRIBUTING.md` and the two have drifted apart over time. The docs page seems to have been updated a bit more so let's leave only that version.
HTML responses generated by the Browsable API otherwise generate
inconsistent ETAGs -- due to the presence of CSRF tokens in the response
-- even when the API is read-only, (and as such when the response
contains no resource-modifying forms, i.e. neither POST nor PUT forms,
which might require the CSRF token).
While the template was appropriately including CSRF tokens only within
POST and PUT forms, its AJAX overlay included the CSRF token in *every*
response, regardless of whether it would be needed.
This change brings the logic of the `script` block into line with that
of the rest of the template -- and such that read-only APIs (and really
the Browsable API pages of *any* read-only resources) will not
needlessly include the CSRF token, and will now be safely cachable -- by
both back-end systems and by the user agent.
* Add failing tests for ordering filter with model property
* Fix get_default_valid_fields of OrderingFilter
* Filter model properties in get_default_valid_fields of OrderingFilter
* Fix JSONBoundField usage on nested serializers (#6211)
* Unify JSONBoundField as_form_field output between py2 and py3
When using json.dumps with indenting, in python2 the default formatting
prints whitespace after commas (,) and python3 does not. This can be
unified with the separators keyword argument.
* Document the limitation that object level permissions do not apply to object creation. See for example #6409.
* Add overview of three different ways to restrict access
* upgrade to latest version of pytest+pytest-django to eliminate dependency on six
* rollback pytest to 6.1 as py35 is dropped in 6.2
Co-authored-by: Tom Christie <tom@tomchristie.com>
This pull request adds rest-framework-actions to Third Party Packages, under Views
rest-framework-actions can be found on PyPi here: https://pypi.org/project/rest-framework-actions/
Co-authored-by: Tom Christie <tom@tomchristie.com>
* Add failing test when rendering to json a schema with timedelta
* Fix JSONOpenAPIRenderer for fields with default=timedelta()
* fix isort
* fix test for python 3.5
Co-authored-by: Pierre Chiquet <pierre.chiquet@ubikey.fr>