Skip to content

Commit 0a39ffe

Browse files
committed
Switch require_role to require_permission
For the `StaffAreaAdministrator` role. This does not remove all checks on the role for staff area access, since there is also `has_role` which we'll update. This removes all users of `require_role` which we can now remove.
1 parent f79540d commit 0a39ffe

File tree

17 files changed

+86
-95
lines changed

17 files changed

+86
-95
lines changed

jobserver/authorization/decorators.py

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from django.core.exceptions import PermissionDenied
44

55
from .permissions import backend_manage
6-
from .utils import has_permission, has_role
6+
from .utils import has_permission
77

88

99
def require_permission(permission):
@@ -26,20 +26,4 @@ def wrapper_require_role(request, *args, **kwargs):
2626
return decorator_require_permission
2727

2828

29-
def require_role(role):
30-
"""Decorator for views which require a given Role"""
31-
32-
def decorator_require_role(f): # sigh
33-
@wraps(f)
34-
def wrapper_require_role(request, *args, **kwargs):
35-
if not has_role(request.user, role):
36-
raise PermissionDenied
37-
38-
return f(request, *args, **kwargs)
39-
40-
return wrapper_require_role
41-
42-
return decorator_require_role
43-
44-
4529
require_manage_backends = require_permission(backend_manage)

staff/views/applications.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@
1313
from applications.models import Application
1414
from applications.wizard import Wizard
1515
from jobserver.actions import projects
16-
from jobserver.authorization import StaffAreaAdministrator
17-
from jobserver.authorization.decorators import require_role
16+
from jobserver.authorization.decorators import require_permission
17+
from jobserver.authorization.permissions import staff_area_access
1818
from jobserver.hash_utils import unhash, unhash_or_404
1919
from jobserver.models import Org, Project, User
2020

2121
from ..forms import ApplicationApproveForm
2222

2323

24-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
24+
@method_decorator(require_permission(staff_area_access), name="dispatch")
2525
class ApplicationApprove(FormView):
2626
form_class = ApplicationApproveForm
2727
model = Application
@@ -97,7 +97,7 @@ def get_initial(self):
9797
return initial
9898

9999

100-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
100+
@method_decorator(require_permission(staff_area_access), name="dispatch")
101101
class ApplicationDetail(View):
102102
def dispatch(self, request, *args, **kwargs):
103103
self.application = get_object_or_404(
@@ -144,7 +144,7 @@ def post(self, request, *args, **kwargs):
144144
return redirect("staff:application-detail", self.application.pk_hash)
145145

146146

147-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
147+
@method_decorator(require_permission(staff_area_access), name="dispatch")
148148
class ApplicationEdit(UpdateView):
149149
fields = [
150150
"status",
@@ -176,7 +176,7 @@ def get_success_url(self):
176176
return self.object.get_staff_url()
177177

178178

179-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
179+
@method_decorator(require_permission(staff_area_access), name="dispatch")
180180
class ApplicationList(ListView):
181181
response_class = TemplateResponse
182182
ordering = "-created_at"
@@ -232,7 +232,7 @@ def get_queryset(self):
232232
return qs.distinct()
233233

234234

235-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
235+
@method_decorator(require_permission(staff_area_access), name="dispatch")
236236
class ApplicationRemove(View):
237237
def post(self, request, *args, **kwargs):
238238
application = get_object_or_404(
@@ -255,7 +255,7 @@ def post(self, request, *args, **kwargs):
255255
return redirect("staff:application-list")
256256

257257

258-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
258+
@method_decorator(require_permission(staff_area_access), name="dispatch")
259259
class ApplicationRestore(View):
260260
def post(self, request, *args, **kwargs):
261261
application = get_object_or_404(

staff/views/dashboards/copiloting.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
from django.utils.decorators import method_decorator
1010
from django.views.generic import TemplateView
1111

12-
from jobserver.authorization import StaffAreaAdministrator
13-
from jobserver.authorization.decorators import require_role
12+
from jobserver.authorization.decorators import require_permission
13+
from jobserver.authorization.permissions import staff_area_access
1414
from jobserver.github import GitHubError, _get_github_api
1515
from jobserver.models import Project, ReleaseFile, Repo
1616

@@ -78,7 +78,7 @@ def build_repos_by_project(projects, get_github_api=_get_github_api):
7878
return {p.pk: [r for r in repos if r["pk"] in p.repo_ids] for p in projects}
7979

8080

81-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
81+
@method_decorator(require_permission(staff_area_access), name="dispatch")
8282
@method_decorator(csp_exempt(), name="dispatch")
8383
class Copiloting(TemplateView):
8484
get_github_api = staticmethod(_get_github_api)

staff/views/dashboards/index.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
from django.utils.decorators import method_decorator
22
from django.views.generic import TemplateView
33

4-
from jobserver.authorization import StaffAreaAdministrator
5-
from jobserver.authorization.decorators import require_role
4+
from jobserver.authorization.decorators import require_permission
5+
from jobserver.authorization.permissions import staff_area_access
66

77

8-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
8+
@method_decorator(require_permission(staff_area_access), name="dispatch")
99
class DashboardIndex(TemplateView):
1010
template_name = "staff/dashboards/index.html"

staff/views/dashboards/projects.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
from django.utils.decorators import method_decorator
77
from django.views.generic import TemplateView
88

9-
from jobserver.authorization import StaffAreaAdministrator
10-
from jobserver.authorization.decorators import require_role
9+
from jobserver.authorization.decorators import require_permission
10+
from jobserver.authorization.permissions import staff_area_access
1111
from jobserver.models import Org, Project, ReleaseFile
1212

1313

14-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
14+
@method_decorator(require_permission(staff_area_access), name="dispatch")
1515
@method_decorator(csp_exempt(), name="dispatch")
1616
class ProjectsDashboard(TemplateView):
1717
template_name = "staff/dashboards/projects.html"

staff/views/dashboards/repos.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@
1010
from django.utils.decorators import method_decorator
1111
from django.views.generic import View
1212

13-
from jobserver.authorization import StaffAreaAdministrator
14-
from jobserver.authorization.decorators import require_role
13+
from jobserver.authorization.decorators import require_permission
14+
from jobserver.authorization.permissions import staff_area_access
1515
from jobserver.github import _get_github_api
1616
from jobserver.models import Project, Repo, Workspace
1717

1818

1919
logger = structlog.get_logger(__name__)
2020

2121

22-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
22+
@method_decorator(require_permission(staff_area_access), name="dispatch")
2323
class PrivateReposDashboard(View):
2424
get_github_api = staticmethod(_get_github_api)
2525

@@ -147,7 +147,7 @@ def select(repo):
147147
)
148148

149149

150-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
150+
@method_decorator(require_permission(staff_area_access), name="dispatch")
151151
class ReposWithMultipleProjects(View):
152152
@csp_exempt()
153153
def get(self, request, *args, **kwargs):

staff/views/index.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
from django.views.generic import View
88

99
from applications.models import Application
10-
from jobserver.authorization import StaffAreaAdministrator
11-
from jobserver.authorization.decorators import require_role
10+
from jobserver.authorization.decorators import require_permission
11+
from jobserver.authorization.permissions import staff_area_access
1212
from jobserver.models import Backend, Org, Project, User, Workspace
1313

1414

@@ -95,7 +95,7 @@ def get_results(q):
9595
return list(itertools.chain.from_iterable(queries))
9696

9797

98-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
98+
@method_decorator(require_permission(staff_area_access), name="dispatch")
9999
class Index(View):
100100
def get(self, request, *args, **kwargs):
101101
q = self.request.GET.get("q")

staff/views/job_requests.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,16 @@
44
from django.views.generic import DetailView, ListView
55

66
from jobserver.authorization import StaffAreaAdministrator
7-
from jobserver.authorization.decorators import require_role
7+
from jobserver.authorization.decorators import require_permission
8+
from jobserver.authorization.permissions import staff_area_access
89
from jobserver.authorization.utils import has_role
910
from jobserver.models import Backend, JobRequest, Org, Project, User, Workspace
1011
from jobserver.views.job_requests import JobRequestCancel as BaseJobRequestCancel
1112

1213
from .qwargs_tools import qwargs
1314

1415

15-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
16+
@method_decorator(require_permission(staff_area_access), name="dispatch")
1617
class JobRequestCancel(BaseJobRequestCancel):
1718
def user_has_permission_to_cancel(self, request):
1819
return has_role(request.user, StaffAreaAdministrator)
@@ -21,14 +22,14 @@ def redirect(self):
2122
return redirect(self.job_request.get_staff_url())
2223

2324

24-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
25+
@method_decorator(require_permission(staff_area_access), name="dispatch")
2526
class JobRequestDetail(DetailView):
2627
context_object_name = "job_request"
2728
model = JobRequest
2829
template_name = "staff/job_request/detail.html"
2930

3031

31-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
32+
@method_decorator(require_permission(staff_area_access), name="dispatch")
3233
class JobRequestList(ListView):
3334
ordering = "-created_at"
3435
paginate_by = 25

staff/views/orgs.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,17 @@
99
from django_htmx.http import HttpResponseClientRedirect
1010
from furl import furl
1111

12-
from jobserver.authorization import StaffAreaAdministrator, permissions
13-
from jobserver.authorization.decorators import require_permission, require_role
12+
from jobserver.authorization import permissions
13+
from jobserver.authorization.decorators import require_permission
14+
from jobserver.authorization.permissions import staff_area_access
1415
from jobserver.models import Org, OrgMembership, User
1516

1617
from ..forms import OrgAddGitHubOrgForm, OrgAddMemberForm
1718
from ..htmx_tools import get_redirect_url
1819
from .qwargs_tools import qwargs
1920

2021

21-
@require_role(StaffAreaAdministrator)
22+
@require_permission(staff_area_access)
2223
def org_add_github_org(request, slug):
2324
org = get_object_or_404(Org, slug=slug)
2425

@@ -83,7 +84,7 @@ def get_template_names(self):
8384
return [template_name]
8485

8586

86-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
87+
@method_decorator(require_permission(staff_area_access), name="dispatch")
8788
class OrgDetail(FormView):
8889
form_class = OrgAddMemberForm
8990
template_name = "staff/org/detail.html"
@@ -126,7 +127,7 @@ def get_initial(self):
126127
}
127128

128129

129-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
130+
@method_decorator(require_permission(staff_area_access), name="dispatch")
130131
class OrgEdit(UpdateView):
131132
fields = [
132133
"name",
@@ -158,7 +159,7 @@ def form_valid(self, form):
158159
return redirect(new.get_staff_url())
159160

160161

161-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
162+
@method_decorator(require_permission(staff_area_access), name="dispatch")
162163
class OrgList(ListView):
163164
queryset = Org.objects.order_by("name")
164165
paginate_by = 25
@@ -181,7 +182,7 @@ def get_queryset(self):
181182
return qs.distinct()
182183

183184

184-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
185+
@method_decorator(require_permission(staff_area_access), name="dispatch")
185186
class OrgRemoveGitHubOrg(View):
186187
def post(self, request, *args, **kwargs):
187188
org = get_object_or_404(Org, slug=self.kwargs["slug"])
@@ -199,7 +200,7 @@ def post(self, request, *args, **kwargs):
199200
return redirect(org.get_staff_url())
200201

201202

202-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
203+
@method_decorator(require_permission(staff_area_access), name="dispatch")
203204
class OrgRemoveMember(View):
204205
def post(self, request, *args, **kwargs):
205206
org = get_object_or_404(Org, slug=self.kwargs["slug"])

staff/views/projects.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
from jobserver.actions import project_members as members
1818
from jobserver.actions import projects
1919
from jobserver.auditing.presenters.lookup import get_presenter
20-
from jobserver.authorization import StaffAreaAdministrator
21-
from jobserver.authorization.decorators import require_role
20+
from jobserver.authorization.decorators import require_permission
21+
from jobserver.authorization.permissions import staff_area_access
2222
from jobserver.authorization.utils import roles_for
2323
from jobserver.models import AuditableEvent, Org, Project, ProjectMembership, User
2424

@@ -32,7 +32,7 @@
3232
from .qwargs_tools import qwargs
3333

3434

35-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
35+
@method_decorator(require_permission(staff_area_access), name="dispatch")
3636
class ProjectAddMember(FormView):
3737
form_class = ProjectAddMemberForm
3838
template_name = "staff/project/membership_create.html"
@@ -72,7 +72,7 @@ def get_initial(self):
7272
}
7373

7474

75-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
75+
@method_decorator(require_permission(staff_area_access), name="dispatch")
7676
class ProjectAuditLog(ListView):
7777
paginate_by = 25
7878
template_name = "staff/project/audit_log.html"
@@ -109,7 +109,7 @@ def get_queryset(self):
109109
return qs.distinct()
110110

111111

112-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
112+
@method_decorator(require_permission(staff_area_access), name="dispatch")
113113
class ProjectDetail(DetailView):
114114
model = Project
115115
template_name = "staff/project/detail.html"
@@ -129,7 +129,7 @@ def get_context_data(self, **kwargs):
129129
}
130130

131131

132-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
132+
@method_decorator(require_permission(staff_area_access), name="dispatch")
133133
class ProjectEdit(UpdateView):
134134
form_class = ProjectEditForm
135135
model = Project
@@ -142,7 +142,7 @@ def form_valid(self, form):
142142
return redirect(new.get_staff_url())
143143

144144

145-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
145+
@method_decorator(require_permission(staff_area_access), name="dispatch")
146146
class ProjectLinkApplication(UpdateView):
147147
form_class = ProjectLinkApplicationForm
148148
model = Project
@@ -175,7 +175,7 @@ def get_context_data(self, **kwargs):
175175
}
176176

177177

178-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
178+
@method_decorator(require_permission(staff_area_access), name="dispatch")
179179
class ProjectList(ListView):
180180
queryset = Project.objects.order_by("-number", Lower("name"))
181181
paginate_by = 25
@@ -203,7 +203,7 @@ def get_queryset(self):
203203
return qs.distinct()
204204

205205

206-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
206+
@method_decorator(require_permission(staff_area_access), name="dispatch")
207207
class ProjectMembershipEdit(UpdateView):
208208
context_object_name = "membership"
209209
form_class = ProjectMembershipForm
@@ -244,7 +244,7 @@ def get_object(self):
244244
)
245245

246246

247-
@method_decorator(require_role(StaffAreaAdministrator), name="dispatch")
247+
@method_decorator(require_permission(staff_area_access), name="dispatch")
248248
class ProjectMembershipRemove(View):
249249
def post(self, request, *args, **kwargs):
250250
membership = get_object_or_404(

0 commit comments

Comments
 (0)