public ChangeTaskHelper(ApprovalCommandService generalCommandService, ApprovalCommandMapper approvalCommandMapper, LanguageChangeDetails languageChangeDetails, MovingChangeDetail movingChangeDetail, SecurityChangeDetail securityChangeDetail, ExpirationChangeDetails expirationChangeDetails)
 {
     _generalCommandService   = generalCommandService;
     _approvalCommandMapper   = approvalCommandMapper;
     _languageChangeDetails   = languageChangeDetails;
     _movingChangeDetail      = movingChangeDetail;
     _securityChangeDetail    = securityChangeDetail;
     _expirationChangeDetails = expirationChangeDetails;
 }
Ejemplo n.º 2
0
        public void CompleteChanges(RockContext rockContext = null)
        {
            SecurityChangeDetail securityChangeDetail = new SecurityChangeDetail
            {
                ChangeRequestId = this.Id,
                ChangeDetails   = new List <string>()
            };

            if (rockContext == null)
            {
                rockContext = new RockContext();
            }
            using (var dbContextTransaction = rockContext.Database.BeginTransaction())
            {
                try
                {
                    IEntity entity = GetEntity(EntityTypeId, EntityId, rockContext);

                    //Make changes
                    foreach (var changeRecord in ChangeRecords.Where(r => r.WasApplied != true && r.IsRejected == false))
                    {
                        var targetEntity = entity;
                        if (changeRecord.RelatedEntityTypeId.HasValue)
                        {
                            if (changeRecord.RelatedEntityId.HasValue &&
                                !(changeRecord.RelatedEntityId == 0 || changeRecord.Action == ChangeRecordAction.Create))
                            {
                                //existing entity
                                targetEntity = GetEntity(changeRecord.RelatedEntityTypeId.Value, changeRecord.RelatedEntityId.Value, rockContext);
                            }
                            else
                            {
                                //new entity
                                targetEntity = CreateNewEntity(changeRecord.RelatedEntityTypeId.Value, changeRecord.NewValue, rockContext);
                                changeRecord.RelatedEntityId = targetEntity.Id;

                                //if we add a phone number add that to the change list
                                if (targetEntity?.GetType() == typeof(PhoneNumber))
                                {
                                    var number     = targetEntity as PhoneNumber;
                                    var numberType = DefinedValueCache.GetValue(number.NumberTypeValueId.Value);
                                    securityChangeDetail.ChangeDetails.Add(string.Format("Added {0} phone number {1}", numberType, number.NumberFormatted));
                                }
                            }
                        }

                        //Some times entitities can be deleted (such as a binary file being cleaned up)
                        //And cannot update, delete or change and attribute on it anymore
                        if (targetEntity == null)
                        {
                            continue;
                        }

                        //Remove records marked as delete
                        if (changeRecord.Action == ChangeRecordAction.Delete)
                        {
                            DeleteEntity(targetEntity, rockContext);
                        }
                        else if (changeRecord.Action == ChangeRecordAction.Attribute)
                        {
                            UpdateAttribute(targetEntity, changeRecord.Property, changeRecord.NewValue, rockContext);
                        }
                        else if (changeRecord.Property.IsNotNullOrWhiteSpace())
                        {
                            PropertyInfo prop = targetEntity.GetType().GetProperty(changeRecord.Property, BindingFlags.Public | BindingFlags.Instance);

                            if (prop != null && prop.PropertyType.GetInterfaces().Any(i => i.IsInterface && i.GetInterfaces().Contains(typeof(IEntity))))
                            {
                                PropertyInfo propId    = targetEntity.GetType().GetProperty(changeRecord.Property + "Id", BindingFlags.Public | BindingFlags.Instance);
                                var          newObject = changeRecord.NewValue.FromJsonOrNull <BasicEntity>();
                                prop.SetValue(targetEntity, null, null);
                                if (newObject != null)
                                {
                                    propId.SetValue(targetEntity, newObject.Id);
                                }
                                else
                                {
                                    propId.SetValue(targetEntity, null, null);
                                }
                            }
                            else
                            {
                                SetProperty(targetEntity, prop, changeRecord.NewValue);
                            }
                        }
                        changeRecord.WasApplied = true;

                        //Check to see if the email address was changed
                        var targetEntityType = targetEntity?.GetType();
                        if (targetEntityType?.BaseType == typeof(Person) && // is a person
                            changeRecord.Property == "Email" && // and changed email
                            changeRecord.OldValue.IsNotNullOrWhiteSpace() && //old value isn't blank
                            changeRecord.NewValue.IsNotNullOrWhiteSpace()    //new value isn't blank
                            )
                        {
                            securityChangeDetail.ChangeDetails.Add(string.Format("Changed email address from {0} to {1}", changeRecord.OldValue, changeRecord.NewValue));
                            securityChangeDetail.CurrentEmail  = changeRecord.NewValue;
                            securityChangeDetail.PreviousEmail = changeRecord.OldValue;
                        }

                        //Check to see if the phone number was changed
                        if (targetEntityType?.BaseType == typeof(PhoneNumber) && //is a phonenuumber
                            changeRecord.Property == "Number"     //is a number change
                            )
                        {
                            var number     = targetEntity as PhoneNumber;
                            var numberType = DefinedValueCache.GetValue(number.NumberTypeValueId.Value);
                            securityChangeDetail.ChangeDetails.Add(string.Format("Changed {0} phone number from {1} to {2}",
                                                                                 numberType,
                                                                                 PhoneNumber.FormattedNumber(PhoneNumber.DefaultCountryCode(), changeRecord.OldValue),
                                                                                 PhoneNumber.FormattedNumber(PhoneNumber.DefaultCountryCode(), changeRecord.NewValue)));
                        }
                    }

                    //Undo Changes
                    foreach (var changeRecord in ChangeRecords.Where(r => r.WasApplied == true && r.IsRejected == true))
                    {
                        var targetEntity = entity;

                        if (changeRecord.RelatedEntityTypeId.HasValue && changeRecord.Action != ChangeRecordAction.Delete)
                        {
                            if (changeRecord.RelatedEntityId.HasValue && changeRecord.Action != ChangeRecordAction.Create)
                            {
                                //existing entity
                                targetEntity = GetEntity(changeRecord.RelatedEntityTypeId.Value, changeRecord.RelatedEntityId.Value, rockContext);
                            }
                            else
                            {
                                //This was a created entity that we must now murder in cold blood.
                                targetEntity = GetEntity(changeRecord.RelatedEntityTypeId.Value, changeRecord.RelatedEntityId.Value, rockContext);
                                DeleteEntity(targetEntity, rockContext);
                                changeRecord.WasApplied = false;
                                continue;
                            }
                        }

                        //Undelete
                        if (changeRecord.RelatedEntityTypeId.HasValue && changeRecord.Action == ChangeRecordAction.Delete)
                        {
                            targetEntity = CreateNewEntity(changeRecord.RelatedEntityTypeId.Value, changeRecord.OldValue, rockContext);
                            changeRecord.RelatedEntityId = targetEntity.Id;
                        }
                        else if (changeRecord.Action == ChangeRecordAction.Attribute)
                        {
                            UpdateAttribute(targetEntity, changeRecord.Property, changeRecord.OldValue, rockContext);
                        }
                        //Property changes
                        else if (changeRecord.Property.IsNotNullOrWhiteSpace())
                        {
                            PropertyInfo prop = targetEntity?.GetType()?.GetProperty(changeRecord.Property, BindingFlags.Public | BindingFlags.Instance);
                            if (targetEntity == null || prop == null)
                            {
                                //Entity was probably deleted after the change request
                                continue;
                            }

                            if (prop.PropertyType.GetInterfaces().Any(i => i.IsInterface && i.GetInterfaces().Contains(typeof(IEntity))))
                            {
                                PropertyInfo propId    = targetEntity.GetType().GetProperty(changeRecord.Property + "Id", BindingFlags.Public | BindingFlags.Instance);
                                var          oldObject = changeRecord.OldValue.FromJsonOrNull <BasicEntity>();
                                prop.SetValue(targetEntity, null, null);
                                if (oldObject != null)
                                {
                                    propId.SetValue(targetEntity, oldObject.Id);
                                }
                                else
                                {
                                    propId.SetValue(targetEntity, null, null);
                                }
                            }
                            else
                            {
                                SetProperty(targetEntity, prop, changeRecord.OldValue);
                            }
                        }
                        changeRecord.WasApplied = false;
                    }


                    rockContext.SaveChanges();
                    dbContextTransaction.Commit();

                    if (entity.GetType()?.BaseType == typeof(Person) && securityChangeDetail.ChangeDetails.Any())
                    {
                        var workflowGuid = GlobalAttributesCache.Get().GetValue("ChangeManagerSecurityWorkflow").AsGuidOrNull();
                        this.LaunchWorkflow(workflowGuid,
                                            "Change Request Security Notice",
                                            new Dictionary <string, string> {
                            { "ChangeDetail", securityChangeDetail.ToJson() }
                        });
                    }
                }
                catch (Exception e)
                {
                    dbContextTransaction.Rollback();
                    throw new Exception("Exception occured durring saving changes.", e);
                }
            }
        }