@@ -415,6 +415,49 @@ def test_download_with_attachment_for_anonymous(self):
415415 if resource :
416416 resource .delete ()
417417
418+ def test_cross_download (self ):
419+
420+ admin , _ = get_user_model ().objects .get_or_create (username = "admin" )
421+ user1 , _ = get_user_model ().objects .get_or_create (username = "user1" )
422+ user2 , _ = get_user_model ().objects .get_or_create (username = "user2" )
423+
424+ asset_handler = asset_handler_registry .get_default_handler ()
425+
426+ assets = []
427+ for user , file in ((user1 , ONE_JSON ), (user2 , TWO_JSON )):
428+ asset1 = asset_handler .create (
429+ title = "Test Asset1" ,
430+ description = "Description of test asset" ,
431+ type = "NeverMind" ,
432+ owner = user1 ,
433+ files = [file ],
434+ clone_files = True ,
435+ )
436+ asset1 .save ()
437+ self .assertIsInstance (asset1 , LocalAsset )
438+ assets .append (asset1 )
439+
440+ # check that user1 can access file1
441+ self .client .force_login (user1 )
442+
443+ args = {"pk" : assets [0 ].pk , "path" : "one.json" }
444+ url = reverse ("assets-link" , kwargs = args )
445+ response = self .client .get (url )
446+ self .assertEqual (response .status_code , 200 )
447+
448+ # check that user1 can NOT access file2 using asset1 link/download
449+ a2path = assets [1 ].location [0 ]
450+ logger .debug (f"Asset path { a2path } " )
451+ a2dir = a2path .split ("/" )[- 2 ]
452+ logger .debug (f"Asset dir { a2dir } " )
453+ forged_path = f"../{ a2dir } /two.json" # path will be automatically urlencoded into "%2e%2e%2f{a2dir}%2ftwo.json"
454+
455+ args = {"pk" : assets [0 ].pk , "path" : forged_path }
456+ url = reverse ("assets-link" , kwargs = args )
457+ logger .debug (f"Reverse link URL is { url } " )
458+ response = self .client .get (url )
459+ self .assertEqual (response .status_code , 400 )
460+
418461 def _setup_test (self , u , _file = ONE_JSON ):
419462 asset_handler = asset_handler_registry .get_default_handler ()
420463 asset = asset_handler .create (
0 commit comments