I created an app for SharePoint Online that attach a ListAddedEvent
to a site, and brake permissions on a specific folder, when a document library is created.
the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Client;
using Microsoft.SharePoint.Client.EventReceivers;
using System.ServiceModel;
using System.ServiceModel.Channels;
using log4net;
namespace BreakPermissionsRERWeb.Services
{
public class AppEventReceiver : IRemoteEventService
{
private static readonly ILog Logger = LogManager.GetLogger(typeof(AppEventReceiver));
private const string RECEIVER_NAME = "ListAddedEvent";
private const string Folder_Name = "test1";
public SPRemoteEventResult ProcessEvent(SPRemoteEventProperties properties)
{
SPRemoteEventResult result = new SPRemoteEventResult();
switch (properties.EventType)
{
case SPRemoteEventType.AppInstalled:
HandleAppInstalled(properties);
break;
case SPRemoteEventType.AppUninstalling:
HandleAppUninstalling(properties);
break;
case SPRemoteEventType.ListAdded:
HandleListAdded(properties);
break;
}
return result;
}
private void HandleAppInstalled(SPRemoteEventProperties properties)
{
using (ClientContext cc = TokenHelper.CreateAppEventClientContext(properties, false))
{
if (cc != null)
{
bool rerExists = false;
cc.Load(cc.Web.EventReceivers);
cc.ExecuteQuery();
foreach (var rer in cc.Web.EventReceivers)
{
if (rer.ReceiverName == RECEIVER_NAME)
{
rerExists = true;
Logger.Info("Found existing ListAdded receiver at " + rer.ReceiverUrl);
}
}
if (!rerExists)
{
EventReceiverDefinitionCreationInformation receiver = new EventReceiverDefinitionCreationInformation();
receiver.EventType = EventReceiverType.ListAdded;
OperationContext op = OperationContext.Current;
Message msg = op.RequestContext.RequestMessage;
receiver.ReceiverUrl = msg.Headers.To.ToString();
receiver.ReceiverName = RECEIVER_NAME;
receiver.Synchronization = EventReceiverSynchronization.Synchronous;
cc.Web.EventReceivers.Add(receiver);
cc.ExecuteQuery();
Logger.Info("Added ListAdded receiver at " + msg.Headers.To.ToString());
}
}
}
}
private void HandleAppUninstalling(SPRemoteEventProperties properties)
{
using (ClientContext cc = TokenHelper.CreateAppEventClientContext(properties, false))
{
if (cc != null)
{
cc.Load(cc.Web.EventReceivers);
cc.ExecuteQuery();
var rer = cc.Web.EventReceivers.Where(e => e.ReceiverName == RECEIVER_NAME).FirstOrDefault();
try
{
Logger.Info("Removing ListAdded receiver at " + rer.ReceiverUrl);
rer.DeleteObject();
cc.ExecuteQuery();
}
catch (Exception ex)
{
Logger.Error(ex);
System.Diagnostics.Trace.WriteLine(ex.Message);
}
}
}
}
public void ProcessOneWayEvent(SPRemoteEventProperties properties)
{
throw new NotImplementedException();
}
}
}
In the development site this work perfectly, but in the production site i got an access denied error on the removal of the remote event receiver using the AppUninstall
event.
I deleted all the apps but the remote event receivers are still attached to the site.
So i created an app to remove all the remote event receivers and I'm still getting the access denied error.
I tried to check and unchecked the allow the app to make app only calls to SharePoint and the app permissions is set to Full Control on both the web and site collection.
Is there a way to resolve the issue?
the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Client;
using Microsoft.SharePoint.Client.EventReceivers;
using log4net;
namespace RemoveAllRERWeb.Services
{
public class AppEventReceiver : IRemoteEventService
{
private static readonly ILog Logger = LogManager.GetLogger(typeof(AppEventReceiver));
private const string RECEIVER_NAME = "ListAddedEvent";
public SPRemoteEventResult ProcessEvent(SPRemoteEventProperties properties)
{
SPRemoteEventResult result = new SPRemoteEventResult();
System.Net.ServicePointManager.Expect100Continue = false;
switch (properties.EventType)
{
case SPRemoteEventType.AppInstalled:
HandleAppInstalled(properties);
break;
}
return result;
}
private void HandleAppInstalled(SPRemoteEventProperties properties)
{
using (ClientContext cc = TokenHelper.CreateAppEventClientContext(properties, false))
{
if (cc != null)
{
cc.Load(cc.Web.EventReceivers);
cc.ExecuteQuery();
try
{
Logger.Info("======================================");
Logger.Info("Remote Event Receivers List:");
foreach (var rer in cc.Web.EventReceivers)
{
Logger.Info(rer.ReceiverName);
}
Logger.Info("End Of List");
Logger.Info("=======================================");
}
catch (Exception ex)
{
Logger.Error(ex);
}
try
{
cc.Load(cc.Web.EventReceivers);
cc.ExecuteQuery();
Logger.Info("----******* start deleting **********---------");
foreach (var rer in cc.Web.EventReceivers)
{
if (rer.ReceiverName == RECEIVER_NAME)
{
Logger.Info(rer.ReceiverName);
rer.DeleteObject();
cc.ExecuteQuery();
}
}
Logger.Info("----******* deleting end **********---------");
}
catch (Exception ex)
{
Logger.Error(ex);
}
}
}
}
public void ProcessOneWayEvent(SPRemoteEventProperties properties)
{
throw new NotImplementedException();
}
}
}