Skip to content

Commit cd286f2

Browse files
authored
Merge pull request #11339 from ihorsokhanexoft/feature/ENG-9022
## Purpose Anyone can duplicate public projects (structure only) but should be a contributor for a private project ## Changes Updated if statement ## Ticket https://openscience.atlassian.net/browse/ENG-9022
2 parents 09397dd + 29e8cd7 commit cd286f2

File tree

2 files changed

+92
-20
lines changed

2 files changed

+92
-20
lines changed

api/nodes/serializers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -787,7 +787,7 @@ def create(self, validated_data):
787787
template_node = Node.load(template_from)
788788
if template_node is None:
789789
raise exceptions.NotFound
790-
if not template_node.has_permission(user, osf_permissions.READ, check_parent=False):
790+
if not template_node.is_public and not template_node.is_contributor(user):
791791
raise exceptions.PermissionDenied
792792
validated_data.pop('creator')
793793
changed_data = {template_from: validated_data}

api_tests/nodes/views/test_node_list.py

Lines changed: 91 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1477,25 +1477,6 @@ def test_create_from_template_errors(self, app, user_one, user_two, url):
14771477
expect_errors=True)
14781478
assert res.status_code == 404
14791479

1480-
# test_403_on_create_from_template_of_unauthorized_project
1481-
template_from = ProjectFactory(creator=user_two, is_public=True)
1482-
templated_project_data = {
1483-
'data': {
1484-
'type': 'nodes',
1485-
'attributes':
1486-
{
1487-
'title': 'No permission',
1488-
'category': 'project',
1489-
'template_from': template_from._id,
1490-
}
1491-
}
1492-
}
1493-
res = app.post_json_api(
1494-
url, templated_project_data,
1495-
auth=user_one.auth,
1496-
expect_errors=True)
1497-
assert res.status_code == 403
1498-
14991480
def test_creates_project_from_template(self, app, user_one, category, url):
15001481
template_from = ProjectFactory(creator=user_one, is_public=True)
15011482
template_component = ProjectFactory(
@@ -1527,6 +1508,97 @@ def test_creates_project_from_template(self, app, user_one, category, url):
15271508
assert len(new_project.nodes) == len(template_from.nodes)
15281509
assert new_project.nodes[0].title == template_component.title
15291510

1511+
def test_non_contributor_create_project_from_public_template_success(self, app, user_one, category, url):
1512+
template_from = ProjectFactory(creator=user_one, is_public=True)
1513+
user_without_permissions = AuthUserFactory()
1514+
templated_project_data = {
1515+
'data': {
1516+
'type': 'nodes',
1517+
'attributes':
1518+
{
1519+
'title': 'template from project',
1520+
'category': category,
1521+
'template_from': template_from._id,
1522+
}
1523+
}
1524+
}
1525+
res = app.post_json_api(
1526+
url, templated_project_data,
1527+
auth=user_without_permissions.auth
1528+
)
1529+
assert res.status_code == 201
1530+
1531+
def test_non_contributor_create_project_from_private_template_no_permission_fails(self, app, user_one, category, url):
1532+
template_from = ProjectFactory(creator=user_one, is_public=False)
1533+
user_without_permissions = AuthUserFactory()
1534+
templated_project_data = {
1535+
'data': {
1536+
'type': 'nodes',
1537+
'attributes':
1538+
{
1539+
'title': 'template from project',
1540+
'category': category,
1541+
'template_from': template_from._id,
1542+
}
1543+
}
1544+
}
1545+
res = app.post_json_api(
1546+
url, templated_project_data,
1547+
auth=user_without_permissions.auth,
1548+
expect_errors=True
1549+
)
1550+
assert res.status_code == 403
1551+
1552+
def test_contributor_create_project_from_private_template_with_permission_success(self, app, user_one, category, url):
1553+
template_from = ProjectFactory(creator=user_one, is_public=False)
1554+
user_without_permissions = AuthUserFactory()
1555+
template_from.add_contributor(user_without_permissions, permissions=permissions.READ, auth=Auth(user_one), save=True)
1556+
templated_project_data = {
1557+
'data': {
1558+
'type': 'nodes',
1559+
'attributes':
1560+
{
1561+
'title': 'template from project',
1562+
'category': category,
1563+
'template_from': template_from._id,
1564+
}
1565+
}
1566+
}
1567+
res = app.post_json_api(
1568+
url, templated_project_data,
1569+
auth=user_without_permissions.auth
1570+
)
1571+
assert res.status_code == 201
1572+
assert template_from.has_permission(user_without_permissions, permissions.READ)
1573+
1574+
template_from.update_contributor(
1575+
user_without_permissions,
1576+
permission=permissions.WRITE,
1577+
auth=Auth(user_one),
1578+
save=True,
1579+
visible=True
1580+
)
1581+
res = app.post_json_api(
1582+
url, templated_project_data,
1583+
auth=user_without_permissions.auth
1584+
)
1585+
assert res.status_code == 201
1586+
assert template_from.has_permission(user_without_permissions, permissions.WRITE)
1587+
1588+
template_from.update_contributor(
1589+
user_without_permissions,
1590+
permission=permissions.ADMIN,
1591+
auth=Auth(user_one),
1592+
save=True,
1593+
visible=True
1594+
)
1595+
res = app.post_json_api(
1596+
url, templated_project_data,
1597+
auth=user_without_permissions.auth
1598+
)
1599+
assert res.status_code == 201
1600+
assert template_from.has_permission(user_without_permissions, permissions.ADMIN)
1601+
15301602
def test_creates_project_creates_project_and_sanitizes_html(
15311603
self, app, user_one, category, url):
15321604
title = '<em>Cool</em> <strong>Project</strong>'

0 commit comments

Comments
 (0)