Skip to content

Commit

Permalink
Merge pull request #3219 from kobotoolbox/3218-implied-add-submission…
Browse files Browse the repository at this point in the history
…-permission

Assigning "Change submissions" implies "Add submissions"
  • Loading branch information
joshuaberetta authored May 19, 2021
2 parents 8dccba4 + 1e943da commit 8d3b938
Show file tree
Hide file tree
Showing 9 changed files with 29 additions and 22 deletions.
2 changes: 1 addition & 1 deletion jsapp/js/actions.es6
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ actions.resources.duplicateSubmission.listen((uid, sid, duplicatedSubmission) =>
actions.resources.loadAsset({id: uid});
})
.fail((response) => {
alertify.error(t('Failed to duplicate submisson'));
alertify.error(t('Failed to duplicate submission'));
actions.resources.duplicateSubmission.failed(response);
});
});
Expand Down
2 changes: 1 addition & 1 deletion jsapp/js/components/assetrow.es6
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ class AssetRow extends React.Component {
{ this.props.asset_type == ASSET_TYPES.survey.id &&
<bem.AssetRow__cell
m={'submission-count'}
key={'submisson-count'}
key={'submission-count'}
className='mdl-cell mdl-cell--1-col mdl-cell--1-col-tablet mdl-cell--1-col-phone'
>
{
Expand Down
1 change: 0 additions & 1 deletion jsapp/js/components/modalForms/submission.es6
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,6 @@ class Submission extends React.Component {
}

{this.userCan('change_submissions', this.props.asset) &&
this.userCan('add_submissions', this.props.asset) &&
<a
onClick={this.duplicateSubmission.bind(this)}
className='kobo-button kobo-button--blue submission-duplicate__button'
Expand Down
3 changes: 2 additions & 1 deletion jsapp/js/components/permissions/permissionsMocks.es6
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ const permissions = {
'codename': 'change_submissions',
'implied': [
'/api/v2/permissions/view_asset/',
'/api/v2/permissions/view_submissions/'
'/api/v2/permissions/view_submissions/',
'/api/v2/permissions/add_submissions/'
],
'contradictory': [
'/api/v2/permissions/partial_submissions/'
Expand Down
6 changes: 6 additions & 0 deletions jsapp/js/components/permissions/userAssetPermsEditor.es6
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,12 @@ class UserAssetPermsEditor extends React.Component {
stateObj.formViewDisabled = true;
}

// checking `submissionsEdit` implies having `submissionsAdd` checked
if (stateObj.submissionsEdit) {
stateObj.submissionsAdd = true;
stateObj.submissionsAddDisabled = true;
}

// checking these options implies having `submissionsView` checked
if (
stateObj.submissionsDelete ||
Expand Down
5 changes: 4 additions & 1 deletion kpi/models/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,10 @@ class Meta:
PERM_ADD_SUBMISSIONS: (PERM_VIEW_ASSET,),
PERM_VIEW_SUBMISSIONS: (PERM_VIEW_ASSET,),
PERM_PARTIAL_SUBMISSIONS: (PERM_VIEW_ASSET,),
PERM_CHANGE_SUBMISSIONS: (PERM_VIEW_SUBMISSIONS,),
PERM_CHANGE_SUBMISSIONS: (
PERM_VIEW_SUBMISSIONS,
PERM_ADD_SUBMISSIONS,
),
PERM_DELETE_SUBMISSIONS: (PERM_VIEW_SUBMISSIONS,),
PERM_VALIDATE_SUBMISSIONS: (PERM_VIEW_SUBMISSIONS,),
}
Expand Down
5 changes: 1 addition & 4 deletions kpi/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,10 +262,7 @@ class EditSubmissionPermission(SubmissionPermission):
class DuplicateSubmissionPermission(SubmissionPermission):
perms_map = {
'GET': ['%(app_label)s.view_%(model_name)s'],
'POST': [
'%(app_label)s.add_%(model_name)s',
'%(app_label)s.change_%(model_name)s',
],
'POST': ['%(app_label)s.change_%(model_name)s'],
}


Expand Down
14 changes: 3 additions & 11 deletions kpi/tests/api/v2/test_api_submissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -533,11 +533,12 @@ def test_duplicate_submission_by_anotheruser_shared_view_only_not_allowed(self):
response = self.client.post(self.submission_url, {'format': 'json'})
assert response.status_code == status.HTTP_403_FORBIDDEN

def test_duplicate_submission_by_anotheruser_shared_change_not_allowed(self):
def test_duplicate_submission_by_anotheruser_shared_as_editor_allowed(self):
self.asset.assign_perm(self.anotheruser, PERM_CHANGE_SUBMISSIONS)
self._log_in_as_another_user()
response = self.client.post(self.submission_url, {'format': 'json'})
assert response.status_code == status.HTTP_403_FORBIDDEN
assert response.status_code == status.HTTP_201_CREATED
self._check_duplicate(response)

def test_duplicate_submission_by_anotheruser_shared_add_not_allowed(self):
for perm in [PERM_VIEW_SUBMISSIONS, PERM_ADD_SUBMISSIONS]:
Expand All @@ -546,15 +547,6 @@ def test_duplicate_submission_by_anotheruser_shared_add_not_allowed(self):
response = self.client.post(self.submission_url, {'format': 'json'})
assert response.status_code == status.HTTP_403_FORBIDDEN

def test_duplicate_submission_by_anotheruser_shared_add_and_change_allowed(self):
# user needs both `add_submissions` and `change_submissions` permissions
for perm in [PERM_CHANGE_SUBMISSIONS, PERM_ADD_SUBMISSIONS]:
self.asset.assign_perm(self.anotheruser, perm)
self._log_in_as_another_user()
response = self.client.post(self.submission_url, {'format': 'json'})
assert response.status_code == status.HTTP_201_CREATED
self._check_duplicate(response)


class BulkUpdateSubmissionsApiTests(BaseSubmissionTestCase):

Expand Down
13 changes: 11 additions & 2 deletions kpi/tests/test_permissions.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# coding: utf-8
import unittest
from django.contrib.auth.models import User, AnonymousUser
from django.test import TestCase

Expand Down Expand Up @@ -256,7 +257,11 @@ def test_implied_asset_grant_permissions(self):
PERM_CHANGE_ASSET: (PERM_VIEW_ASSET,),
PERM_ADD_SUBMISSIONS: (PERM_VIEW_ASSET,),
PERM_VIEW_SUBMISSIONS: (PERM_VIEW_ASSET,),
PERM_CHANGE_SUBMISSIONS: (PERM_VIEW_ASSET, PERM_VIEW_SUBMISSIONS),
PERM_CHANGE_SUBMISSIONS: (
PERM_VIEW_ASSET,
PERM_VIEW_SUBMISSIONS,
PERM_ADD_SUBMISSIONS,
),
PERM_VALIDATE_SUBMISSIONS: (PERM_VIEW_ASSET, PERM_VIEW_SUBMISSIONS),
}
asset = self.admin_asset
Expand Down Expand Up @@ -293,6 +298,7 @@ def test_remove_implied_asset_permissions(self):
PERM_VIEW_ASSET,
PERM_VIEW_SUBMISSIONS,
PERM_CHANGE_SUBMISSIONS,
PERM_ADD_SUBMISSIONS,
]
self.assertListEqual(
sorted(asset.get_perms(grantee)), sorted(expected_perms)
Expand Down Expand Up @@ -394,7 +400,7 @@ def test_contradict_implied_asset_deny_permissions(self):
)
expected_perms = [
# codename, deny
(PERM_ADD_SUBMISSIONS, True),
(PERM_ADD_SUBMISSIONS, False),
(PERM_CHANGE_ASSET, True),
(PERM_CHANGE_SUBMISSIONS, False),
(PERM_DELETE_SUBMISSIONS, True),
Expand Down Expand Up @@ -473,6 +479,7 @@ def test_calculated_submission_editor_permissions(self):
grantee = self.someuser
asset = self.admin_asset
submission_editor_permissions = [
PERM_ADD_SUBMISSIONS,
PERM_CHANGE_SUBMISSIONS,
PERM_VIEW_ASSET,
PERM_VIEW_SUBMISSIONS,
Expand Down Expand Up @@ -715,6 +722,8 @@ def test_remove_partial_submission_permission(self):
self.assertFalse(grantee.has_perm(PERM_PARTIAL_SUBMISSIONS, asset))
self.assertTrue(asset.asset_partial_permissions.count() == 0)

@unittest.skip(reason='Skip until this branch is merged within '
'`3115-allowed-write-actions-with-partial-perm`')
def test_implied_partial_submission_permission(self):
"""
This test is present even though we can only restrict users to view
Expand Down

0 comments on commit 8d3b938

Please sign in to comment.