hi,
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); } } } } private void HandleListAdded(SPRemoteEventProperties properties) { using (ClientContext cc = TokenHelper.CreateRemoteEventReceiverClientContext(properties)) { if (cc == null) { Logger.Info("cc null"); Logger.Info("\\"); return; } Logger.Info("using start"); Logger.Info("\\"); try { if (properties.ListEventProperties.TemplateId != (int)ListTemplateType.DocumentLibrary) { Logger.Info("Template is not a Document Library"); Logger.Info("\\"); return; } while (cc.Web.Lists.GetById(properties.ListEventProperties.ListId) == null) { Logger.Info("list still not created"); Logger.Info("\\"); System.Threading.Thread.Sleep(1000); } Logger.Info("list was created"); Logger.Info("\\"); List myList = cc.Web.Lists.GetById(properties.ListEventProperties.ListId); cc.Load(myList); cc.ExecuteQuery(); CamlQuery query = new CamlQuery(); query.ViewXml = ""; ListItemCollection items = myList.GetItems(query); cc.Load(items); cc.ExecuteQuery(); while (items.Count == 0) { Logger.Info("no items yet... "); Logger.Info("\\"); System.Threading.Thread.Sleep(1000); items = myList.GetItems(query); cc.Load(items); cc.ExecuteQuery(); } Logger.Info("items exists ... "); Logger.Info("\\"); foreach (ListItem myitem in items) { string FileLeafRef = myitem["FileLeafRef"].ToString(); if (FileLeafRef == Folder_Name) { Logger.Info("FileLeafRef == Folder_Name "); Logger.Info("\\"); myitem.BreakRoleInheritance(false, true); cc.ExecuteQuery(); Logger.Info("BreakRoleInheritance"); Logger.Info("\\"); RoleDefinition Role = cc.Web.RoleDefinitions.GetById(1073741829); RoleDefinitionBindingCollection RoleColl = new RoleDefinitionBindingCollection(cc); RoleColl.Add(Role); Principal principalId = cc.Web.SiteGroups.GetById(71); myitem.RoleAssignments.Add(principalId, RoleColl); cc.ExecuteQuery(); Logger.Info("Break Permissions RER ended"); Logger.Info("\\"); } } } 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(); } } }