Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jstemerdink/b94c104b0aabb04bd3d9b1ab87f8b636 to your computer and use it in GitHub Desktop.
Save jstemerdink/b94c104b0aabb04bd3d9b1ab87f8b636 to your computer and use it in GitHub Desktop.
Set access rights to Episerver Commerce Markets for specific users
[ServiceConfiguration(typeof(IContentQuery))]
public class GetSalesCampaignChildrenQueryFiltered : GetSalesCampaignChildrenQuery
{
private readonly IMarketAccessRightsHelper marketAccessRightsHelper;
public GetSalesCampaignChildrenQueryFiltered(
IContentQueryHelper queryHelper,
IContentRepository contentRepository,
LanguageSelectorFactory languageSelectorFactory,
CampaignInfoExtractor campaignInfoExtractor,
FacetQueryHandler facetQueryHandler,
IMarketAccessRightsHelper marketAccessRightsHelper)
: base(
queryHelper: queryHelper,
contentRepository: contentRepository,
languageSelectorFactory: languageSelectorFactory,
campaignInfoExtractor: campaignInfoExtractor,
facetQueryHandler: facetQueryHandler)
{
this.marketAccessRightsHelper = marketAccessRightsHelper;
}
protected override IEnumerable<IContent> GetChildrenByType(
Type type,
ContentReference parentLink,
ILanguageSelector selector)
{
if (type == typeof(SalesCampaign) && this.marketAccessRightsHelper.IsFilteredMarketsRequest())
{
return base.GetChildrenByType(type, parentLink, selector).OfType<SalesCampaign>().Where(
c => this.marketAccessRightsHelper.UserHasAccessToMarket(c.TargetMarket));
}
return base.GetChildrenByType(type, parentLink, selector);
}
}
using Mediachase.Commerce;
namespace EPiServer.Reference.Commerce.Site.Features.MarketSecurity
{
public interface IMarketAccessRightsHelper
{
bool IsFilteredMarketsRequest();
bool UserHasAccessToMarket(IMarket market);
bool UserHasAccessToMarket(string marketId);
}
}
using System.Collections.Generic;
using System.Web;
using EPiServer.ServiceLocation;
using Mediachase.Commerce;
namespace EPiServer.Reference.Commerce.Site.Features.MarketSecurity
{
[ServiceConfiguration(typeof(IMarketAccessRightsHelper), Lifecycle = ServiceInstanceScope.Singleton)]
public class MarketAccessRightsHelper : IMarketAccessRightsHelper
{
public const string MarketAccessPrefix = "MarketAccess_";
private readonly IList<string> _epiUiUrls;
public MarketAccessRightsHelper()
{
// Configure Episerver UI url segments
_epiUiUrls = new List<string>
{
"Episerver.Commerce.Shell/".ToLower(),
"CMS/".ToLower(),
"Shell/".ToLower()
};
}
public virtual bool IsFilteredMarketsRequest()
{
if (HttpContext.Current.Request.Url.Segments.Length > 2)
{
var uiUrlSegment = HttpContext.Current.Request.Url.Segments[2].ToLower();
return _epiUiUrls.Contains(uiUrlSegment);
}
return false;
}
public virtual bool UserHasAccessToMarket(IMarket market)
{
return HttpContext.Current.User.IsInRole(MarketAccessPrefix + market.MarketId.Value) || HttpContext.Current.User.IsInRole("CommerceAdmins");
}
public virtual bool UserHasAccessToMarket(string marketId)
{
return HttpContext.Current.User.IsInRole(MarketAccessPrefix + marketId) || HttpContext.Current.User.IsInRole("CommerceAdmins");
}
}
}
using System.Collections.Generic;
using System.Linq;
using EPiServer.Framework.Cache;
using Mediachase.Commerce;
using Mediachase.Commerce.Markets.Database;
namespace EPiServer.Reference.Commerce.Site.Features.MarketSecurity
{
public class MarketAccessRightsMarketService : MarketServiceCache
{
private readonly IMarketAccessRightsHelper _marketAccessRightsHelper;
public MarketAccessRightsMarketService(ISynchronizedObjectInstanceCache cache, IMarketAccessRightsHelper marketAccessRightsHelper) : base(cache)
{
_marketAccessRightsHelper = marketAccessRightsHelper;
}
public override IEnumerable<IMarket> GetAllMarkets()
{
if (_marketAccessRightsHelper.IsFilteredMarketsRequest())
{
var allMarkets = base.GetAllMarkets();
return allMarkets.Where(market => _marketAccessRightsHelper.UserHasAccessToMarket(market)).ToList();
}
return base.GetAllMarkets();
}
}
}
using System.Collections.Generic;
using System.Linq;
using EPiServer.Core;
using Mediachase.Commerce;
using Mediachase.Commerce.Catalog;
using Mediachase.Commerce.Markets;
using Mediachase.Commerce.Pricing;
using Mediachase.Commerce.Pricing.Database;
namespace EPiServer.Reference.Commerce.Site.Features.MarketSecurity
{
public class MarketAccessRightsPriceDetailDatabase : PriceDetailDatabase, IPriceDetailService
{
private readonly IMarketAccessRightsHelper _marketAccessRightsHelper;
private readonly IMarketService _marketService;
public MarketAccessRightsPriceDetailDatabase(ReferenceConverter referenceConverter, IMarketAccessRightsHelper marketAccessRightsHelper, IMarketService marketService) : base(referenceConverter)
{
_marketAccessRightsHelper = marketAccessRightsHelper;
_marketService = marketService;
}
public new IList<IPriceDetailValue> List(ContentReference catalogContentReference, MarketId marketId,
PriceFilter priceFilter, int offset, int count, out int totalCount)
{
// If the market Id is blank (i.e "All") then filter the
// prices by the markets that the user has access to
if (_marketAccessRightsHelper.IsFilteredMarketsRequest() && marketId.Value == string.Empty)
{
var allowedMarkets = _marketService.GetAllMarkets().Select(m => m.MarketId);
var allPrices = base.List(catalogContentReference, marketId, priceFilter, offset, count, out totalCount);
return allPrices.Where(price => allowedMarkets.Contains(price.MarketId)).ToList();
}
return base.List(catalogContentReference, marketId, priceFilter, offset, count, out totalCount);
}
}
}
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using EPiServer.ServiceLocation;
using Mediachase.Commerce.Markets;
using Mediachase.Commerce.Pricing;
namespace EPiServer.Reference.Commerce.Site.Features.MarketSecurity
{
[ModuleDependency(typeof(EPiServer.Commerce.Initialization.InitializationModule))]
public class RegisterMarketSecurityImpl : IConfigurableModule
{
public void ConfigureContainer(ServiceConfigurationContext context)
{
// Ovveride the default implementations, could use an interceptor here too
context.StructureMap().Configure(x => { x.For<IMarketService>().Use<MarketAccessRightsMarketService>(); });
context.StructureMap().Configure(x => { x.For<IPriceDetailService>().Use<MarketAccessRightsPriceDetailDatabase>(); });
context.StructureMap().Configure(
x =>
{
x.ForConcreteType<GetSalesCampaignChildrenQuery>().Configure.InterceptWith(
new DecoratorInterceptor(
typeof(GetSalesCampaignChildrenQuery),
typeof(GetSalesCampaignChildrenQueryFiltered)));
});
}
public void Initialize(InitializationEngine context) { }
public void Uninitialize(InitializationEngine context) { }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment