Ejemplo n.º 1
0
        public async Task SaveChangesAsync(IIdentity user)
        {
            var contextInfo = GetContextInfo(user);

            _dbcontext.ChangeTracker.DetectChanges();
            var entries = _dbcontext.ChangeTracker.Entries().ToList();

            foreach (var entityChange in _dbcontext.ChangeTracker.Entries())
            {
                var authResult = await AuthorizeEntityChangeAsync(user, entityChange);

                if (!authResult.HasSucceed)
                {
                    if (entityChange.State == EntityState.Modified)
                    {
                        await Listen.ModificationFailedAsync(CreateWithValues(entityChange.OriginalValues),
                                                             entityChange.Entity as T, GetContextInfo(user));
                    }
                    else if (entityChange.State == EntityState.Deleted)
                    {
                        await Listen.RemoveFailedAsync(CreateWithValues(entityChange.OriginalValues), contextInfo);
                    }

                    throw new AuthorizationFailedException(authResult);
                }
            }

            // Added should be updated after saving changes for get the ID of the newly created entity
            var added    = entries.Where(a => a.State == EntityState.Added).Select(a => a.Entity).ToList();
            var modified = entries.Where(a => a.State == EntityState.Modified).Select(SelectBoth).ToList();
            var removed  = entries.Where(a => a.State == EntityState.Deleted).Select(a => SelectOriginal(a)).ToList();

            if (removed.Any())
            {
                if (GetLogicalDeleteProperty(_type) == null)
                {
                    if (!IgnoreLogicalDeleteError &&
                        removed.Any(entry => GetLogicalDeleteProperty(entry.GetType()) != null))
                    {
                        throw new LogicalSecurityRiskException(
                                  $"There are derived types in the deleted entries which have LogicalDeleteAttribute, but the base type does not use logical delete.");
                    }
                }
                else
                {
                    var logicalRemoved = entries.Where(a => a.State == EntityState.Deleted).ToList();
                    logicalRemoved.ForEach(entry =>
                    {
                        entry.Reload();
                        entry.State = EntityState.Modified;
                        entry.Property(GetLogicalDeleteProperty(_type).Name).CurrentValue = true;
                    });
                }
            }

            await _dbcontext.SaveChangesAsync();

            await DistributeToListenersAsync(added, contextInfo, modified, removed);
        }
Ejemplo n.º 2
0
        public async Task ModificationFailed()
        {
            MockListener.Reset();
            await Listen.ModificationFailedAsync(ent, ent, ctx);

            Assert.IsFalse(MockListener.WasOnCreatedCalled);
            Assert.IsFalse(MockListener.WasOnCreationValidationFailedCalled);
            Assert.IsFalse(MockListener.WasOnModifiedCalled);
            Assert.IsTrue(MockListener.WasOnModificationFailedCalled);
            Assert.IsFalse(MockListener.WasOnDeletedCalled);
            Assert.IsFalse(MockListener.WasOnDeletionFailedCalled);
        }