@@ -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
0 commit comments