Skip to content

Commit 0d20709

Browse files
authored
Merge pull request #1369 from rcpch/mbarton/view-old-cohorts-2
Normal users can view old cohorts
2 parents 6236c62 + b970826 commit 0d20709

67 files changed

Lines changed: 1063 additions & 485 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

epilepsy12/decorator.py

Lines changed: 88 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -225,95 +225,100 @@ def wrapper(request, *args, **kwargs):
225225
return decorator
226226

227227

228-
def user_may_view_this_child():
229-
# decorator receives case_id or registration_id from view as argument.
230-
# access is granted only to users who are either:
228+
def lookup_child_if_user_has_permission(request_kwargs, user):
229+
# Guard against users with no active primary employer
230+
if not user.organisation_employer:
231+
return None
232+
233+
via_registration = lambda obj: obj.registration.case
234+
via_multiaxial_dagnosis = lambda obj: obj.multiaxial_diagnosis.registration.case
235+
via_management = lambda obj: obj.management.registration.case
236+
237+
lookup = {
238+
"registration_id": (Registration, lambda reg: reg.case),
239+
"management_id": (Management, via_registration),
240+
"investigations_id": (Investigations, via_registration),
241+
"first_paediatric_assessment_id": (FirstPaediatricAssessment, via_registration),
242+
"epilepsy_context_id": (EpilepsyContext, via_registration),
243+
"multiaxial_diagnosis_id": (MultiaxialDiagnosis, via_registration),
244+
"episode_id": (Episode, via_multiaxial_dagnosis),
245+
"syndrome_id": (Syndrome, via_multiaxial_dagnosis),
246+
"comorbidity_id": (Comorbidity, via_multiaxial_dagnosis),
247+
"antiepilepsy_medicine_id": (AntiEpilepsyMedicine, via_management),
248+
"assessment_id": (Assessment, via_registration),
249+
"case_id": (Case, lambda o: o),
250+
}
251+
252+
for key, (model, via_fn) in lookup.items():
253+
pk = request_kwargs.get(key)
254+
255+
if pk is not None:
256+
obj = model.objects.get(pk=pk)
257+
child = via_fn(obj)
258+
259+
org_filters = {
260+
"cases": child,
261+
"patient_sites__site_is_actively_involved_in_epilepsy_care": True,
262+
"patient_sites__site_is_primary_centre_of_epilepsy_care": True,
263+
# Access is sliced by trust - so members of other organisations in that trust can see data
264+
"trust": user.organisation_employer.trust,
265+
}
266+
267+
if Organisation.objects.filter(**org_filters).exists():
268+
return child
269+
270+
271+
def lookup_user_permissions_on_child(request, request_kwargs):
272+
# Lookup sub object by id and walk backwards to case.
273+
# Access is granted only to users who are either:
231274
# 1. superusers
232-
# 2. Active RCPCH audit members
233-
# 3. Active trust level users where their trust is the same as the child
275+
# 2. Active RCPCH audit members with confirmed email
276+
# 3. Active trust level users with confirmed email where their trust is the same as the child
277+
# Editing is allowed if the cohort is still open or if you are an RCPCH audit member
278+
user = request.user
279+
280+
# Check user is active and has confirmed their email (unless superuser)
281+
if not user.is_superuser and not (user.is_active and user.email_confirmed):
282+
return {
283+
"can_view": False,
284+
"can_edit": False,
285+
}
286+
287+
is_admin = user.is_rcpch_audit_team_member or user.is_rcpch_staff or user.is_superuser
288+
289+
if is_admin:
290+
return {
291+
"can_view": True,
292+
"can_edit": True,
293+
}
294+
295+
child = lookup_child_if_user_has_permission(request_kwargs, request.user)
296+
297+
if child:
298+
return {
299+
"can_view": True,
300+
"can_edit": child.editable(),
301+
}
302+
303+
return {
304+
"can_view": False,
305+
"can_edit": False,
306+
}
307+
308+
309+
def user_may_view_this_child():
234310
def decorator(view):
235311
def wrapper(request, *args, **kwargs):
236-
user = request.user
237-
if (user.is_active and user.email_confirmed) or user.is_superuser:
238-
# user is registered and active or a superuser
239-
if kwargs.get("registration_id") is not None:
240-
registration = Registration.objects.get(
241-
pk=kwargs.get("registration_id")
242-
)
243-
child = registration.case
244-
elif kwargs.get("management_id") is not None:
245-
management = Management.objects.get(pk=kwargs.get("management_id"))
246-
child = management.registration.case
247-
elif kwargs.get("investigations_id") is not None:
248-
investigations = Investigations.objects.get(
249-
pk=kwargs.get("investigations_id")
250-
)
251-
child = investigations.registration.case
252-
elif kwargs.get("first_paediatric_assessment_id") is not None:
253-
first_paediatric_assessment = FirstPaediatricAssessment.objects.get(
254-
pk=kwargs.get("first_paediatric_assessment_id")
255-
)
256-
child = first_paediatric_assessment.registration.case
257-
elif kwargs.get("epilepsy_context_id") is not None:
258-
epilepsy_context = EpilepsyContext.objects.get(
259-
pk=kwargs.get("epilepsy_context_id")
260-
)
261-
child = epilepsy_context.registration.case
262-
elif kwargs.get("multiaxial_diagnosis_id") is not None:
263-
multiaxial_diagnosis = MultiaxialDiagnosis.objects.get(
264-
pk=kwargs.get("multiaxial_diagnosis_id")
265-
)
266-
child = multiaxial_diagnosis.registration.case
267-
elif kwargs.get("episode_id") is not None:
268-
episode = Episode.objects.get(pk=kwargs.get("episode_id"))
269-
child = episode.multiaxial_diagnosis.registration.case
270-
elif kwargs.get("syndrome_id") is not None:
271-
syndrome = Syndrome.objects.get(pk=kwargs.get("syndrome_id"))
272-
child = syndrome.multiaxial_diagnosis.registration.case
273-
elif kwargs.get("comorbidity_id") is not None:
274-
comorbidity = Comorbidity.objects.get(
275-
pk=kwargs.get("comorbidity_id")
276-
)
277-
child = comorbidity.multiaxial_diagnosis.registration.case
278-
elif kwargs.get("antiepilepsy_medicine_id") is not None:
279-
antiepilepsy_medicine = AntiEpilepsyMedicine.objects.get(
280-
pk=kwargs.get("antiepilepsy_medicine_id")
281-
)
282-
child = antiepilepsy_medicine.management.registration.case
283-
elif kwargs.get("assessment_id") is not None:
284-
assessment = Assessment.objects.get(pk=kwargs.get("assessment_id"))
285-
child = assessment.registration.case
286-
elif kwargs.get("case_id") is not None:
287-
case = Case.objects.get(pk=kwargs.get("case_id"))
288-
child = case
289-
290-
if user.is_rcpch_audit_team_member:
291-
organisation = Organisation.objects.filter(
292-
cases=child,
293-
patient_sites__site_is_actively_involved_in_epilepsy_care=True,
294-
patient_sites__site_is_primary_centre_of_epilepsy_care=True,
295-
)
296-
else:
297-
# filter for object where trust (not just organisation) where case is registered is the same as that of user
298-
organisation = Organisation.objects.filter(
299-
cases=child,
300-
patient_sites__site_is_actively_involved_in_epilepsy_care=True,
301-
patient_sites__site_is_primary_centre_of_epilepsy_care=True,
302-
trust=request.user.organisation_employer.trust,
303-
)
312+
permissions = lookup_user_permissions_on_child(request, kwargs)
304313

305-
if (
306-
organisation.exists()
307-
or user.is_rcpch_audit_team_member
308-
or user.is_rcpch_staff
309-
or user.is_superuser
310-
):
311-
return view(request, *args, **kwargs)
312-
else:
313-
raise PermissionDenied()
314-
else:
314+
if request.method not in ["GET", "HEAD", "OPTIONS"] and not permissions["can_edit"]:
315315
raise PermissionDenied()
316316

317+
if permissions["can_view"]:
318+
return view(request, permissions["can_edit"], *args, **kwargs)
319+
320+
raise PermissionDenied()
321+
317322
return wrapper
318323

319324
return decorator

epilepsy12/forms_folder/case_form.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ def __init__(self, *args, **kwargs) -> None:
8787
self.organisation_id = kwargs.pop(
8888
"organisation_id", None
8989
) # This is the organisation_id
90+
can_edit = kwargs.pop("can_edit", True) # Default to True if not provided
9091

9192
# set a flag to check if this is Jersey
9293
self.is_jersey = (
@@ -98,6 +99,13 @@ def __init__(self, *args, **kwargs) -> None:
9899
super(CaseForm, self).__init__(*args, **kwargs)
99100
self.existing_nhs_number = self.instance.nhs_number
100101
self.fields["ethnicity"].widget.attrs.update({"class": "ui rcpch dropdown"})
102+
103+
# Disable all fields if user cannot edit
104+
if not can_edit:
105+
for field_name, field in self.fields.items():
106+
field.widget.attrs['disabled'] = True
107+
field.widget.attrs['readonly'] = True
108+
101109
if self.is_jersey:
102110
# this is Jersey - hide the NHS number field
103111
self.fields["nhs_number"].widget = forms.HiddenInput()

0 commit comments

Comments
 (0)