Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
using Grand.Domain.Common;
using Grand.Domain.Customers;
using Grand.Domain.Localization;
using Grand.Infrastructure;
using Grand.Domain.Stores;

namespace Grand.Business.Authentication.Services;

Expand All @@ -14,14 +14,11 @@ public class TwoFactorAuthenticationService : ITwoFactorAuthenticationService
private readonly IEnumerable<ISMSVerificationService> _smsVerificationService;
private readonly TwoFactorAuthenticator _twoFactorAuthentication;
private readonly ICustomerService _customerService;
private readonly IContextAccessor _contextAccessor;

public TwoFactorAuthenticationService(
IContextAccessor contextAccessor,
ICustomerService customerService,
IEnumerable<ISMSVerificationService> smsVerificationService)
{
_contextAccessor = contextAccessor;
_customerService = customerService;
_smsVerificationService = smsVerificationService;
_twoFactorAuthentication = new TwoFactorAuthenticator();
Expand Down Expand Up @@ -55,14 +52,16 @@ public virtual async Task<bool> AuthenticateTwoFactor(string secretKey, string t
}

public virtual async Task<TwoFactorCodeSetup> GenerateCodeSetup(string secretKey, Customer customer,
Language language, TwoFactorAuthenticationType twoFactorAuthenticationType)
Store store, Language language, TwoFactorAuthenticationType twoFactorAuthenticationType)
{
ArgumentNullException.ThrowIfNull(store);

var model = new TwoFactorCodeSetup();

switch (twoFactorAuthenticationType)
{
case TwoFactorAuthenticationType.AppVerification:
var setupInfo = _twoFactorAuthentication.GenerateSetupCode(_contextAccessor.StoreContext.CurrentStore.CompanyName,
var setupInfo = _twoFactorAuthentication.GenerateSetupCode(store.CompanyName,
customer.Email, secretKey, false);
model.CustomValues.Add("QrCodeImageUrl", setupInfo.QrCodeSetupImageUrl);
model.CustomValues.Add("ManualEntryQrCode", setupInfo.ManualEntryKey);
Expand Down
88 changes: 45 additions & 43 deletions src/Business/Grand.Business.Cms/Services/KnowledgebaseService.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
using Grand.Business.Core.Interfaces.Cms;
using Grand.Business.Core.Utilities.Catalog;
using Grand.Data;
using Grand.Domain;
using Grand.Domain.Customers;
using Grand.Domain.Knowledgebase;
using Grand.Domain.Permissions;
using Grand.Domain.Stores;
using Grand.Infrastructure;
using Grand.Infrastructure.Caching;
using Grand.Infrastructure.Caching.Constants;
using Grand.Infrastructure.Configuration;
Expand All @@ -22,7 +22,6 @@ public class KnowledgebaseService : IKnowledgebaseService
private readonly IRepository<KnowledgebaseArticle> _knowledgebaseArticleRepository;
private readonly IRepository<KnowledgebaseCategory> _knowledgebaseCategoryRepository;
private readonly IMediator _mediator;
private readonly IContextAccessor _contextAccessor;

/// <summary>
/// Ctor
Expand All @@ -32,35 +31,36 @@ public KnowledgebaseService
IRepository<KnowledgebaseArticle> knowledgebaseArticleRepository,
IRepository<KnowledgebaseArticleComment> articleCommentRepository,
IMediator mediator,
IContextAccessor contextAccessor,
ICacheBase cacheBase, AccessControlConfig accessControlConfig)
{
_knowledgebaseCategoryRepository = knowledgebaseCategoryRepository;
_knowledgebaseArticleRepository = knowledgebaseArticleRepository;
_articleCommentRepository = articleCommentRepository;
_mediator = mediator;
_contextAccessor = contextAccessor;
_cacheBase = cacheBase;
_accessControlConfig = accessControlConfig;
}

private IQueryable<T> ApplyStandardFilter<T>(IQueryable<T> query) where T : BaseEntity, IGroupLinkEntity, IStoreLinkEntity
private IQueryable<T> ApplyStandardFilter<T>(IQueryable<T> query, CatalogAccess access)
where T : BaseEntity, IGroupLinkEntity, IStoreLinkEntity
{
return ApplyStandardFilter(query, _contextAccessor.WorkContext.CurrentCustomer.GetCustomerGroupIds(),
_contextAccessor.StoreContext.CurrentStore.Id);
ArgumentNullException.ThrowIfNull(access);
return ApplyStandardFilter(query, access.ShowHidden ? null : access.Customer.GetCustomerGroupIds(),
access.StoreId);
}

//null group ids skip the group filter, an empty store id the store filter
private IQueryable<T> ApplyStandardFilter<T>(IQueryable<T> query, string[] allowedCustomerGroupsIds,
string storeId) where T : BaseEntity, IGroupLinkEntity, IStoreLinkEntity
{
if (!_accessControlConfig.IgnoreAcl)
if (allowedCustomerGroupsIds != null && !_accessControlConfig.IgnoreAcl)
{
query = from p in query
where !p.LimitedToGroups || allowedCustomerGroupsIds.Any(x => p.CustomerGroups.Contains(x))
select p;
}

if (!_accessControlConfig.IgnoreStoreLimitations)
if (!string.IsNullOrEmpty(storeId) && !_accessControlConfig.IgnoreStoreLimitations)
{
query = from p in query
where !p.LimitedToStores || p.Stores.Contains(storeId)
Expand All @@ -70,13 +70,14 @@ private IQueryable<T> ApplyStandardFilter<T>(IQueryable<T> query, string[] allow
return query;
}

private string GetCacheKey(string format, params object[] additionalParams)
private string GetCacheKey(string format, CatalogAccess access, params object[] additionalParams)
{
var standardParams = new[]
{
string.Join(",", _contextAccessor.WorkContext.CurrentCustomer.GetCustomerGroupIds()),
_contextAccessor.StoreContext.CurrentStore.Id
};
ArgumentNullException.ThrowIfNull(access);
//groups only matter with the ACL on; "*" keeps reads including hidden records apart from a customer with no groups
var groupIds = _accessControlConfig.IgnoreAcl ? ""
: access.ShowHidden ? "*"
: string.Join(",", access.Customer.GetCustomerGroupIds());
var standardParams = new[] { groupIds, access.StoreId };

var allParams = additionalParams != null
? standardParams.Concat(additionalParams).ToArray()
Expand Down Expand Up @@ -132,9 +133,9 @@ public virtual async Task<KnowledgebaseCategory> GetKnowledgebaseCategory(string
/// </summary>
/// <param name="id"></param>
/// <returns>knowledge base category</returns>
public virtual async Task<KnowledgebaseCategory> GetPublicKnowledgebaseCategory(string id)
public virtual async Task<KnowledgebaseCategory> GetPublicKnowledgebaseCategory(string id, CatalogAccess access)
{
var key = GetCacheKey(CacheKey.KNOWLEDGEBASE_CATEGORY_BY_ID, id);
var key = GetCacheKey(CacheKey.KNOWLEDGEBASE_CATEGORY_BY_ID, access, id);

return await _cacheBase.GetAsync(key, async () =>
{
Expand All @@ -143,7 +144,7 @@ public virtual async Task<KnowledgebaseCategory> GetPublicKnowledgebaseCategory(

query = query.Where(x => x.Published);
query = query.Where(x => x.Id == id);
query = ApplyStandardFilter(query);
query = ApplyStandardFilter(query, access);
var toReturn = await _knowledgebaseCategoryRepository.FirstOrDefaultAsync(query);
return toReturn;
});
Expand Down Expand Up @@ -185,15 +186,13 @@ public virtual Task<KnowledgebaseArticle> GetKnowledgebaseArticle(string id)
}

/// <summary>
/// Gets knowledge base articles
/// Gets every knowledge base article, unpublished and group- or store-limited ones included
/// </summary>
/// <returns>List of knowledge base articles</returns>
/// <param name="storeId">Store ident</param>
public virtual async Task<List<KnowledgebaseArticle>> GetKnowledgebaseArticles(string storeId = "")
public virtual async Task<List<KnowledgebaseArticle>> GetKnowledgebaseArticles()
{
var query = from p in _knowledgebaseArticleRepository.Table
select p;
query = ApplyStandardFilter(query);
query = query.OrderBy(x => x.DisplayOrder);
return (await _knowledgebaseArticleRepository.ToListAsync(query)).ToList();
}
Expand Down Expand Up @@ -253,9 +252,9 @@ public virtual async Task<IPagedList<KnowledgebaseArticle>> GetKnowledgebaseArti
/// Gets public(published etc) knowledge base categories
/// </summary>
/// <returns>List of public knowledgebase categories</returns>
public virtual async Task<List<KnowledgebaseCategory>> GetPublicKnowledgebaseCategories()
public virtual async Task<List<KnowledgebaseCategory>> GetPublicKnowledgebaseCategories(CatalogAccess access)
{
var key = GetCacheKey(CacheKey.KNOWLEDGEBASE_CATEGORIES);
var key = GetCacheKey(CacheKey.KNOWLEDGEBASE_CATEGORIES, access);

return await _cacheBase.GetAsync(key, async () =>
{
Expand All @@ -264,7 +263,7 @@ public virtual async Task<List<KnowledgebaseCategory>> GetPublicKnowledgebaseCat

query = query.Where(x => x.Published);

query = ApplyStandardFilter(query);
query = ApplyStandardFilter(query, access);
query = query.OrderBy(x => x.DisplayOrder);
return (await _knowledgebaseCategoryRepository.ToListAsync(query)).ToList();
});
Expand All @@ -274,17 +273,17 @@ public virtual async Task<List<KnowledgebaseCategory>> GetPublicKnowledgebaseCat
/// Gets public(published etc) knowledge base articles
/// </summary>
/// <returns>List of public knowledge base articles</returns>
public virtual async Task<List<KnowledgebaseArticle>> GetPublicKnowledgebaseArticles()
public virtual async Task<List<KnowledgebaseArticle>> GetPublicKnowledgebaseArticles(CatalogAccess access)
{
var key = GetCacheKey(CacheKey.ARTICLES);
var key = GetCacheKey(CacheKey.ARTICLES, access);

return await _cacheBase.GetAsync(key, async () =>
{
var query = from p in _knowledgebaseArticleRepository.Table
select p;

query = query.Where(x => x.Published);
query = ApplyStandardFilter(query);
query = ApplyStandardFilter(query, access);

query = query.OrderBy(x => x.DisplayOrder);
return (await _knowledgebaseArticleRepository.ToListAsync(query)).ToList();
Expand Down Expand Up @@ -314,9 +313,9 @@ public virtual async Task<List<KnowledgebaseArticle>> GetPublicKnowledgebaseArti
/// Gets knowledge base article if it is published etc
/// </summary>
/// <returns>knowledge base article</returns>
public virtual async Task<KnowledgebaseArticle> GetPublicKnowledgebaseArticle(string id)
public virtual async Task<KnowledgebaseArticle> GetPublicKnowledgebaseArticle(string id, CatalogAccess access)
{
var key = GetCacheKey(CacheKey.ARTICLE_BY_ID, id);
var key = GetCacheKey(CacheKey.ARTICLE_BY_ID, access, id);

return await _cacheBase.GetAsync(key, async () =>
{
Expand All @@ -325,7 +324,7 @@ public virtual async Task<KnowledgebaseArticle> GetPublicKnowledgebaseArticle(st

query = query.Where(x => x.Published);
query = query.Where(x => x.Id == id);
query = ApplyStandardFilter(query);
query = ApplyStandardFilter(query, access);
return await _knowledgebaseArticleRepository.FirstOrDefaultAsync(query);
});
}
Expand All @@ -334,9 +333,10 @@ public virtual async Task<KnowledgebaseArticle> GetPublicKnowledgebaseArticle(st
/// Gets public(published etc) knowledge base articles for category id
/// </summary>
/// <returns>List of public knowledge base articles</returns>
public virtual async Task<List<KnowledgebaseArticle>> GetPublicKnowledgebaseArticlesByCategory(string categoryId)
public virtual async Task<List<KnowledgebaseArticle>> GetPublicKnowledgebaseArticlesByCategory(string categoryId,
CatalogAccess access)
{
var key = GetCacheKey(CacheKey.ARTICLES_BY_CATEGORY_ID, categoryId);
var key = GetCacheKey(CacheKey.ARTICLES_BY_CATEGORY_ID, access, categoryId);

return await _cacheBase.GetAsync(key, async () =>
{
Expand All @@ -346,7 +346,7 @@ public virtual async Task<List<KnowledgebaseArticle>> GetPublicKnowledgebaseArti
query = query.Where(x => x.Published);
query = query.Where(x => x.ParentCategoryId == categoryId);

query = ApplyStandardFilter(query);
query = ApplyStandardFilter(query, access);
query = query.OrderBy(x => x.DisplayOrder);
return (await _knowledgebaseArticleRepository.ToListAsync(query)).ToList();
});
Expand All @@ -356,9 +356,10 @@ public virtual async Task<List<KnowledgebaseArticle>> GetPublicKnowledgebaseArti
/// Gets public(published etc) knowledge base articles for keyword
/// </summary>
/// <returns>List of public knowledge base articles</returns>
public virtual async Task<List<KnowledgebaseArticle>> GetPublicKnowledgebaseArticlesByKeyword(string keyword)
public virtual async Task<List<KnowledgebaseArticle>> GetPublicKnowledgebaseArticlesByKeyword(string keyword,
CatalogAccess access)
{
var key = GetCacheKey(CacheKey.ARTICLES_BY_KEYWORD, keyword);
var key = GetCacheKey(CacheKey.ARTICLES_BY_KEYWORD, access, keyword);

return await _cacheBase.GetAsync(key, async () =>
{
Expand All @@ -371,7 +372,7 @@ public virtual async Task<List<KnowledgebaseArticle>> GetPublicKnowledgebaseArti
p.Locales.Any(x => x.LocaleValue != null && x.LocaleValue.ToLower().Contains(keyword.ToLower()))
|| p.Name.ToLower().Contains(keyword.ToLower()) || p.Content.ToLower().Contains(keyword.ToLower()));

query = ApplyStandardFilter(query);
query = ApplyStandardFilter(query, access);
query = query.OrderBy(x => x.DisplayOrder);
return (await _knowledgebaseArticleRepository.ToListAsync(query)).ToList();
});
Expand All @@ -381,9 +382,10 @@ public virtual async Task<List<KnowledgebaseArticle>> GetPublicKnowledgebaseArti
/// Gets public(published etc) knowledge base categories for keyword
/// </summary>
/// <returns>List of public knowledge base categories</returns>
public virtual async Task<List<KnowledgebaseCategory>> GetPublicKnowledgebaseCategoriesByKeyword(string keyword)
public virtual async Task<List<KnowledgebaseCategory>> GetPublicKnowledgebaseCategoriesByKeyword(string keyword,
CatalogAccess access)
{
var key = GetCacheKey(CacheKey.KNOWLEDGEBASE_CATEGORIES_BY_KEYWORD, keyword);
var key = GetCacheKey(CacheKey.KNOWLEDGEBASE_CATEGORIES_BY_KEYWORD, access, keyword);

return await _cacheBase.GetAsync(key, async () =>
{
Expand All @@ -396,7 +398,7 @@ public virtual async Task<List<KnowledgebaseCategory>> GetPublicKnowledgebaseCat
p.Locales.Any(x => x.LocaleValue != null && x.LocaleValue.ToLower().Contains(keyword.ToLower()))
|| p.Name.ToLower().Contains(keyword.ToLower()) || p.Description.ToLower().Contains(keyword.ToLower()));

query = ApplyStandardFilter(query);
query = ApplyStandardFilter(query, access);
query = query.OrderBy(x => x.DisplayOrder);
return (await _knowledgebaseCategoryRepository.ToListAsync(query)).ToList();
});
Expand All @@ -406,9 +408,9 @@ public virtual async Task<List<KnowledgebaseCategory>> GetPublicKnowledgebaseCat
/// Gets homepage knowledge base articles
/// </summary>
/// <returns>List of homepage knowledge base articles</returns>
public virtual async Task<List<KnowledgebaseArticle>> GetHomepageKnowledgebaseArticles()
public virtual async Task<List<KnowledgebaseArticle>> GetHomepageKnowledgebaseArticles(CatalogAccess access)
{
var key = GetCacheKey(CacheKey.HOMEPAGE_ARTICLES);
var key = GetCacheKey(CacheKey.HOMEPAGE_ARTICLES, access);

return await _cacheBase.GetAsync(key, async () =>
{
Expand All @@ -417,7 +419,7 @@ public virtual async Task<List<KnowledgebaseArticle>> GetHomepageKnowledgebaseAr

query = query.Where(x => x.Published);
query = query.Where(x => x.ShowOnHomepage);
query = ApplyStandardFilter(query);
query = ApplyStandardFilter(query, access);
query = query.OrderBy(x => x.DisplayOrder);
return (await _knowledgebaseArticleRepository.ToListAsync(query)).ToList();
});
Expand Down
Loading
Loading