diff --git a/src/Tests/Grand.Web.Store.Tests/Controllers/ProductControllerTests.cs b/src/Tests/Grand.Web.Store.Tests/Controllers/ProductControllerTests.cs index 16845a4f6..11558b0ba 100644 --- a/src/Tests/Grand.Web.Store.Tests/Controllers/ProductControllerTests.cs +++ b/src/Tests/Grand.Web.Store.Tests/Controllers/ProductControllerTests.cs @@ -6,9 +6,11 @@ using Grand.Domain.Catalog; using Grand.Domain.Customers; using Grand.Domain.Localization; +using Grand.Domain.Permissions; using Grand.Infrastructure; using Grand.Web.AdminShared.Interfaces; using Grand.Web.AdminShared.Models.Catalog; +using Grand.Web.Common.DataSource; using Grand.Web.Common.Localization; using Grand.Web.Store.Controllers; using Microsoft.AspNetCore.Http; @@ -31,6 +33,7 @@ public class ProductControllerTests private const string OtherStoreId = "store-2"; private ProductController _controller; + private Mock _permissionServiceMock; private Mock _productServiceMock; private Mock _productViewModelServiceMock; private Mock _translationServiceMock; @@ -40,6 +43,7 @@ public void Setup() { _productServiceMock = new Mock(); _productViewModelServiceMock = new Mock(); + _permissionServiceMock = new Mock(); _translationServiceMock = new Mock(); _translationServiceMock.Setup(t => t.GetResource(It.IsAny())).Returns("resource"); @@ -61,7 +65,7 @@ public void Setup() new Mock().Object, new Mock().Object, new Mock().Object, - new Mock().Object, + _permissionServiceMock.Object, new Mock().Object); var httpContext = new DefaultHttpContext(); @@ -69,6 +73,63 @@ public void Setup() _controller.TempData = new TempDataDictionary(httpContext, new Mock().Object); } + // --- Shared helpers for the CanAccessProduct denial tests below ------------------------------- + // Every action denies access via the same rule (AclMappingExtension.AccessToEntityByStore: an + // explicit single foreign store beats the staff member's store). Centralizing the "denied product" + // shape and the per-response-type assertions keeps each of the ~60 call sites below to a few lines, + // matching the mechanical nature of the CanAccessProduct extraction itself. + + private static Product ForeignProduct(string id = "denied") + { + var product = new Product { Id = id, LimitedToStores = true }; + product.Stores.Add(OtherStoreId); + return product; + } + + private void MockAnyProductLookupAsForeign() + { + _productServiceMock.Setup(p => p.GetProductById(It.IsAny(), It.IsAny())) + .ReturnsAsync(ForeignProduct()); + } + + private void MockSkuLookupAsForeign() + { + _productServiceMock.Setup(p => p.GetProductBySku(It.IsAny())).ReturnsAsync(ForeignProduct()); + } + + private static void AssertKendoGridPermissionError(IActionResult result) + { + var json = result as JsonResult; + Assert.IsNotNull(json, "expected a JsonResult"); + var data = json.Value as DataSourceResult; + Assert.IsNotNull(data, "expected a DataSourceResult"); + Assert.AreEqual("resource", data.Errors); + } + + private static void AssertContentPermissionError(IActionResult result) + { + var content = result as ContentResult; + Assert.IsNotNull(content, "expected a ContentResult"); + Assert.AreEqual("resource", content.Content); + } + + private static void AssertJsonErrorsPermissionError(IActionResult result) + { + var json = result as JsonResult; + Assert.IsNotNull(json, "expected a JsonResult"); + var errorsProp = json.Value?.GetType().GetProperty("errors"); + Assert.IsNotNull(errorsProp, "expected an anonymous object with an 'errors' property"); + Assert.AreEqual("resource", errorsProp.GetValue(json.Value)); + } + + private static void AssertRedirectToProductList(IActionResult result) + { + var redirect = result as RedirectToActionResult; + Assert.IsNotNull(redirect, "expected a RedirectToActionResult"); + Assert.AreEqual("List", redirect.ActionName); + Assert.AreEqual("Product", redirect.ControllerName); + } + [TestMethod] public async Task Delete_ProductNotFound_RedirectsToList() { @@ -201,4 +262,1029 @@ public async Task EditGet_ProductSharedAcrossMultipleStoresIncludingStaffStore_S _productViewModelServiceMock.Verify( s => s.PrepareProductModel(It.IsAny(), product, false, false), Times.Once); } + + [TestMethod] + public async Task EditGet_ProductInSingleOtherStore_RedirectsToList() + { + // The strict branch of Edit(GET) - a product limited to exactly one store that isn't this + // staff member's - as opposed to the permissive multi-store branch tested above. + var product = new Product { Id = "p1", LimitedToStores = true }; + product.Stores.Add(OtherStoreId); + _productServiceMock.Setup(p => p.GetProductById("p1", true)).ReturnsAsync(product); + + var result = await _controller.Edit("p1"); + + var redirect = result as RedirectToActionResult; + Assert.IsNotNull(redirect); + Assert.AreEqual("List", redirect.ActionName); + _productViewModelServiceMock.Verify( + s => s.PrepareProductModel(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), + Times.Never); + } + + [TestMethod] + public async Task GoToSku_ProductNotAccessible_RedirectsToEditWithoutExposingIt() + { + MockSkuLookupAsForeign(); + + var result = await _controller.GoToSku(new ProductListModel { GoDirectlyToSku = "sku1" }); + + var redirect = result as RedirectToActionResult; + Assert.IsNotNull(redirect); + Assert.AreEqual("Edit", redirect.ActionName); + Assert.AreEqual("denied", redirect.RouteValues["id"]); + } + + [TestMethod] + public async Task LoadProductFriendlyNames_SkipsNamesOfProductsNotAccessible() + { + var owned = new Product { Id = "owned", Name = "Owned", LimitedToStores = true }; + owned.Stores.Add(StaffStoreId); + var foreign = ForeignProduct("foreign"); + foreign.Name = "Foreign"; + _productServiceMock.Setup(p => p.GetProductsByIds(new[] { "owned", "foreign" }, true)) + .ReturnsAsync(new List { owned, foreign }); + + var result = await _controller.LoadProductFriendlyNames("owned,foreign"); + + // Note: the trailing ", " is current behavior, not intentional - the separator is appended + // based on loop position ("not the last id"), not on whether a name was actually appended for + // the *previous* id. Preserved as-is; not this refactor's concern to fix. + var json = result as JsonResult; + Assert.IsNotNull(json); + var text = json.Value.GetType().GetProperty("Text")?.GetValue(json.Value) as string; + Assert.AreEqual("Owned, ", text); + } + + // --- Product categories --------------------------------------------------------------------- + + [TestMethod] + public async Task ProductCategoryList_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductCategoryList(new DataSourceRequest(), "p1"); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task ProductCategoryInsert_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductCategoryInsert(new ProductModel.ProductCategoryModel { ProductId = "p1" }); + + AssertKendoGridPermissionError(result); + _productViewModelServiceMock.Verify( + s => s.InsertProductCategoryModel(It.IsAny()), Times.Never); + } + + [TestMethod] + public async Task ProductCategoryUpdate_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductCategoryUpdate(new ProductModel.ProductCategoryModel { ProductId = "p1" }); + + AssertKendoGridPermissionError(result); + _productViewModelServiceMock.Verify( + s => s.UpdateProductCategoryModel(It.IsAny()), Times.Never); + } + + [TestMethod] + public async Task ProductCategoryDelete_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductCategoryDelete(new ProductModel.ProductCategoryModel { ProductId = "p1" }); + + AssertKendoGridPermissionError(result); + _productViewModelServiceMock.Verify( + s => s.DeleteProductCategory(It.IsAny(), It.IsAny()), Times.Never); + } + + // --- Product collections ---------------------------------------------------------------------- + + [TestMethod] + public async Task ProductCollectionList_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductCollectionList(new DataSourceRequest(), "p1"); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task ProductCollectionInsert_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductCollectionInsert(new ProductModel.ProductCollectionModel { ProductId = "p1" }); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task ProductCollectionUpdate_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductCollectionUpdate(new ProductModel.ProductCollectionModel { ProductId = "p1" }); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task ProductCollectionDelete_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductCollectionDelete(new ProductModel.ProductCollectionModel { ProductId = "p1" }); + + AssertKendoGridPermissionError(result); + } + + // --- Related products -------------------------------------------------------------------------- + + [TestMethod] + public async Task RelatedProductList_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.RelatedProductList(new DataSourceRequest(), "p1"); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task RelatedProductUpdate_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.RelatedProductUpdate(new ProductModel.RelatedProductModel { ProductId1 = "p1" }); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task RelatedProductDelete_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.RelatedProductDelete(new ProductModel.RelatedProductModel { ProductId1 = "p1" }); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task RelatedProductAddPopup_ProductNotAccessible_ReturnsContentError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.RelatedProductAddPopup(new ProductModel.AddRelatedProductModel { ProductId = "p1" }); + + AssertContentPermissionError(result); + _productViewModelServiceMock.Verify( + s => s.InsertRelatedProductModel(It.IsAny()), Times.Never); + } + + // --- Similar products --------------------------------------------------------------------------- + + [TestMethod] + public async Task SimilarProductList_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.SimilarProductList(new DataSourceRequest(), "p1"); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task SimilarProductUpdate_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.SimilarProductUpdate(new ProductModel.SimilarProductModel { ProductId1 = "p1" }); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task SimilarProductDelete_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.SimilarProductDelete(new ProductModel.SimilarProductModel { ProductId1 = "p1" }); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task SimilarProductAddPopup_ProductNotAccessible_ReturnsContentError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.SimilarProductAddPopup(new ProductModel.AddSimilarProductModel { ProductId = "p1" }); + + AssertContentPermissionError(result); + } + + // --- Bundle products ------------------------------------------------------------------------------ + + [TestMethod] + public async Task BundleProductList_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.BundleProductList(new DataSourceRequest(), "p1"); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task BundleProductUpdate_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.BundleProductUpdate(new ProductModel.BundleProductModel { ProductBundleId = "p1" }); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task BundleProductDelete_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.BundleProductDelete(new ProductModel.BundleProductModel { ProductBundleId = "p1" }); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task BundleProductAddPopup_ProductNotAccessible_ReturnsContentError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.BundleProductAddPopup(new ProductModel.AddBundleProductModel { ProductId = "p1" }); + + AssertContentPermissionError(result); + } + + // --- Cross-sell products -------------------------------------------------------------------------- + + [TestMethod] + public async Task CrossSellProductList_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.CrossSellProductList(new DataSourceRequest(), "p1"); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task CrossSellProductDelete_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.CrossSellProductDelete(new ProductModel.CrossSellProductModel { ProductId = "p1" }); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task CrossSellProductAddPopup_ProductNotAccessible_ReturnsContentError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.CrossSellProductAddPopup(new ProductModel.AddCrossSellProductModel { ProductId = "p1" }); + + AssertContentPermissionError(result); + } + + // --- Recommended products ------------------------------------------------------------------------- + + [TestMethod] + public async Task RecommendedProductList_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.RecommendedProductList(new DataSourceRequest(), "p1"); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task RecommendedProductDelete_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.RecommendedProductDelete(new ProductModel.RecommendedProductModel { ProductId = "p1" }); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task RecommendedProductAddPopup_ProductNotAccessible_ReturnsContentError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.RecommendedProductAddPopup(new ProductModel.AddRecommendedProductModel { ProductId = "p1" }); + + AssertContentPermissionError(result); + } + + // --- Associated products ---------------------------------------------------------------------------- + + [TestMethod] + public async Task AssociatedProductList_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.AssociatedProductList(new DataSourceRequest(), "p1"); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task AssociatedProductUpdate_AssociatedProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.AssociatedProductUpdate(new ProductModel.AssociatedProductModel { Id = "p1" }); + + AssertKendoGridPermissionError(result); + _productServiceMock.Verify(s => s.UpdateAssociatedProduct(It.IsAny()), Times.Never); + } + + [TestMethod] + public async Task AssociatedProductDelete_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.AssociatedProductDelete(new ProductModel.AssociatedProductModel { Id = "p1" }); + + AssertKendoGridPermissionError(result); + _productViewModelServiceMock.Verify(s => s.DeleteAssociatedProduct(It.IsAny()), Times.Never); + } + + [TestMethod] + public async Task AssociatedProductAddPopup_ParentProductNotAccessible_ReturnsContentError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.AssociatedProductAddPopup(new ProductModel.AddAssociatedProductModel { + ProductId = "p1" + }); + + AssertContentPermissionError(result); + _productViewModelServiceMock.Verify( + s => s.InsertAssociatedProductModel(It.IsAny()), Times.Never); + } + + [TestMethod] + public async Task AssociatedProductAddPopup_ParentOwnedButCandidateNotAccessible_ExcludesCandidate() + { + // The parent product is the vendor's own, but one selected candidate belongs to another + // store - AssociatedProductAddPopup filters SelectedProductIds down to only the accessible + // ones (the positive `CanAccessProduct(selected)` form) before calling InsertAssociatedProductModel. + var parent = new Product { Id = "parent", LimitedToStores = true }; + parent.Stores.Add(StaffStoreId); + _productServiceMock.Setup(p => p.GetProductById("parent", It.IsAny())).ReturnsAsync(parent); + _productServiceMock.Setup(p => p.GetProductById("foreign", It.IsAny())).ReturnsAsync(ForeignProduct("foreign")); + + var model = new ProductModel.AddAssociatedProductModel { + ProductId = "parent", + SelectedProductIds = ["foreign"] + }; + + var result = await _controller.AssociatedProductAddPopup(model); + + AssertSuccessContent(result); + _productViewModelServiceMock.Verify( + s => s.InsertAssociatedProductModel(It.IsAny()), Times.Never); + } + + private static void AssertSuccessContent(IActionResult result) + { + var content = result as ContentResult; + Assert.IsNotNull(content, "expected a ContentResult (success path, not the permission-denied one)"); + Assert.AreEqual("", content.Content); + } + + // --- Product pictures -------------------------------------------------------------------------- + // ProductPictureAdd is deliberately not covered here: reaching its CanAccessProduct check requires + // a non-empty IFormFileCollection and a prior Pictures-permission check, disproportionate setup for + // what is otherwise the same one-line condition covered everywhere else in this file. + + [TestMethod] + public async Task ProductPictureList_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductPictureList(new DataSourceRequest(), "p1"); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task ProductPicturePopupGet_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductPicturePopup("p1", "pic1"); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task ProductPicturePopupPost_ProductNotAccessible_Throws() + { + // Unlike its GET counterpart, the POST handler throws instead of returning an error response. + MockAnyProductLookupAsForeign(); + + try + { + await _controller.ProductPicturePopup(new ProductModel.ProductPictureModel { ProductId = "p1" }); + Assert.Fail("expected an ArgumentException"); + } + catch (ArgumentException) + { + // expected + } + } + + [TestMethod] + public async Task ProductPictureDelete_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductPictureDelete(new ProductModel.ProductPictureModel { ProductId = "p1" }); + + AssertKendoGridPermissionError(result); + } + + // --- Product specification attributes --------------------------------------------------------- + + [TestMethod] + public async Task ProductSpecAttrList_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductSpecAttrList(new DataSourceRequest(), "p1"); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task ProductSpecAttrPopupGet_ProductNotAccessible_ReturnsContentError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductSpecAttrPopup( + new Mock().Object, "p1", null); + + AssertContentPermissionError(result); + } + + [TestMethod] + public async Task ProductSpecAttrPopupPost_ProductNotAccessible_ReturnsContentError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductSpecAttrPopup( + new Mock().Object, + new ProductModel.AddProductSpecificationAttributeModel { ProductId = "p1" }); + + AssertContentPermissionError(result); + } + + [TestMethod] + public async Task ProductSpecAttrDelete_ProductNotAccessible_ReturnsContentError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductSpecAttrDelete(new ProductSpecificationAttributeModel { ProductId = "p1" }); + + AssertContentPermissionError(result); + } + + // --- Purchased with orders / Reviews ------------------------------------------------------------ + + [TestMethod] + public async Task PurchasedWithOrders_ProductNotAccessible_ReturnsKendoGridError() + { + _permissionServiceMock.Setup(p => p.Authorize(It.IsAny())).ReturnsAsync(true); + MockAnyProductLookupAsForeign(); + + var result = await _controller.PurchasedWithOrders(new DataSourceRequest(), "p1", + new Mock().Object); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task Reviews_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.Reviews(new DataSourceRequest(), "p1", new Mock().Object); + + AssertKendoGridPermissionError(result); + } + + // --- Bulk editing -------------------------------------------------------------------------------- + + [TestMethod] + public async Task BulkEditDelete_FiltersOutProductsNotAccessible() + { + var owned = new Product { Id = "owned", LimitedToStores = true }; + owned.Stores.Add(StaffStoreId); + _productServiceMock.Setup(p => p.GetProductById("owned", It.IsAny())).ReturnsAsync(owned); + _productServiceMock.Setup(p => p.GetProductById("foreign", It.IsAny())).ReturnsAsync(ForeignProduct("foreign")); + + var models = new List { + new() { Id = "owned" }, + new() { Id = "foreign" } + }; + + await _controller.BulkEditDelete(models); + + _productViewModelServiceMock.Verify(s => s.DeleteBulkEdit( + It.Is>(list => list.Count == 1 && list[0].Id == "owned")), Times.Once); + } + + [TestMethod] + public async Task BulkEditUpdate_FiltersOutProductsNotAccessible() + { + var owned = new Product { Id = "owned", LimitedToStores = true }; + owned.Stores.Add(StaffStoreId); + _productServiceMock.Setup(p => p.GetProductById("owned", It.IsAny())).ReturnsAsync(owned); + _productServiceMock.Setup(p => p.GetProductById("foreign", It.IsAny())).ReturnsAsync(ForeignProduct("foreign")); + + var models = new List { + new() { Id = "owned" }, + new() { Id = "foreign" } + }; + + await _controller.BulkEditUpdate(models); + + _productViewModelServiceMock.Verify(s => s.UpdateBulkEdit( + It.Is>(list => list.Count() == 1 && list.First().Id == "owned")), + Times.Once); + } + + // --- Product currency price ------------------------------------------------------------------------ + + [TestMethod] + public async Task ProductPriceList_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductPriceList(new DataSourceRequest(), "p1"); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task ProductPriceInsert_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductPriceInsert(new ProductModel.ProductPriceModel { ProductId = "p1" }); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task ProductPriceUpdate_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductPriceUpdate(new ProductModel.ProductPriceModel { ProductId = "p1" }); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task ProductPriceDelete_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductPriceDelete(new ProductModel.ProductPriceModel { ProductId = "p1" }); + + AssertKendoGridPermissionError(result); + } + + // --- Tier prices ----------------------------------------------------------------------------------- + + [TestMethod] + public async Task TierPriceList_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.TierPriceList(new DataSourceRequest(), "p1"); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task TierPriceCreatePopup_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.TierPriceCreatePopup(new ProductModel.TierPriceModel { ProductId = "p1" }); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task TierPriceEditPopup_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.TierPriceEditPopup("p1", new ProductModel.TierPriceModel()); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task TierPriceDelete_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.TierPriceDelete(new ProductModel.TierPriceDeleteModel("t1", "p1")); + + AssertKendoGridPermissionError(result); + } + + // --- Product attributes ----------------------------------------------------------------------- + + [TestMethod] + public async Task ProductAttributeMappingList_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductAttributeMappingList(new DataSourceRequest(), "p1"); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task ProductAttributeMappingPopupGet_ProductNotAccessible_ReturnsContentError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductAttributeMappingPopup("p1", null); + + AssertContentPermissionError(result); + } + + [TestMethod] + public async Task ProductAttributeMappingPopupPost_ProductNotAccessible_ReturnsContentError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductAttributeMappingPopup( + new ProductModel.ProductAttributeMappingModel { ProductId = "p1" }); + + AssertContentPermissionError(result); + } + + [TestMethod] + public async Task ProductAttributeMappingDelete_ProductNotAccessible_ReturnsKendoGridError() + { + var foreign = ForeignProduct(); + foreign.ProductAttributeMappings.Add(new ProductAttributeMapping { Id = "pam1" }); + _productServiceMock.Setup(p => p.GetProductById("p1", It.IsAny())).ReturnsAsync(foreign); + + var result = await _controller.ProductAttributeMappingDelete("pam1", "p1", + new Mock().Object); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task ProductAttributeValidationRulesPopup_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductAttributeValidationRulesPopup("id1", "p1"); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task ProductAttributeConditionPopupGet_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductAttributeConditionPopup("p1", "pam1"); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task ProductAttributeConditionPopupPost_ProductNotAccessible_ReturnsContentError() + { + var foreign = ForeignProduct(); + foreign.ProductAttributeMappings.Add(new ProductAttributeMapping { Id = "pam1" }); + _productServiceMock.Setup(p => p.GetProductById("p1", It.IsAny())).ReturnsAsync(foreign); + + var result = await _controller.ProductAttributeConditionPopup( + new ProductAttributeConditionModel { ProductId = "p1", ProductAttributeMappingId = "pam1" }); + + AssertContentPermissionError(result); + } + + [TestMethod] + public async Task EditAttributeValues_ProductNotAccessible_ReturnsContentError() + { + var foreign = ForeignProduct(); + foreign.ProductAttributeMappings.Add(new ProductAttributeMapping { Id = "pam1" }); + _productServiceMock.Setup(p => p.GetProductById("p1", It.IsAny())).ReturnsAsync(foreign); + + var result = await _controller.EditAttributeValues("pam1", "p1", new Mock().Object); + + AssertContentPermissionError(result); + } + + // --- Product attribute values ------------------------------------------------------------------ + + [TestMethod] + public async Task ProductAttributeValueList_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductAttributeValueList("pam1", "p1", new DataSourceRequest()); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task ProductAttributeValueCreatePopupGet_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductAttributeValueCreatePopup("pam1", "p1"); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task ProductAttributeValueCreatePopupPost_ProductNotAccessible_RedirectsToProductList() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductAttributeValueCreatePopup( + new ProductModel.ProductAttributeValueModel { ProductId = "p1" }); + + AssertRedirectToProductList(result); + } + + [TestMethod] + public async Task ProductAttributeValueEditPopupGet_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductAttributeValueEditPopup("val1", "p1", "pam1"); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task ProductAttributeValueEditPopupPost_ProductNotAccessible_RedirectsToProductList() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductAttributeValueEditPopup("p1", + new ProductModel.ProductAttributeValueModel()); + + AssertRedirectToProductList(result); + } + + [TestMethod] + public async Task ProductAttributeValueDelete_ProductNotAccessible_Throws() + { + var foreign = ForeignProduct(); + var mapping = new ProductAttributeMapping { Id = "pam1" }; + mapping.ProductAttributeValues.Add(new ProductAttributeValue { Id = "val1" }); + foreign.ProductAttributeMappings.Add(mapping); + _productServiceMock.Setup(p => p.GetProductById("p1", It.IsAny())).ReturnsAsync(foreign); + + try + { + await _controller.ProductAttributeValueDelete("val1", "pam1", "p1", + new Mock().Object); + Assert.Fail("expected an ArgumentException"); + } + catch (ArgumentException) + { + // expected + } + } + + [TestMethod] + public async Task AssociateProductToAttributeValuePopup_AssociatedProductNotAccessible_Throws() + { + MockAnyProductLookupAsForeign(); + + try + { + await _controller.AssociateProductToAttributeValuePopup( + new ProductModel.ProductAttributeValueModel.AssociateProductToAttributeValueModel { + AssociatedToProductId = "p1" + }); + Assert.Fail("expected an ArgumentException"); + } + catch (ArgumentException) + { + // expected + } + } + + // --- Product attribute combinations --------------------------------------------------------------- + + [TestMethod] + public async Task ProductAttributeCombinationList_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductAttributeCombinationList(new DataSourceRequest(), "p1"); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task ProductAttributeCombinationDelete_ProductNotAccessible_ReturnsKendoGridError() + { + var foreign = ForeignProduct(); + foreign.ProductAttributeCombinations.Add(new ProductAttributeCombination { Id = "c1" }); + _productServiceMock.Setup(p => p.GetProductById("p1", It.IsAny())).ReturnsAsync(foreign); + + var result = await _controller.ProductAttributeCombinationDelete("c1", "p1", + new Mock().Object); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task AttributeCombinationPopupGet_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.AttributeCombinationPopup("p1", "c1"); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task AttributeCombinationPopupPost_ProductNotAccessible_ReturnsContentError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.AttributeCombinationPopup("p1", new ProductAttributeCombinationModel { ProductId = "p1" }); + + AssertContentPermissionError(result); + } + + [TestMethod] + public async Task GenerateAllAttributeCombinations_ProductNotAccessible_ReturnsContentError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.GenerateAllAttributeCombinations("p1"); + + AssertContentPermissionError(result); + } + + [TestMethod] + public async Task ClearAllAttributeCombinations_ProductNotAccessible_ReturnsContentError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ClearAllAttributeCombinations("p1"); + + AssertContentPermissionError(result); + } + + [TestMethod] + public async Task ProductAttributeCombinationTierPriceList_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductAttributeCombinationTierPriceList(new DataSourceRequest(), "p1", "c1"); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task ProductAttributeCombinationTierPriceInsert_ProductNotAccessible_ReturnsContentError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductAttributeCombinationTierPriceInsert("p1", "c1", + new ProductModel.ProductAttributeCombinationTierPricesModel()); + + AssertContentPermissionError(result); + } + + [TestMethod] + public async Task ProductAttributeCombinationTierPriceUpdate_ProductNotAccessible_ReturnsContentError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductAttributeCombinationTierPriceUpdate("p1", "c1", + new ProductModel.ProductAttributeCombinationTierPricesModel()); + + AssertContentPermissionError(result); + } + + [TestMethod] + public async Task ProductAttributeCombinationTierPriceDelete_ProductNotAccessible_ReturnsContentError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductAttributeCombinationTierPriceDelete("p1", "c1", "t1"); + + AssertContentPermissionError(result); + } + + // --- Reservation ---------------------------------------------------------------------------------- + + [TestMethod] + public async Task ListReservations_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ListReservations(new DataSourceRequest(), "p1"); + + AssertKendoGridPermissionError(result); + } + + [TestMethod] + public async Task GenerateCalendar_ProductNotAccessible_ReturnsJsonErrors() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.GenerateCalendar("p1", new ProductModel.GenerateCalendarModel()); + + AssertJsonErrorsPermissionError(result); + } + + [TestMethod] + public async Task ClearCalendar_ProductNotAccessible_ReturnsJsonErrors() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ClearCalendar("p1"); + + AssertJsonErrorsPermissionError(result); + } + + [TestMethod] + public async Task ClearOld_ProductNotAccessible_ReturnsJsonErrors() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ClearOld("p1"); + + AssertJsonErrorsPermissionError(result); + } + + [TestMethod] + public async Task ProductReservationDelete_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ProductReservationDelete(new ProductModel.ReservationModel { ProductId = "p1" }); + + AssertKendoGridPermissionError(result); + } + + // --- Bids ----------------------------------------------------------------------------------------- + + [TestMethod] + public async Task ListBids_ProductNotAccessible_ReturnsJsonErrors() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.ListBids(new DataSourceRequest(), "p1"); + + AssertJsonErrorsPermissionError(result); + } + + [TestMethod] + public async Task BidDelete_ProductNotAccessible_ReturnsKendoGridError() + { + MockAnyProductLookupAsForeign(); + + var result = await _controller.BidDelete(new ProductModel.BidModel { ProductId = "p1" }); + + AssertKendoGridPermissionError(result); + } } diff --git a/src/Web/Grand.Web.Store/Controllers/ProductController.cs b/src/Web/Grand.Web.Store/Controllers/ProductController.cs index 7cb0dfab3..33c6b0631 100644 --- a/src/Web/Grand.Web.Store/Controllers/ProductController.cs +++ b/src/Web/Grand.Web.Store/Controllers/ProductController.cs @@ -79,6 +79,18 @@ public ProductController( #region Methods + /// + /// Whether the given product is accessible to this store's staff. Null-safe: a missing product + /// is treated the same as one belonging to another store. Mirrors Grand.Web.Vendor's + /// CheckAccessToProduct - callers decide how to respond (redirect, grid error, JSON error, ...), + /// this only answers the yes/no question. + /// + private bool CanAccessProduct(Product product) + { + return product != null && + product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId); + } + #region Product list / create / edit / delete //list products @@ -118,7 +130,7 @@ public async Task GoToSku(ProductListModel model) var product = await _productService.GetProductBySku(sku); if (product != null) { - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return RedirectToAction("Edit", new { id = product.Id }); } @@ -177,7 +189,7 @@ public async Task Edit(string id) } else { - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return RedirectToAction("List"); } @@ -208,7 +220,7 @@ public async Task Edit(ProductModel model, bool continueEditing) //No product found with the specified id return RedirectToAction("List"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return RedirectToAction("Edit", new { id = product.Id }); if (model.Ticks != product.Ticks) @@ -250,7 +262,7 @@ public async Task Delete(string id) //No product found with the specified id return RedirectToAction("List"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return RedirectToAction("Edit", new { id = product.Id }); if (ModelState.IsValid) @@ -341,7 +353,7 @@ public async Task LoadProductFriendlyNames(string productIds) var products = await _productService.GetProductsByIds(ids.ToArray(), true); for (var i = 0; i <= products.Count - 1; i++) { - if (!products[i].AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(products[i])) continue; result += products[i].Name; @@ -384,7 +396,7 @@ public async Task ProductCategoryList(DataSourceRequest command, { var product = await _productService.GetProductById(productId); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var productCategoriesModel = await _productViewModelService.PrepareProductCategoryModel(product); @@ -401,7 +413,7 @@ public async Task ProductCategoryList(DataSourceRequest command, public async Task ProductCategoryInsert(ProductModel.ProductCategoryModel model) { var product = await _productService.GetProductById(model.ProductId); - if (product == null || !product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); if (ModelState.IsValid) @@ -423,7 +435,7 @@ public async Task ProductCategoryInsert(ProductModel.ProductCateg public async Task ProductCategoryUpdate(ProductModel.ProductCategoryModel model) { var product = await _productService.GetProductById(model.ProductId); - if (product == null || !product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); if (ModelState.IsValid) @@ -445,7 +457,7 @@ public async Task ProductCategoryUpdate(ProductModel.ProductCateg public async Task ProductCategoryDelete(ProductModel.ProductCategoryModel model) { var product = await _productService.GetProductById(model.ProductId); - if (product == null || !product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); if (ModelState.IsValid) @@ -467,7 +479,7 @@ public async Task ProductCollectionList(DataSourceRequest command { var product = await _productService.GetProductById(productId); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var productCollectionsModel = await _productViewModelService.PrepareProductCollectionModel(product); @@ -484,7 +496,7 @@ public async Task ProductCollectionList(DataSourceRequest command public async Task ProductCollectionInsert(ProductModel.ProductCollectionModel model) { var product = await _productService.GetProductById(model.ProductId); - if (product == null || !product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); if (ModelState.IsValid) @@ -506,7 +518,7 @@ public async Task ProductCollectionInsert(ProductModel.ProductCol public async Task ProductCollectionUpdate(ProductModel.ProductCollectionModel model) { var product = await _productService.GetProductById(model.ProductId); - if (product == null || !product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); if (ModelState.IsValid) @@ -528,7 +540,7 @@ public async Task ProductCollectionUpdate(ProductModel.ProductCol public async Task ProductCollectionDelete(ProductModel.ProductCollectionModel model) { var product = await _productService.GetProductById(model.ProductId); - if (product == null || !product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); if (ModelState.IsValid) @@ -550,7 +562,7 @@ public async Task RelatedProductList(DataSourceRequest command, s { var product = await _productService.GetProductById(productId); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var relatedProducts = product.RelatedProducts.OrderBy(x => x.DisplayOrder); @@ -577,7 +589,7 @@ public async Task RelatedProductList(DataSourceRequest command, s public async Task RelatedProductUpdate(ProductModel.RelatedProductModel model) { var product = await _productService.GetProductById(model.ProductId1); - if (product == null || !product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); if (ModelState.IsValid) @@ -594,7 +606,7 @@ public async Task RelatedProductUpdate(ProductModel.RelatedProduc public async Task RelatedProductDelete(ProductModel.RelatedProductModel model) { var product = await _productService.GetProductById(model.ProductId1); - if (product == null || !product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); if (ModelState.IsValid) @@ -634,7 +646,7 @@ public async Task RelatedProductAddPopupList(DataSourceRequest co public async Task RelatedProductAddPopup(ProductModel.AddRelatedProductModel model) { var product = await _productService.GetProductById(model.ProductId); - if (product == null || !product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return Content(_translationService.GetResource("Admin.Catalog.Products.Permissions")); if (ModelState.IsValid) @@ -658,7 +670,7 @@ public async Task SimilarProductList(DataSourceRequest command, s { var product = await _productService.GetProductById(productId); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var similarProducts = product.SimilarProducts.OrderBy(x => x.DisplayOrder); @@ -685,7 +697,7 @@ public async Task SimilarProductList(DataSourceRequest command, s public async Task SimilarProductUpdate(ProductModel.SimilarProductModel model) { var product = await _productService.GetProductById(model.ProductId1); - if (product == null || !product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); if (ModelState.IsValid) @@ -702,7 +714,7 @@ public async Task SimilarProductUpdate(ProductModel.SimilarProduc public async Task SimilarProductDelete(ProductModel.SimilarProductModel model) { var product = await _productService.GetProductById(model.ProductId1); - if (product == null || !product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); if (ModelState.IsValid) @@ -742,7 +754,7 @@ public async Task SimilarProductAddPopupList(DataSourceRequest co public async Task SimilarProductAddPopup(ProductModel.AddSimilarProductModel model) { var product = await _productService.GetProductById(model.ProductId); - if (product == null || !product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return Content(_translationService.GetResource("Admin.Catalog.Products.Permissions")); if (ModelState.IsValid) @@ -766,7 +778,7 @@ public async Task BundleProductList(DataSourceRequest command, st { var product = await _productService.GetProductById(productId); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var bundleProducts = product.BundleProducts.OrderBy(x => x.DisplayOrder); @@ -793,7 +805,7 @@ public async Task BundleProductList(DataSourceRequest command, st public async Task BundleProductUpdate(ProductModel.BundleProductModel model) { var product = await _productService.GetProductById(model.ProductBundleId); - if (product == null || !product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); if (ModelState.IsValid) @@ -810,7 +822,7 @@ public async Task BundleProductUpdate(ProductModel.BundleProductM public async Task BundleProductDelete(ProductModel.BundleProductModel model) { var product = await _productService.GetProductById(model.ProductBundleId); - if (product == null || !product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); if (ModelState.IsValid) @@ -850,7 +862,7 @@ public async Task BundleProductAddPopupList(DataSourceRequest com public async Task BundleProductAddPopup(ProductModel.AddBundleProductModel model) { var product = await _productService.GetProductById(model.ProductId); - if (product == null || !product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return Content(_translationService.GetResource("Admin.Catalog.Products.Permissions")); if (ModelState.IsValid) @@ -874,7 +886,7 @@ public async Task CrossSellProductList(DataSourceRequest command, { var product = await _productService.GetProductById(productId); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var crossSellProducts = product.CrossSellProduct; @@ -900,7 +912,7 @@ public async Task CrossSellProductDelete(ProductModel.CrossSellPr var product = await _productService.GetProductById(model.ProductId); if (product == null) throw new ArgumentException("Product not exists"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var crossSellProduct = product.CrossSellProduct.FirstOrDefault(x => x == model.Id); @@ -944,7 +956,7 @@ public async Task CrossSellProductAddPopupList(DataSourceRequest public async Task CrossSellProductAddPopup(ProductModel.AddCrossSellProductModel model) { var product = await _productService.GetProductById(model.ProductId); - if (product == null || !product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return Content(_translationService.GetResource("Admin.Catalog.Products.Permissions")); if (ModelState.IsValid) @@ -968,7 +980,7 @@ public async Task RecommendedProductList(DataSourceRequest comman { var product = await _productService.GetProductById(productId); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var recommendedProductsModel = new List(); @@ -993,7 +1005,7 @@ public async Task RecommendedProductDelete(ProductModel.Recommend var product = await _productService.GetProductById(model.ProductId); if (product == null) throw new ArgumentException("Product not exists"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var recommendedProduct = product.RecommendedProduct.FirstOrDefault(x => x == model.Id); @@ -1037,7 +1049,7 @@ public async Task RecommendedProductAddPopupList(DataSourceReques public async Task RecommendedProductAddPopup(ProductModel.AddRecommendedProductModel model) { var product = await _productService.GetProductById(model.ProductId); - if (product == null || !product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return Content(_translationService.GetResource("Admin.Catalog.Products.Permissions")); if (ModelState.IsValid) @@ -1061,7 +1073,7 @@ public async Task AssociatedProductList(DataSourceRequest command { var product = await _productService.GetProductById(productId); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var associatedProducts = await _productService.GetAssociatedProducts(productId, @@ -1093,7 +1105,7 @@ public async Task AssociatedProductUpdate(ProductModel.Associated if (associatedProduct == null) throw new ArgumentException("No associated product found with the specified id"); - if (!associatedProduct.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(associatedProduct)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); associatedProduct.DisplayOrder = model.DisplayOrder; @@ -1115,7 +1127,7 @@ public async Task AssociatedProductDelete(ProductModel.Associated if (product == null) throw new ArgumentException("No associated product found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); await _productViewModelService.DeleteAssociatedProduct(product); @@ -1152,7 +1164,7 @@ public async Task AssociatedProductAddPopupList(DataSourceRequest public async Task AssociatedProductAddPopup(ProductModel.AddAssociatedProductModel model) { var parentProduct = await _productService.GetProductById(model.ProductId); - if (parentProduct == null || !parentProduct.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(parentProduct)) return Content(_translationService.GetResource("Admin.Catalog.Products.Permissions")); if (ModelState.IsValid) @@ -1165,7 +1177,7 @@ public async Task AssociatedProductAddPopup(ProductModel.AddAssoc foreach (var id in model.SelectedProductIds) { var selected = await _productService.GetProductById(id); - if (selected != null && selected.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (CanAccessProduct(selected)) validIds.Add(id); } model.SelectedProductIds = validIds.ToArray(); @@ -1212,7 +1224,7 @@ public async Task ProductPictureAdd( }); var product = await _productService.GetProductById(objectId); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return Json(new { success = false, @@ -1251,7 +1263,7 @@ public async Task ProductPictureList(DataSourceRequest command, s { var product = await _productService.GetProductById(productId); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var productPicturesModel = await _productViewModelService.PrepareProductPicturesModel(product); @@ -1270,7 +1282,7 @@ public async Task ProductPicturePopup(string productId, string id if (product == null) return Content("Product not exist"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var pp = product.ProductPictures.FirstOrDefault(x => x.Id == id); @@ -1298,7 +1310,7 @@ public async Task ProductPicturePopup(ProductModel.ProductPicture if (product == null) throw new ArgumentException("No product found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) throw new ArgumentException(_translationService.GetResource("Admin.Catalog.Products.Permissions")); if (product.ProductPictures.FirstOrDefault(x => x.Id == model.Id) == null) @@ -1319,7 +1331,7 @@ public async Task ProductPicturePopup(ProductModel.ProductPicture public async Task ProductPictureDelete(ProductModel.ProductPictureModel model) { var product = await _productService.GetProductById(model.ProductId); - if (product == null || !product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); if (ModelState.IsValid) @@ -1354,7 +1366,7 @@ public async Task ProductSpecAttrList(DataSourceRequest command, { var product = await _productService.GetProductById(productId); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var productrSpecsModel = await _productViewModelService.PrepareProductSpecificationAttributeModel(product); @@ -1371,7 +1383,7 @@ public async Task ProductSpecAttrPopup( string productId, string id) { var product = await _productService.GetProductById(productId); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return Content(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var model = new ProductModel.AddProductSpecificationAttributeModel { @@ -1402,7 +1414,7 @@ public async Task ProductSpecAttrPopup( if (product == null) return Content("Product not exists"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return Content(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var psa = product.ProductSpecificationAttributes.FirstOrDefault(x => x.Id == model.Id); @@ -1442,7 +1454,7 @@ public async Task ProductSpecAttrDelete(ProductSpecificationAttri if (product == null) return Content("Product not exists"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return Content(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var psa = product.ProductSpecificationAttributes.FirstOrDefault(x => x.Id == model.Id); @@ -1473,7 +1485,7 @@ public async Task PurchasedWithOrders(DataSourceRequest command, var product = await _productService.GetProductById(productId); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var model = new OrderListModel { @@ -1502,7 +1514,7 @@ public async Task Reviews(DataSourceRequest command, string produ { var product = await _productService.GetProductById(productId); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var storeId = _contextAccessor.WorkContext.CurrentCustomer.StaffStoreId; @@ -1594,7 +1606,7 @@ private async Task> FilterValidProductsForStore(IEnum if (product == null) throw new ArgumentException("No product found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) continue; validProducts.Add(pModel); @@ -1612,7 +1624,7 @@ public async Task ProductPriceList(DataSourceRequest command, str { var product = await _productService.GetProductById(productId); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var items = new List(); @@ -1640,7 +1652,7 @@ public async Task ProductPriceInsert(ProductModel.ProductPriceMod if (product == null) throw new ArgumentException("No product found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); if (product.ProductPrices.Any(x => x.CurrencyCode == model.CurrencyCode)) @@ -1672,7 +1684,7 @@ public async Task ProductPriceUpdate(ProductModel.ProductPriceMod if (product == null) throw new ArgumentException("No product found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var productPrice = product.ProductPrices.FirstOrDefault(x => x.Id == model.Id); @@ -1709,7 +1721,7 @@ public async Task ProductPriceDelete(ProductModel.ProductPriceMod if (product == null) throw new ArgumentException("No product found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var productPrice = product.ProductPrices.FirstOrDefault(x => x.Id == model.Id); @@ -1737,7 +1749,7 @@ public async Task TierPriceList(DataSourceRequest command, string { var product = await _productService.GetProductById(productId); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var tierPricesModel = await _productViewModelService.PrepareTierPriceModel(product, _contextAccessor.WorkContext.CurrentCustomer.StaffStoreId); @@ -1768,7 +1780,7 @@ public async Task TierPriceCreatePopup(ProductModel.TierPriceMode if (product == null) throw new ArgumentException("No product found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var tierPrice = model.ToEntity(_dateTimeService); @@ -1810,7 +1822,7 @@ public async Task TierPriceEditPopup(string productId, ProductMod if (product == null) throw new ArgumentException("No product found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var tierPrice = product.TierPrices.FirstOrDefault(x => x.Id == model.Id); @@ -1839,7 +1851,7 @@ public async Task TierPriceDelete(ProductModel.TierPriceDeleteMod if (product == null) throw new ArgumentException("No product found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var tierPrice = product.TierPrices.FirstOrDefault(x => x.Id == model.Id); @@ -1863,7 +1875,7 @@ public async Task ProductAttributeMappingList(DataSourceRequest c { var product = await _productService.GetProductById(productId); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var attributesModel = await _productViewModelService.PrepareProductAttributeMappingModels(product); @@ -1880,7 +1892,7 @@ public async Task ProductAttributeMappingPopup(string productId, { var product = await _productService.GetProductById(productId); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return Content(_translationService.GetResource("Admin.Catalog.Products.Permissions")); if (string.IsNullOrEmpty(productAttributeMappingId)) @@ -1908,7 +1920,7 @@ public async Task ProductAttributeMappingPopup(ProductModel.Produ if (product == null) throw new ArgumentException("No product found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return Content(_translationService.GetResource("Admin.Catalog.Products.Permissions")); if (string.IsNullOrEmpty(model.Id)) @@ -1937,7 +1949,7 @@ public async Task ProductAttributeMappingDelete(string id, string if (productAttributeMapping == null) throw new ArgumentException("No product attribute mapping found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); await productAttributeService.DeleteProductAttributeMapping(productAttributeMapping, product.Id); @@ -1950,7 +1962,7 @@ public async Task ProductAttributeValidationRulesPopup(string id, { var product = await _productService.GetProductById(productId); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var productAttributeMapping = product.ProductAttributeMappings.FirstOrDefault(x => x.Id == id); @@ -1995,7 +2007,7 @@ public async Task ProductAttributeConditionPopup(string productId { var product = await _productService.GetProductById(productId); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var productAttributeMapping = @@ -2022,7 +2034,7 @@ public async Task ProductAttributeConditionPopup(ProductAttribute if (productAttributeMapping == null) return Content("No attribute value found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return Content(_translationService.GetResource("Admin.Catalog.Products.Permissions")); await _productViewModelService.UpdateProductAttributeConditionModel(product, productAttributeMapping, model); @@ -2047,7 +2059,7 @@ public async Task EditAttributeValues(string productAttributeMapp if (productAttributeMapping == null) throw new ArgumentException("No product attribute mapping found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return Content(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var productAttribute = @@ -2069,7 +2081,7 @@ public async Task ProductAttributeValueList(string productAttribu { var product = await _productService.GetProductById(productId); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var productAttributeMapping = @@ -2093,7 +2105,7 @@ public async Task ProductAttributeValueCreatePopup(string product { var product = await _productService.GetProductById(productId); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var productAttributeMapping = @@ -2116,7 +2128,7 @@ public async Task ProductAttributeValueCreatePopup(ProductModel.P if (product == null) throw new ArgumentException("No product found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return RedirectToAction("List", "Product"); var productAttributeMapping = @@ -2143,7 +2155,7 @@ public async Task ProductAttributeValueEditPopup(string id, strin { var product = await _productService.GetProductById(productId); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var pa = product.ProductAttributeMappings.FirstOrDefault(x => x.Id == productAttributeMappingId); @@ -2175,7 +2187,7 @@ public async Task ProductAttributeValueEditPopup(string productId if (product == null) throw new ArgumentException("No product found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return RedirectToAction("List", "Product"); var pav = product.ProductAttributeMappings.FirstOrDefault(x => x.Id == model.ProductAttributeMappingId) @@ -2210,7 +2222,7 @@ public async Task ProductAttributeValueDelete(string id, string p if (pav == null) throw new ArgumentException("No product attribute value found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) throw new ArgumentException(_translationService.GetResource("Admin.Catalog.Products.Permissions")); if (ModelState.IsValid) @@ -2251,7 +2263,7 @@ public async Task AssociateProductToAttributeValuePopup( if (associatedProduct == null) return Content("Cannot load a product"); - if (!associatedProduct.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(associatedProduct)) throw new ArgumentException(_translationService.GetResource("Admin.Catalog.Products.Permissions")); return Content(""); @@ -2267,7 +2279,7 @@ public async Task ProductAttributeCombinationList(DataSourceReque { var product = await _productService.GetProductById(productId); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var combinationsModel = await _productViewModelService.PrepareProductAttributeCombinationModel(product); @@ -2291,7 +2303,7 @@ public async Task ProductAttributeCombinationDelete(string id, st if (combination == null) throw new ArgumentException("No product attribute combination found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); await productAttributeService.DeleteProductAttributeCombination(combination, productId); @@ -2312,7 +2324,7 @@ public async Task AttributeCombinationPopup(string productId, str { var product = await _productService.GetProductById(productId); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var model = await _productViewModelService.PrepareProductAttributeCombinationModel(product, Id); @@ -2330,7 +2342,7 @@ public async Task AttributeCombinationPopup(string productId, //No product found with the specified id return RedirectToAction("List", "Product"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return Content(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var warnings = await _productViewModelService.InsertOrUpdateProductAttributeCombinationPopup(product, model); @@ -2349,7 +2361,7 @@ public async Task GenerateAllAttributeCombinations(string product if (product == null) throw new ArgumentException("No product found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return Content(_translationService.GetResource("Admin.Catalog.Products.Permissions")); await _productViewModelService.GenerateAllAttributeCombinations(product); @@ -2365,7 +2377,7 @@ public async Task ClearAllAttributeCombinations(string productId) if (product == null) throw new ArgumentException("No product found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return Content(_translationService.GetResource("Admin.Catalog.Products.Permissions")); if (ModelState.IsValid) @@ -2394,7 +2406,7 @@ public async Task ProductAttributeCombinationTierPriceList(DataSo { var product = await _productService.GetProductById(productId); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var tierPriceModel = @@ -2417,7 +2429,7 @@ public async Task ProductAttributeCombinationTierPriceInsert(stri if (product == null) throw new ArgumentException("No product found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return Content(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var combination = product.ProductAttributeCombinations.FirstOrDefault(x => x.Id == productAttributeCombinationId); @@ -2437,7 +2449,7 @@ public async Task ProductAttributeCombinationTierPriceUpdate(stri if (product == null) throw new ArgumentException("No product found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return Content(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var combination = product.ProductAttributeCombinations.FirstOrDefault(x => x.Id == productAttributeCombinationId); @@ -2457,7 +2469,7 @@ public async Task ProductAttributeCombinationTierPriceDelete(stri if (product == null) throw new ArgumentException("No product found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return Content(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var combination = @@ -2485,7 +2497,7 @@ public async Task ListReservations(DataSourceRequest command, str { var product = await _productService.GetProductById(productId); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var reservations = @@ -2518,7 +2530,7 @@ public async Task GenerateCalendar(string productId, ProductModel if (product == null) throw new ArgumentException("No product found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return Json(new { errors = _translationService.GetResource("Admin.Catalog.Products.Permissions") }); var reservations = await _productReservationService.GetProductReservationsByProductId(productId, null, null); @@ -2652,7 +2664,7 @@ public async Task ClearCalendar(string productId) if (product == null) throw new ArgumentException("No product found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return Json(new { errors = _translationService.GetResource("Admin.Catalog.Products.Permissions") }); var toDelete = await _productReservationService.GetProductReservationsByProductId(productId, true, null); @@ -2668,7 +2680,7 @@ public async Task ClearOld(string productId) if (product == null) throw new ArgumentException("No product found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return Json(new { errors = _translationService.GetResource("Admin.Catalog.Products.Permissions") }); var toDelete = @@ -2687,7 +2699,7 @@ public async Task ProductReservationDelete(ProductModel.Reservati if (product == null) throw new ArgumentException("No product found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return ErrorForKendoGridJson(_translationService.GetResource("Admin.Catalog.Products.Permissions")); var toDelete = await _productReservationService.GetProductReservation(model.ReservationId); @@ -2716,7 +2728,7 @@ public async Task ListBids(DataSourceRequest command, string prod if (product == null) throw new ArgumentException("No product found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return Json(new { errors = _translationService.GetResource("Admin.Catalog.Products.Permissions") }); var (bidModels, totalCount) = @@ -2736,7 +2748,7 @@ public async Task BidDelete(ProductModel.BidModel model) if (product == null) throw new ArgumentException("No product found with the specified id"); - if (!product.AccessToEntityByStore(_contextAccessor.WorkContext.CurrentCustomer.StaffStoreId)) + if (!CanAccessProduct(product)) return Json(new DataSourceResult { Errors = _translationService.GetResource("Admin.Catalog.Products.Permissions") }); var toDelete = await _auctionService.GetBid(model.BidId);