@@ -451,4 +451,40 @@ public async Task ImportFromXlsx_NoFile_ShowsErrorAndRedirectsToList()
451451 Assert . AreEqual ( "List" , redirect . ActionName ) ;
452452 importManagerMock . Verify ( i => i . Import ( It . IsAny < Stream > ( ) ) , Times . Never ) ;
453453 }
454+
455+ // --- ImportFromXlsx (security fix: ImportManager<T> upserts by an attacker-supplied Id with no
456+ // ownership check - store-scoped callers must be denied outright) ------------------------------
457+
458+ [ TestMethod ]
459+ public async Task ImportFromXlsx_StoreScope_DeniesAndNeverCallsImportManager ( )
460+ {
461+ _scopeMock . Setup ( s => s . DefaultStoreId ) . Returns ( "store-1" ) ;
462+ var importManagerMock = new Mock < Grand . Business . Core . Interfaces . ExportImport . IImportManager < Grand . Business . Core . Dto . BrandDto > > ( ) ;
463+ var fileMock = new Mock < IFormFile > ( ) ;
464+ fileMock . Setup ( f => f . Length ) . Returns ( 100 ) ;
465+
466+ var result = await _controller . ImportFromXlsx ( fileMock . Object , importManagerMock . Object ) ;
467+
468+ var redirect = result as RedirectToActionResult ;
469+ Assert . IsNotNull ( redirect ) ;
470+ Assert . AreEqual ( "List" , redirect . ActionName ) ;
471+ importManagerMock . Verify ( m => m . Import ( It . IsAny < Stream > ( ) ) , Times . Never ) ;
472+ }
473+
474+ [ TestMethod ]
475+ public async Task ImportFromXlsx_GlobalScope_CallsImportManager ( )
476+ {
477+ _scopeMock . Setup ( s => s . DefaultStoreId ) . Returns ( ( string ) null ) ;
478+ var importManagerMock = new Mock < Grand . Business . Core . Interfaces . ExportImport . IImportManager < Grand . Business . Core . Dto . BrandDto > > ( ) ;
479+ var fileMock = new Mock < IFormFile > ( ) ;
480+ fileMock . Setup ( f => f . Length ) . Returns ( 100 ) ;
481+ fileMock . Setup ( f => f . OpenReadStream ( ) ) . Returns ( Stream . Null ) ;
482+
483+ var result = await _controller . ImportFromXlsx ( fileMock . Object , importManagerMock . Object ) ;
484+
485+ var redirect = result as RedirectToActionResult ;
486+ Assert . IsNotNull ( redirect ) ;
487+ Assert . AreEqual ( "List" , redirect . ActionName ) ;
488+ importManagerMock . Verify ( m => m . Import ( It . IsAny < Stream > ( ) ) , Times . Once ) ;
489+ }
454490}
0 commit comments