Vulnerability in EPiServer.Forms

Try our conversational search powered by Generative AI!

IsDeleted propert on MovedContent (IContentEvents)

Vote:
 

When putting content in the recycle bin the MovedContent event is fired in the IContentEvents repository. However at that time the IsDeleted property is still set to false on e.Content.IsDeleted even though if you look in the database at the same time you can see that the Deleted column is set to 1. Why is that and is there a better way of checking if a page is moved to recycle bin other than looking at the TargetLink property of the ContentEventArgs?

#150190
Jun 13, 2016 17:04
Vote:
 

What if you get a fresh instance of the page from content repository at moved event?

#150192
Jun 13, 2016 17:36
Vote:
 

Same thing then. 

Just realized that e.Content (or if you fetch from IContentRepository) is exactly the same on MovedContent as it is in MovingContent. Shouldn't MovedContent show how the content looks after the move or am i misunderstanding something?

#150194
Jun 13, 2016 18:15
Vote:
 

This got to be considered a bug.

Just reflected the EPiServer.Core.dll and looked in the DefaultContentRepository.cs file. Here we can see what happens when you move something to waste basket:

		public override void MoveToWastebasket(ContentReference contentLink, string deletedBy)
		{
			if (ContentReference.IsNullOrEmpty(contentLink))
			{
				throw new System.ArgumentNullException("contentLink", "Parameter has no value set");
			}
			ContentProvider provider = this._providerManager.GetProvider(contentLink.ProviderName);
			DefaultContentRepository.CheckCapabilities(provider, ContentProviderCapabilities.Delete);
			ContentReference contentLink2 = contentLink.ToReferenceWithoutVersion();
			IContent content = this.Get<IContent>(contentLink2, NullLanguageSelector.Instance);
			ContentEventArgs eventArgs = new MoveContentEventArgs(contentLink, provider.WastebasketReference)
			{
				RequiredAccess = AccessLevel.Delete,
				OriginalParent = content.ParentLink,
				Descendents = this.GetDescendents(contentLink),
				Content = content
			};
			this._contentEventsHandler.RaiseCancellableContentEvent("MovingEvent", "Moving content was cancelled by event handler.", eventArgs);
			if (!this._accessChecker.HasSufficientAccess(provider, contentLink, AccessLevel.Delete))
			{
				throw new AccessDeniedException(contentLink, string.Format("The current user does not have sufficient rights to delete the page with id {0}", contentLink));
			}
			if (provider.IsDefaultProvider && this._providerManager.HasEntryPointChild(contentLink))
			{
				throw new CannotMoveProviderException("This page or some of it's descendants is parent to a page provider and it can't be deleted. Please remove page provider first in web.config file.");
			}
			provider.MoveToWastebasket(contentLink, deletedBy);
			this._contentEventsHandler.RaiseContentEvent("MovedEvent", eventArgs);
		}

As you see, the same eventArgs are sent to both MovingEvent and MovedEvent so no wonder that e.Content looks the same on both events. Not sure if this might have been fixed in later versions of EPiServer. (this customer is running epi 7.5).

If we look into the Publish method....

		internal override void Publish(ContentReference contentLink, System.DateTime? delayPublishUntil, AccessLevel access)
		{
			if (ContentReference.IsNullOrEmpty(contentLink))
			{
				throw new System.ArgumentNullException("contentLink");
			}
			if (contentLink.WorkID == 0)
			{
				throw new System.ArgumentException("The version must be specified when publishing content", "contentLink");
			}
			if (delayPublishUntil.HasValue && !PropertyDate.IsValidDate(delayPublishUntil.Value))
			{
				throw new System.ArgumentOutOfRangeException("delayPublishUntil", string.Format("Publish date '{0}' must be a date between '{1}' and '{2}'.", delayPublishUntil.Value, PropertyDate.MinValue, PropertyDate.MaxValue));
			}
			IContent content = this.Get<IContent>(contentLink, NullLanguageSelector.Instance);
			bool hasValue = delayPublishUntil.HasValue;
			SaveAction action = hasValue ? ((SaveAction)1026) : SaveAction.Publish;
			SaveContentEventArgs saveContentEventArgs = this._contentEventsHandler.CreateSaveEventArgs(content, action, access);
			this.RaisePreSaveEvents(saveContentEventArgs, false, false);
			if (!DefaultContentRepository.VerifyPreviousStateForPublishing(saveContentEventArgs.Content))
			{
				return;
			}
			ContentProvider contentProvider = this.GetContentProvider(contentLink, false);
			DefaultContentRepository.CheckCapabilities(contentProvider, ContentProviderCapabilities.Edit);
			this.CheckSufficientAccess(contentProvider, contentLink, access);
			if (!hasValue)
			{
				contentProvider.Validate(content, (SaveAction)515);
			}
			saveContentEventArgs.ContentLink = contentProvider.UpdateStatus(content, action, delayPublishUntil);
			this._cacheManager.RemoveLocal(DataFactoryCache.ContentVersionCacheKey(saveContentEventArgs.ContentLink));
			saveContentEventArgs.Content = this.Get<IContent>(saveContentEventArgs.ContentLink, NullLanguageSelector.Instance);
			this.RaisePostSaveEvents(content, saveContentEventArgs, false, false);
		}

Here we see that before the PublishedContent is called (which is done in the RaisePostSaveEvent method) the code first clears the cache and then repopulates the Content property of the eventargs.

Knowing this I was able to get around the problem by first clearing the episerver cache for this page by calling DataFactoryCache.RemovePage(e.ContentLink) and the fetching the content again by calling ServiceLocator.Current.GetInstance<IContentRepository>().Get<IContent>(e.ContentLink).

#150196
Jun 13, 2016 18:51
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.