only product resource owner can save it
six006 opened this issue · 2 comments
six006 commented
Can't find any solution for product resource authorize,I want to only product creator can save the product.
src\VirtoCommerce.CatalogModule.Web\Authorization\CatalogAuthorizationHandler.cs
/// <summary>
/// Create/Update the specified products.
/// </summary>
/// <param name="products">The products.</param>
[HttpPost]
[Route("batch")]
public async Task<ActionResult> SaveProducts([FromBody] CatalogProduct[] products)
{
var authorizationResult = await _authorizationService.AuthorizeAsync(User, products, new CatalogAuthorizationRequirement(ModuleConstants.Security.Permissions.Update));
if (!authorizationResult.Succeeded)
{
return Unauthorized();
}
await InnerSaveProducts(products);
return Ok();
}
But can't find a solution in CatalogAuthorizationHandler.cs
src\VirtoCommerce.CatalogModule.Web\Authorization\CatalogAuthorizationHandler.cs
public sealed class CatalogAuthorizationHandler : PermissionAuthorizationHandlerBase<CatalogAuthorizationRequirement>
{
private readonly MvcNewtonsoftJsonOptions _jsonOptions;
public CatalogAuthorizationHandler(IOptions<MvcNewtonsoftJsonOptions> jsonOptions)
{
_jsonOptions = jsonOptions.Value;
}
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, CatalogAuthorizationRequirement requirement)
{
await base.HandleRequirementAsync(context, requirement);
if (!context.HasSucceeded)
{
var userPermission = context.User.FindPermission(requirement.Permission, _jsonOptions.SerializerSettings);
if (userPermission != null)
{
var allowedCatalogIds = userPermission.AssignedScopes.OfType<SelectedCatalogScope>()
.Select(x => x.CatalogId)
.Distinct()
.ToArray();
if (context.Resource is CatalogSearchCriteria catalogSearchCriteria)
{
catalogSearchCriteria.CatalogIds = allowedCatalogIds;
context.Succeed(requirement);
}
else if (context.Resource is CatalogListEntrySearchCriteria listEntrySearchCriteria)
{
listEntrySearchCriteria.CatalogIds = allowedCatalogIds;
context.Succeed(requirement);
}
else if (context.Resource is Catalog catalog && !catalog.IsTransient())
{
if (allowedCatalogIds.Contains(catalog.Id))
{
context.Succeed(requirement);
}
}
else if (context.Resource is IEnumerable<IHasCatalogId> hasCatalogIds)
{
var catalogIds = hasCatalogIds.Select(x => x.CatalogId).Distinct().ToList();
if (catalogIds.Intersect(allowedCatalogIds).Count() == catalogIds.Count)
{
context.Succeed(requirement);
}
}
else if (context.Resource is IHasCatalogId hasCatalogId)
{
if (allowedCatalogIds.Contains(hasCatalogId.CatalogId))
{
context.Succeed(requirement);
}
}
else if (context.Resource is ProductExportDataQuery dataQuery)
{
if (dataQuery.CatalogIds.IsNullOrEmpty())
{
dataQuery.CatalogIds = allowedCatalogIds;
}
else
{
dataQuery.CatalogIds = dataQuery.CatalogIds.Intersect(allowedCatalogIds).ToArray();
}
context.Succeed(requirement);
}
else if (context.Resource is PropertyDictionaryItemSearchCriteria propertyDictionaryItemSearchCriteria)
{
if (propertyDictionaryItemSearchCriteria.CatalogIds.IsNullOrEmpty())
{
propertyDictionaryItemSearchCriteria.CatalogIds = allowedCatalogIds;
}
else
{
propertyDictionaryItemSearchCriteria.CatalogIds = propertyDictionaryItemSearchCriteria.CatalogIds.Intersect(allowedCatalogIds).ToArray();
}
context.Succeed(requirement);
}
}
}
}
}
mvktsk commented
Task https://virtocommerce.atlassian.net/browse/VP-7043 has been created
Vectorfield4 commented
Hi, @six006! We bring you a test solution for your problem. You can look at it here https://github.com/VirtoCommerce/vc-module-catalog/tree/howto/479 (commit d8109fd).
Feel free to reopen this ticket, if this solution not fully covers your requirements.