Skip to content

Commit 1ea697f

Browse files
ajrbyersmauromsl
authored andcommitted
fix: allow section editors to access typesetting/galley views for assigned articles
1 parent 87e6651 commit 1ea697f

2 files changed

Lines changed: 137 additions & 2 deletions

File tree

src/security/decorators.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -507,15 +507,34 @@ def typesetting_user_or_production_user_or_editor_required(func):
507507

508508
@base_check_required
509509
def wrapper(request, *args, **kwargs):
510+
article_id = kwargs.get("article_id", None)
511+
galley_id = kwargs.get("galley_id", None)
512+
510513
if (
511514
request.user.is_typesetter(request)
512515
or request.user.is_production(request)
513516
or request.user.is_editor(request)
514517
or request.user.is_staff
515518
):
516519
return func(request, *args, **kwargs)
517-
else:
518-
deny_access(request)
520+
521+
elif article_id:
522+
article = get_object_or_404(
523+
models.Article,
524+
pk=article_id,
525+
journal=request.journal,
526+
)
527+
if request.user in article.section_editors():
528+
return func(request, *args, **kwargs)
529+
elif galley_id:
530+
galley = get_object_or_404(
531+
core_models.Galley,
532+
pk=galley_id,
533+
)
534+
if request.user in galley.article.section_editors():
535+
return func(request, *args, **kwargs)
536+
537+
deny_access(request)
519538

520539
return wrapper
521540

src/security/test_security.py

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3851,6 +3851,117 @@ def test_section_editor_production_no_or_bad_article_id(self):
38513851
with self.assertRaises(PermissionDenied):
38523852
decorated_func(request, **bad_kwargs)
38533853

3854+
def test_typesetting_user_or_production_user_or_editor_required_section_editor_article_id(
3855+
self,
3856+
):
3857+
func = Mock()
3858+
decorated_func = (
3859+
decorators.typesetting_user_or_production_user_or_editor_required(
3860+
func,
3861+
)
3862+
)
3863+
kwargs = {
3864+
"article_id": self.article_in_production.pk,
3865+
}
3866+
3867+
success_request = self.prepare_request_with_user(
3868+
self.section_editor,
3869+
self.journal_one,
3870+
self.press,
3871+
)
3872+
3873+
decorated_func(success_request, **kwargs)
3874+
self.assertTrue(
3875+
func.called,
3876+
"typesetting_user_or_production_user_or_editor_required wrongly "
3877+
"blocks a SE assigned to the article.",
3878+
)
3879+
3880+
fail_request = self.prepare_request_with_user(
3881+
self.second_section_editor,
3882+
self.journal_one,
3883+
self.press,
3884+
)
3885+
3886+
with self.assertRaises(PermissionDenied):
3887+
decorated_func(fail_request, **kwargs)
3888+
3889+
def test_typesetting_user_or_production_user_or_editor_required_section_editor_no_ids(
3890+
self,
3891+
):
3892+
func = Mock()
3893+
decorated_func = (
3894+
decorators.typesetting_user_or_production_user_or_editor_required(
3895+
func,
3896+
)
3897+
)
3898+
3899+
request = self.prepare_request_with_user(
3900+
self.section_editor,
3901+
self.journal_one,
3902+
self.press,
3903+
)
3904+
3905+
with self.assertRaises(PermissionDenied):
3906+
decorated_func(request)
3907+
3908+
def test_typesetting_user_or_production_user_or_editor_required_section_editor_bad_article_id(
3909+
self,
3910+
):
3911+
func = Mock()
3912+
decorated_func = (
3913+
decorators.typesetting_user_or_production_user_or_editor_required(
3914+
func,
3915+
)
3916+
)
3917+
kwargs = {
3918+
"article_id": self.article_unassigned.pk,
3919+
}
3920+
3921+
request = self.prepare_request_with_user(
3922+
self.section_editor,
3923+
self.journal_one,
3924+
self.press,
3925+
)
3926+
3927+
with self.assertRaises(PermissionDenied):
3928+
decorated_func(request, **kwargs)
3929+
3930+
def test_typesetting_user_or_production_user_or_editor_required_section_editor_galley_id(
3931+
self,
3932+
):
3933+
func = Mock()
3934+
decorated_func = (
3935+
decorators.typesetting_user_or_production_user_or_editor_required(
3936+
func,
3937+
)
3938+
)
3939+
kwargs = {
3940+
"galley_id": self.article_in_production_galley.pk,
3941+
}
3942+
3943+
success_request = self.prepare_request_with_user(
3944+
self.section_editor,
3945+
self.journal_one,
3946+
self.press,
3947+
)
3948+
3949+
decorated_func(success_request, **kwargs)
3950+
self.assertTrue(
3951+
func.called,
3952+
"typesetting_user_or_production_user_or_editor_required wrongly "
3953+
"blocks a SE accessing a galley for their assigned article.",
3954+
)
3955+
3956+
fail_request = self.prepare_request_with_user(
3957+
self.second_section_editor,
3958+
self.journal_one,
3959+
self.press,
3960+
)
3961+
3962+
with self.assertRaises(PermissionDenied):
3963+
decorated_func(fail_request, **kwargs)
3964+
38543965
def test_loading_keyword_page_fail(self):
38553966
func = Mock()
38563967
decorated_func = decorators.keyword_page_enabled(func)
@@ -5197,6 +5308,11 @@ def setUpTestData(self):
51975308
)
51985309
self.production_section_editor_assignment.save()
51995310

5311+
self.article_in_production_galley = helpers.create_galley(
5312+
article=self.article_in_production,
5313+
label="HTML",
5314+
)
5315+
52005316
self.article_editor_copyediting = submission_models.Article(
52015317
owner=self.regular_user,
52025318
title="A Test Article",

0 commit comments

Comments
 (0)