public override async Task <IdentityResult> UpdateAsync(Role role) { //TODO: Unstable method work, sometimes throws EF already being tracked exception //https://github.com/aspnet/Identity/issues/1807 var result = await base.UpdateAsync(role); if (result.Succeeded && role.Permissions != null) { var sourcePermissionClaims = role.Permissions.Select(x => new Claim(PlatformConstants.Security.Claims.PermissionClaimType, x.Name)).ToList(); var targetPermissionClaims = (await GetClaimsAsync(role)).Where(x => x.Type == PlatformConstants.Security.Claims.PermissionClaimType).ToList(); var comparer = AnonymousComparer.Create((Claim x) => x.Value); //Add foreach (var sourceClaim in sourcePermissionClaims.Except(targetPermissionClaims, comparer)) { await base.AddClaimAsync(role, sourceClaim); } //Remove foreach (var targetClaim in targetPermissionClaims.Except(sourcePermissionClaims, comparer).ToArray()) { await base.RemoveClaimAsync(role, targetClaim); } SecurityCacheRegion.ExpireRegion(); } return(result); }
public async Task Invoke(HttpContext context) { var cacheKey = CacheKey.With(GetType(), "GetAllPlatformRoles"); try { await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) => { cacheEntry.AddExpirationToken(SecurityCacheRegion.CreateChangeToken()); var allRolesIds = (await _platformSecurityApi.SearchRolesAsync(new RoleSearchCriteria { Take = int.MaxValue })).Roles.Select(x => x.Id).ToArray(); foreach (var role in SecurityConstants.Roles.AllRoles) { if (!allRolesIds.Contains(role.Id)) { await _platformSecurityApi.UpdateRoleAsync(role.ToRoleDto()); } } return(allRolesIds); }, cacheNullValue : false); } catch (Exception ex) { _looger.LogError(ex, ex.Message); } await _next(context); }
public override async Task <IdentityResult> CreateAsync(ApplicationUser user) { var changedEntries = new List <GenericChangedEntry <ApplicationUser> > { new GenericChangedEntry <ApplicationUser>(user, EntryState.Added) }; await _eventPublisher.Publish(new UserChangingEvent(changedEntries)); var result = await base.CreateAsync(user); if (result.Succeeded) { if (!user.Roles.IsNullOrEmpty()) { //Add foreach (var newRole in user.Roles) { await AddToRoleAsync(user, newRole.Name); } } // add external logins if (!user.Logins.IsNullOrEmpty()) { foreach (var login in user.Logins) { await AddLoginAsync(user, new UserLoginInfo(login.LoginProvider, login.ProviderKey, null)); } } SecurityCacheRegion.ExpireUser(user); await _eventPublisher.Publish(new UserChangedEvent(changedEntries)); } return(result); }
public override async Task <IdentityResult> UpdateAsync(ApplicationUser user) { var oldUser = await FindByIdAsync(user.Id); var changedEntries = new List <GenericChangedEntry <ApplicationUser> > { new GenericChangedEntry <ApplicationUser>(user, oldUser, EntryState.Modified) }; await _eventPublisher.Publish(new UserChangingEvent(changedEntries)); var result = await base.UpdateAsync(user); if (result.Succeeded) { await _eventPublisher.Publish(new UserChangedEvent(changedEntries)); if (user.Roles != null) { var targetRoles = (await GetRolesAsync(user)); var sourceRoles = user.Roles.Select(x => x.Name); //Add foreach (var newRole in sourceRoles.Except(targetRoles)) { await AddToRoleAsync(user, newRole); } //Remove foreach (var removeRole in targetRoles.Except(sourceRoles)) { await RemoveFromRoleAsync(user, removeRole); } } SecurityCacheRegion.ExpireUser(user); } return(result); }
protected override async Task <IdentityResult> UpdateUserAsync(ApplicationUser user) { var existentUser = await LoadExistingUser(user); //We cant update not existing user if (existentUser == null) { return(IdentityResult.Failed(ErrorDescriber.DefaultError())); } var changedEntries = new List <GenericChangedEntry <ApplicationUser> > { new GenericChangedEntry <ApplicationUser>(user, (ApplicationUser)existentUser.Clone(), EntryState.Modified) }; await _eventPublisher.Publish(new UserChangingEvent(changedEntries)); //We need to use Patch method to update already tracked by DbContent entity, unless the UpdateAsync for passed user will throw exception //"The instance of entity type 'ApplicationUser' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached" user.Patch(existentUser); var result = await base.UpdateUserAsync(existentUser); if (result.Succeeded) { SecurityCacheRegion.ExpireUser(existentUser); var events = changedEntries.GenerateSecurityEventsByChanges(); var tasks = events.Select(x => _eventPublisher.Publish(x)); await Task.WhenAll(tasks); } return(result); }
public override async Task <IdentityResult> CreateAsync(ApplicationUser user) { var changedEntries = new List <GenericChangedEntry <ApplicationUser> > { new GenericChangedEntry <ApplicationUser>(user, EntryState.Added) }; await _eventPublisher.Publish(new UserChangingEvent(changedEntries)); var result = await base.CreateAsync(user); if (result.Succeeded) { await _eventPublisher.Publish(new UserChangedEvent(changedEntries)); if (user.Roles != null) { //Add foreach (var newRole in user.Roles) { await AddToRoleAsync(user, newRole.Name); } } SecurityCacheRegion.ExpireUser(user); } return(result); }
public override async Task <IdentityResult> UpdateAsync(ApplicationUser user) { ApplicationUser existUser = null; if (!string.IsNullOrEmpty(user.Id)) { //It is important to call base.FindByIdAsync method to avoid of update a cached user. existUser = await base.FindByIdAsync(user.Id); } if (existUser == null) { //It is important to call base.FindByNameAsync method to avoid of update a cached user. existUser = await base.FindByNameAsync(user.UserName); } //We cant update not existing user if (existUser == null) { return(IdentityResult.Failed(ErrorDescriber.DefaultError())); } await LoadUserDetailsAsync(existUser); var changedEntries = new List <GenericChangedEntry <ApplicationUser> > { new GenericChangedEntry <ApplicationUser>(user, existUser, EntryState.Modified) }; await _eventPublisher.Publish(new UserChangingEvent(changedEntries)); //We need to use Patch method to update already tracked by DbContent entity, unless the UpdateAsync for passed user will throw exception //"The instance of entity type 'ApplicationUser' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached" user.Patch(existUser); var result = await base.UpdateAsync(existUser); if (result.Succeeded) { await _eventPublisher.Publish(new UserChangedEvent(changedEntries)); if (user.Roles != null) { var targetRoles = (await GetRolesAsync(existUser)); var sourceRoles = user.Roles.Select(x => x.Name); //Add foreach (var newRole in sourceRoles.Except(targetRoles)) { await AddToRoleAsync(existUser, newRole); } //Remove foreach (var removeRole in targetRoles.Except(sourceRoles)) { await RemoveFromRoleAsync(existUser, removeRole); } } SecurityCacheRegion.ExpireUser(existUser); } return(result); }
public virtual Task Handle(OrderPlacedEvent message) { // Need to expire cache for resetting 'IsFirstTimeBuyer' after order creation if (message.WorkContext.CurrentUser.IsFirstTimeBuyer) { SecurityCacheRegion.ExpireUser(message.WorkContext.CurrentUser.Id); } return(Task.CompletedTask); }
public override async Task <IdentityResult> DeleteAsync(Role role) { var result = await base.DeleteAsync(role); if (result.Succeeded) { SecurityCacheRegion.ExpireRegion(); } return(result); }
public override async Task <IdentityResult> ChangePasswordAsync(ApplicationUser user, string currentPassword, string newPassword) { var result = await base.ChangePasswordAsync(user, currentPassword, newPassword); if (result == IdentityResult.Success) { SecurityCacheRegion.ExpireUser(user); } return(result); }
public override async Task <IdentityResult> ResetPasswordAsync(ApplicationUser user, string token, string newPassword) { //It is important to call base.FindByIdAsync method to avoid of update a cached user. var existUser = await base.FindByIdAsync(user.Id); var result = await base.ResetPasswordAsync(existUser, token, newPassword); if (result == IdentityResult.Success) { SecurityCacheRegion.ExpireUser(user); } return(result); }
public override async Task <IdentityResult> ChangePasswordAsync(ApplicationUser user, string currentPassword, string newPassword) { var result = await base.ChangePasswordAsync(user, currentPassword, newPassword); if (result == IdentityResult.Success) { SecurityCacheRegion.ExpireUser(user); // Calculate password hash for external hash storage. This provided as workaround until password hash storage would implemented var customPasswordHash = _userPasswordHasher.HashPassword(user, newPassword); await _eventPublisher.Publish(new UserPasswordChangedEvent(user.Id, customPasswordHash)); } return(result); }
public override async Task <IdentityResult> CreateAsync(Role role) { var result = await base.CreateAsync(role); if (result.Succeeded && !role.Permissions.IsNullOrEmpty()) { var permissionRoleClaims = role.Permissions.Select(x => new Claim(PlatformConstants.Security.Claims.PermissionClaimType, x.Name)); foreach (var claim in permissionRoleClaims) { await base.AddClaimAsync(role, claim); } SecurityCacheRegion.ExpireRegion(); } return(result); }
public override async Task <Role> FindByIdAsync(string roleId) { var cacheKey = CacheKey.With(GetType(), "FindByIdAsync", roleId); var result = await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) => { cacheEntry.AddExpirationToken(SecurityCacheRegion.CreateChangeToken()); var role = await base.FindByIdAsync(roleId); if (role != null) { await LoadRolePermissionsAsync(role); } return(role); }, cacheNullValue : false); return(result); }
public override async Task <ApplicationUser> FindByLoginAsync(string loginProvider, string providerKey) { var cacheKey = CacheKey.With(GetType(), "FindByLoginAsync", loginProvider, providerKey); var result = await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) => { var user = await base.FindByLoginAsync(loginProvider, providerKey); if (user != null) { await LoadUserRolesAsync(user); cacheEntry.AddExpirationToken(SecurityCacheRegion.CreateChangeTokenForUser(user)); } return(user); }, cacheNullValue : false); return(result); }
public override async Task <ApplicationUser> FindByIdAsync(string userId) { var cacheKey = CacheKey.With(GetType(), nameof(FindByIdAsync), userId); var result = await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) => { var user = await base.FindByIdAsync(userId); if (user != null) { await LoadUserDetailsAsync(user); cacheEntry.AddExpirationToken(SecurityCacheRegion.CreateChangeTokenForUser(user)); } return(user); }, cacheNullValue : false); return(result); }
public override async Task <IdentityResult> DeleteAsync(ApplicationUser user) { var changedEntries = new List <GenericChangedEntry <ApplicationUser> > { new GenericChangedEntry <ApplicationUser>(user, EntryState.Deleted) }; await _eventPublisher.Publish(new UserChangingEvent(changedEntries)); var result = await base.DeleteAsync(user); if (result.Succeeded) { SecurityCacheRegion.ExpireUser(user); await _eventPublisher.Publish(new UserChangedEvent(changedEntries)); } return(result); }
public override async Task <IdentityResult> ResetPasswordAsync(ApplicationUser user, string token, string newPassword) { //It is important to call base.FindByIdAsync method to avoid of update a cached user. var existUser = await base.FindByIdAsync(user.Id); var result = await base.ResetPasswordAsync(existUser, token, newPassword); if (result == IdentityResult.Success) { SecurityCacheRegion.ExpireUser(user); // Calculate password hash for external hash storage. This provided as workaround until password hash storage would implemented var customPasswordHash = _userPasswordHasher.HashPassword(user, newPassword); await _eventPublisher.Publish(new UserResetPasswordEvent(user.Id, customPasswordHash)); } return(result); }
public override async Task <IdentityResult> CreateAsync(Role role) { var result = await base.CreateAsync(role); if (result.Succeeded && !role.Permissions.IsNullOrEmpty()) { var existRole = string.IsNullOrEmpty(role.Id) ? await base.FindByNameAsync(role.Name) : await base.FindByIdAsync(role.Id); var permissionRoleClaims = role.Permissions.Select(x => new Claim(PlatformConstants.Security.Claims.PermissionClaimType, x.Name)); foreach (var claim in permissionRoleClaims) { //Need to use an existing tracked by EF entity in order to add permissions for role await base.AddClaimAsync(existRole, claim); } SecurityCacheRegion.ExpireRegion(); } return(result); }
public override async Task <IdentityResult> UpdateAsync(Role updateRole) { if (updateRole == null) { throw new ArgumentNullException(nameof(updateRole)); } Role existRole = null; if (!string.IsNullOrEmpty(updateRole.Id)) { existRole = await base.FindByIdAsync(updateRole.Id); } if (existRole == null) { existRole = await base.FindByNameAsync(updateRole.Name); } if (existRole != null) { //Need to path exists tracked by EF entity due to already being tracked exception //https://github.com/aspnet/Identity/issues/1807 updateRole.Patch(existRole); } var result = await base.UpdateAsync(existRole); if (result.Succeeded && updateRole.Permissions != null) { var sourcePermissionClaims = updateRole.Permissions.Select(x => x.ToClaim(_jsonOptions.SerializerSettings)).ToList(); var targetPermissionClaims = (await GetClaimsAsync(existRole)).Where(x => x.Type == PlatformConstants.Security.Claims.PermissionClaimType).ToList(); var comparer = AnonymousComparer.Create((Claim x) => x.Value); //Add foreach (var sourceClaim in sourcePermissionClaims.Except(targetPermissionClaims, comparer)) { await base.AddClaimAsync(existRole, sourceClaim); } //Remove foreach (var targetClaim in targetPermissionClaims.Except(sourcePermissionClaims, comparer).ToArray()) { await base.RemoveClaimAsync(existRole, targetClaim); } SecurityCacheRegion.ExpireRegion(); } return(result); }
public ActionResult ResetCache() { //TODO: Replace to some other (maybe with using reflection) ThemeEngineCacheRegion.ExpireRegion(); CartCacheRegion.ExpireRegion(); CatalogCacheRegion.ExpireRegion(); ContentBlobCacheRegion.ExpireRegion(); CustomerCacheRegion.ExpireRegion(); MarketingCacheRegion.ExpireRegion(); PricingCacheRegion.ExpireRegion(); QuoteCacheRegion.ExpireRegion(); RecommendationsCacheRegion.ExpireRegion(); StaticContentCacheRegion.ExpireRegion(); StoreCacheRegion.ExpireRegion(); TaxCacheRegion.ExpireRegion(); SubscriptionCacheRegion.ExpireRegion(); SecurityCacheRegion.ExpireRegion(); return(StoreFrontRedirect("~/")); }