public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { // if this is a sub site then we're not provisioning content types. Technically this can be done but it's not a recommended practice if (web.IsSubSite()) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ContentTypes_Context_web_is_subweb__Skipping_content_types_); return parser; } // Check if this is not a noscript site as we're not allowed to update some properties bool isNoScriptSite = web.IsNoScriptSite(); web.Context.Load(web.ContentTypes, ct => ct.IncludeWithDefaultProperties(c => c.StringId, c => c.FieldLinks, c => c.FieldLinks.Include(fl => fl.Id, fl => fl.Required, fl => fl.Hidden))); web.Context.Load(web.Fields, fld => fld.IncludeWithDefaultProperties(f => f.Id)); web.Context.ExecuteQueryRetry(); var existingCTs = web.ContentTypes.ToList(); var existingFields = web.Fields.ToList(); foreach (var ct in template.ContentTypes.OrderBy(ct => ct.Id)) // ordering to handle references to parent content types that can be in the same template { var existingCT = existingCTs.FirstOrDefault(c => c.StringId.Equals(ct.Id, StringComparison.OrdinalIgnoreCase)); if (existingCT == null) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ContentTypes_Creating_new_Content_Type___0_____1_, ct.Id, ct.Name); var newCT = CreateContentType(web, ct, parser, template.Connector ?? null, scope, existingCTs, existingFields, isNoScriptSite); if (newCT != null) { existingCTs.Add(newCT); } } else { if (ct.Overwrite) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ContentTypes_Recreating_existing_Content_Type___0_____1_, ct.Id, ct.Name); existingCT.DeleteObject(); web.Context.ExecuteQueryRetry(); var newCT = CreateContentType(web, ct, parser, template.Connector ?? null, scope, existingCTs, existingFields, isNoScriptSite); if (newCT != null) { existingCTs.Add(newCT); } } else { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ContentTypes_Updating_existing_Content_Type___0_____1_, ct.Id, ct.Name); UpdateContentType(web, existingCT, ct, parser, scope, isNoScriptSite); } } } } return parser; }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { // if this is a sub site then we're not provisioning fields. Technically this can be done but it's not a recommended practice if (web.IsSubSite()) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Fields_Context_web_is_subweb__skipping_site_columns); return parser; } var existingFields = web.Fields; web.Context.Load(existingFields, fs => fs.Include(f => f.Id)); web.Context.ExecuteQueryRetry(); var existingFieldIds = existingFields.AsEnumerable<SPField>().Select(l => l.Id).ToList(); var fields = template.SiteFields; foreach (var field in fields) { XElement templateFieldElement = XElement.Parse(parser.ParseString(field.SchemaXml, "~sitecollection", "~site")); var fieldId = templateFieldElement.Attribute("ID").Value; if (!existingFieldIds.Contains(Guid.Parse(fieldId))) { try { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Fields_Adding_field__0__to_site, fieldId); CreateField(web, templateFieldElement, scope, parser, field.SchemaXml); } catch (Exception ex) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_Fields_Adding_field__0__failed___1_____2_, fieldId, ex.Message, ex.StackTrace); throw; } } else try { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Fields_Updating_field__0__in_site, fieldId); UpdateField(web, fieldId, templateFieldElement, scope, parser, field.SchemaXml); } catch (Exception ex) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_Fields_Updating_field__0__failed___1_____2_, fieldId, ex.Message, ex.StackTrace); throw; } } } return parser; }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { var context = web.Context as ClientContext; foreach (var handler in template.ExtensibilityHandlers .Union(template.Providers) .Union(applyingInformation.ExtensibilityHandlers)) { if (handler.Enabled) { try { if (!string.IsNullOrEmpty(handler.Configuration)) { //replace tokens in configuration data handler.Configuration = parser.ParseString(handler.Configuration); } scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ExtensibilityProviders_Calling_extensibility_callout__0_, handler.Assembly); _extManager.ExecuteExtensibilityProvisionCallOut(context, handler, template, applyingInformation, parser, scope); } catch (Exception ex) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_ExtensibilityProviders_callout_failed___0_____1_, ex.Message, ex.StackTrace); throw; } } } } return parser; }
public TokenParser AddExtendedTokens(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { var context = web.Context as ClientContext; foreach (var provider in template.Providers) { if (provider.Enabled) { try { if (!string.IsNullOrEmpty(provider.Configuration)) { provider.Configuration = parser.ParseString(provider.Configuration); } scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ExtensibilityProviders_Calling_tokenprovider_extensibility_callout__0_, provider.Assembly); var _providedTokens = _extManager.ExecuteTokenProviderCallOut(context, provider, template); if (_providedTokens != null) { foreach (var token in _providedTokens) { parser.AddToken(token); } } } catch (Exception ex) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_ExtensibilityProviders_tokenprovider_callout_failed___0_____1_, ex.Message, ex.StackTrace); throw; } } } return parser; } }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { var context = web.Context as ClientContext; foreach (var provider in template.Providers) { if (provider.Enabled) { try { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ExtensibilityProviders_Calling_extensibility_callout__0_, provider.Assembly); _extManager.ExecuteExtensibilityCallOut(context, provider, template); } catch (Exception ex) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ExtensibilityProviders_callout_failed___0_____1_, ex.Message, ex.StackTrace); } } } } return parser; }
public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(CoreResources.Provisioning_ObjectHandlers_CustomActions)) { var context = web.Context as ClientContext; bool isSubSite = web.IsSubSite(); var webCustomActions = web.GetCustomActions(); var siteCustomActions = context.Site.GetCustomActions(); var customActions = new CustomActions(); foreach (var customAction in webCustomActions) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Adding_web_scoped_custom_action___0___to_template, customAction.Name); customActions.WebCustomActions.Add(CopyUserCustomAction(customAction)); } // if this is a sub site then we're not creating entities for site collection scoped custom actions if (!isSubSite) { foreach (var customAction in siteCustomActions) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Adding_site_scoped_custom_action___0___to_template, customAction.Name); customActions.SiteCustomActions.Add(CopyUserCustomAction(customAction)); } } template.CustomActions = customActions; // If a base template is specified then use that one to "cleanup" the generated template model if (creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate, isSubSite, scope); } } return template; }
public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(CoreResources.Provisioning_ObjectHandlers_ContentTypes)) { // if this is a sub site then we're not creating content type entities. if (web.IsSubSite()) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ContentTypes_Context_web_is_subweb__Skipping_content_types_); return template; } template.ContentTypes.AddRange(GetEntities(web, scope)); // If a base template is specified then use that one to "cleanup" the generated template model if (creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate, scope); } } return template; }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { if (template.Lists.Any()) { var rootWeb = (web.Context as ClientContext).Site.RootWeb; #region DataRows foreach (var listInstance in template.Lists) { if (listInstance.DataRows != null && listInstance.DataRows.Any()) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Processing_data_rows_for__0_, listInstance.Title); // Retrieve the target list var list = web.Lists.GetByTitle(listInstance.Title); web.Context.Load(list); web.Context.ExecuteQueryRetry(); ListItemsProvider provider = new ListItemsProvider(list, web, template); provider.AddListItems(listInstance.DataRows, template, parser, scope); if (null == m_listContentProviders) { m_listContentProviders = new Dictionary<Guid, ListItemsProvider>(); } m_listContentProviders[list.Id] = provider; } } UpdateLookupValues(web, scope); #endregion } } return parser; }
public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { var context = web.Context as ClientContext; foreach (var handler in creationInfo.ExtensibilityHandlers) { if (handler.Enabled) { try { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ExtensibilityProviders_Calling_extensibility_callout__0_, handler.Assembly); template = _extManager.ExecuteExtensibilityExtractionCallOut(context, handler, template, creationInfo, scope); } catch (Exception ex) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_ExtensibilityProviders_callout_failed___0_____1_, ex.Message, ex.StackTrace); throw; } } } } return template; }
public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { // Load object if not there #if !CLIENTSDKV15 web.EnsureProperties(w => w.Url, w => w.MasterUrl, w => w.AlternateCssUrl, w => w.SiteLogoUrl); #else web.EnsureProperties(w => w.Url, w => w.MasterUrl); #endif // Information coming from the site template.ComposedLook.MasterPage = Tokenize(web.MasterUrl, web.Url); #if !CLIENTSDKV15 template.ComposedLook.AlternateCSS = Tokenize(web.AlternateCssUrl, web.Url); template.ComposedLook.SiteLogo = Tokenize(web.SiteLogoUrl, web.Url); #else template.ComposedLook.AlternateCSS = null; template.ComposedLook.SiteLogo = null; #endif scope.LogInfo(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Retrieving_current_composed_look); var theme = web.GetCurrentComposedLook(); if (theme != null) { if (creationInfo != null) { // Don't exclude the DesignPreviewThemedCssFolderUrl property bag, if any creationInfo.PropertyBagPropertiesToPreserve.Add("DesignPreviewThemedCssFolderUrl"); } template.ComposedLook.Name = theme.Name; if (theme.IsCustomComposedLook) { if (creationInfo != null && creationInfo.PersistComposedLookFiles && creationInfo.FileConnector != null) { Site site = (web.Context as ClientContext).Site; if (!site.IsObjectPropertyInstantiated("Url")) { web.Context.Load(site); web.Context.ExecuteQueryRetry(); } scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Creating_SharePointConnector); // Let's create a SharePoint connector since our files anyhow are in SharePoint at this moment SharePointConnector spConnector = new SharePointConnector(web.Context, web.Url, "dummy"); // to get files from theme catalog we need a connector linked to the root site SharePointConnector spConnectorRoot; if (!site.Url.Equals(web.Url, StringComparison.InvariantCultureIgnoreCase)) { spConnectorRoot = new SharePointConnector(web.Context.Clone(site.Url), site.Url, "dummy"); } else { spConnectorRoot = spConnector; } // Download the theme/branding specific files DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, web.AlternateCssUrl, scope); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, web.SiteLogoUrl, scope); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.BackgroundImage, scope); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.Theme, scope); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.Font, scope); } template.ComposedLook.BackgroundFile = FixFileUrl(Tokenize(theme.BackgroundImage, web.Url)); template.ComposedLook.ColorFile = FixFileUrl(Tokenize(theme.Theme, web.Url)); template.ComposedLook.FontFile = FixFileUrl(Tokenize(theme.Font, web.Url)); // Create file entries for the custom theme files if (!string.IsNullOrEmpty(template.ComposedLook.BackgroundFile)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.BackgroundFile)); } if (!string.IsNullOrEmpty(template.ComposedLook.ColorFile)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.ColorFile)); } if (!string.IsNullOrEmpty(template.ComposedLook.FontFile)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.FontFile)); } if (!string.IsNullOrEmpty(template.ComposedLook.SiteLogo)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.SiteLogo)); } // If a base template is specified then use that one to "cleanup" the generated template model if (creationInfo != null && creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate); } } else { template.ComposedLook.BackgroundFile = ""; template.ComposedLook.ColorFile = ""; template.ComposedLook.FontFile = ""; } } else { template.ComposedLook = null; } if (creationInfo != null && creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate); } } return template; }
private void ProvisionCustomActionImplementation(object parent, CustomActionCollection customActions, TokenParser parser, PnPMonitoredScope scope) { Web web = null; Site site = null; if (parent is Site) { site = parent as Site; // Switch parser context; parser.Rebase(site.RootWeb); } else { web = parent as Web; // Switch parser context parser.Rebase(web); } foreach (var customAction in customActions) { var caExists = false; if (site != null) { caExists = site.CustomActionExists(customAction.Name); } else { caExists = web.CustomActionExists(customAction.Name); } // If the CustomAction does not exist, we don't have to remove it, and it is enabled if (!caExists && !customAction.Remove && customAction.Enabled) { // Then we add it to the target var customActionEntity = new CustomActionEntity() { CommandUIExtension = customAction.CommandUIExtension != null ? parser.ParseString(customAction.CommandUIExtension.ToString()) : string.Empty, Description = parser.ParseString(customAction.Description), Group = customAction.Group, ImageUrl = parser.ParseString(customAction.ImageUrl), Location = customAction.Location, Name = customAction.Name, RegistrationId = customAction.RegistrationId, RegistrationType = customAction.RegistrationType, Remove = customAction.Remove, Rights = customAction.Rights, ScriptBlock = parser.ParseString(customAction.ScriptBlock), ScriptSrc = parser.ParseString(customAction.ScriptSrc, "~site", "~sitecollection"), Sequence = customAction.Sequence, Title = parser.ParseString(customAction.Title), Url = parser.ParseString(customAction.Url) }; if (site != null) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Adding_custom_action___0___to_scope_Site, customActionEntity.Name); site.AddCustomAction(customActionEntity); #if !ONPREMISES if ((!string.IsNullOrEmpty(customAction.Title) && customAction.Title.ContainsResourceToken()) || (!string.IsNullOrEmpty(customAction.Description) && customAction.Description.ContainsResourceToken())) { var uca = site.GetCustomActions().Where(uc => uc.Name == customAction.Name).FirstOrDefault(); SetCustomActionResourceValues(parser, customAction, uca); } #endif } else { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Adding_custom_action___0___to_scope_Web, customActionEntity.Name); web.AddCustomAction(customActionEntity); #if !ONPREMISES if (customAction.Title.ContainsResourceToken() || customAction.Description.ContainsResourceToken()) { var uca = web.GetCustomActions().Where(uc => uc.Name == customAction.Name).FirstOrDefault(); SetCustomActionResourceValues(parser, customAction, uca); } #endif } } else { UserCustomAction existingCustomAction = null; if (site != null) { existingCustomAction = site.GetCustomActions().FirstOrDefault(c => c.Name == customAction.Name); } else { existingCustomAction = web.GetCustomActions().FirstOrDefault(c => c.Name == customAction.Name); } if (existingCustomAction != null) { // If we have to remove the existing CustomAction if (customAction.Remove) { // We simply remove it existingCustomAction.DeleteObject(); existingCustomAction.Context.ExecuteQueryRetry(); } else { UpdateCustomAction(parser, scope, customAction, existingCustomAction); } } } } }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { var context = web.Context as ClientContext; web.EnsureProperties(w => w.ServerRelativeUrl, w => w.Url); foreach (var file in template.Files) { var folderName = parser.ParseString(file.Folder); if (folderName.ToLower().StartsWith((web.ServerRelativeUrl.ToLower()))) { folderName = folderName.Substring(web.ServerRelativeUrl.Length); } var folder = web.EnsureFolderPath(folderName); File targetFile = null; var checkedOut = false; targetFile = folder.GetFile(template.Connector.GetFilenamePart(file.Src)); if (targetFile != null) { if (file.Overwrite) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Files_Uploading_and_overwriting_existing_file__0_, file.Src); checkedOut = CheckOutIfNeeded(web, targetFile); using (var stream = GetFileStream(template, file)) { targetFile = UploadFile(template, file, folder, stream); } } else { checkedOut = CheckOutIfNeeded(web, targetFile); } } else { using (var stream = GetFileStream(template, file)) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Files_Uploading_file__0_, file.Src); targetFile = UploadFile(template, file, folder, stream); } checkedOut = CheckOutIfNeeded(web, targetFile); } if (targetFile != null) { if (file.Properties != null && file.Properties.Any()) { Dictionary<string, string> transformedProperties = file.Properties.ToDictionary(property => property.Key, property => parser.ParseString(property.Value)); SetFileProperties(targetFile, transformedProperties, false); } if (file.WebParts != null && file.WebParts.Any()) { targetFile.EnsureProperties(f => f.ServerRelativeUrl); var existingWebParts = web.GetWebParts(targetFile.ServerRelativeUrl); foreach (var webpart in file.WebParts) { // check if the webpart is already set on the page if (existingWebParts.FirstOrDefault(w => w.WebPart.Title == webpart.Title) == null) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Files_Adding_webpart___0___to_page, webpart.Title); var wpEntity = new WebPartEntity(); wpEntity.WebPartTitle = webpart.Title; wpEntity.WebPartXml = parser.ParseString(webpart.Contents).Trim(new[] { '\n', ' ' }); wpEntity.WebPartZone = webpart.Zone; wpEntity.WebPartIndex = (int)webpart.Order; web.AddWebPartToWebPartPage(targetFile.ServerRelativeUrl, wpEntity); } } } if (checkedOut) { targetFile.CheckIn("", CheckinType.MajorCheckIn); web.Context.ExecuteQueryRetry(); } // Don't set security when nothing is defined. This otherwise breaks on files set outside of a list if (file.Security != null && (file.Security.ClearSubscopes == true || file.Security.CopyRoleAssignments == true || file.Security.RoleAssignments.Count > 0)) { targetFile.ListItemAllFields.SetSecurity(parser, file.Security); } } } } return parser; }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { var context = web.Context as ClientContext; web.EnsureProperties(w => w.ServerRelativeUrl, w => w.RootFolder.WelcomePage); foreach (var page in template.Pages) { var url = parser.ParseString(page.Url); if (!url.ToLower().StartsWith(web.ServerRelativeUrl.ToLower())) { url = UrlUtility.Combine(web.ServerRelativeUrl, url); } var exists = true; Microsoft.SharePoint.Client.File file = null; try { file = web.GetFileByServerRelativeUrl(url); web.Context.Load(file); web.Context.ExecuteQuery(); } catch (ServerException ex) { if (ex.ServerErrorTypeName == "System.IO.FileNotFoundException") { exists = false; } } if (exists) { if (page.Overwrite) { try { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Pages_Overwriting_existing_page__0_, url); if (page.WelcomePage && url.Contains(web.RootFolder.WelcomePage)) { web.SetHomePage(string.Empty); } file.DeleteObject(); web.Context.ExecuteQueryRetry(); web.AddWikiPageByUrl(url); if (page.Layout == WikiPageLayout.Custom) { web.AddLayoutToWikiPage(WikiPageLayout.OneColumn, url); } else { web.AddLayoutToWikiPage(page.Layout, url); } } catch (Exception ex) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_Pages_Overwriting_existing_page__0__failed___1_____2_, url, ex.Message, ex.StackTrace); } } } else { try { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Pages_Creating_new_page__0_, url); web.AddWikiPageByUrl(url); if (page.Layout == WikiPageLayout.Custom) { web.AddLayoutToWikiPage(WikiPageLayout.OneColumn, url); } else { web.AddLayoutToWikiPage(page.Layout, url); } } catch (Exception ex) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_Pages_Creating_new_page__0__failed___1_____2_, url, ex.Message, ex.StackTrace); } } if (page.WelcomePage) { web.RootFolder.EnsureProperty(p => p.ServerRelativeUrl); var rootFolderRelativeUrl = url.Substring(web.RootFolder.ServerRelativeUrl.Length); web.SetHomePage(rootFolderRelativeUrl); } if (page.WebParts != null & page.WebParts.Any()) { var existingWebParts = web.GetWebParts(url); foreach (var webpart in page.WebParts) { if (existingWebParts.FirstOrDefault(w => w.WebPart.Title == webpart.Title) == null) { WebPartEntity wpEntity = new WebPartEntity(); wpEntity.WebPartTitle = webpart.Title; wpEntity.WebPartXml = parser.ParseString(webpart.Contents.Trim(new[] { '\n', ' ' })); web.AddWebPartToWikiPage(url, wpEntity, (int)webpart.Row, (int)webpart.Column, false); } } var allWebParts = web.GetWebParts(url); foreach (var webpart in allWebParts) { parser.AddToken(new WebPartIdToken(web, webpart.WebPart.Title, webpart.Id)); } } file = web.GetFileByServerRelativeUrl(url); file.EnsureProperty(f => f.ListItemAllFields); if (page.Fields.Any()) { var item = file.ListItemAllFields; foreach (var fieldValue in page.Fields) { item[fieldValue.Key] = parser.ParseString(fieldValue.Value); } item.Update(); web.Context.ExecuteQueryRetry(); } if (page.Security != null && page.Security.RoleAssignments.Count != 0) { web.Context.Load(file.ListItemAllFields); web.Context.ExecuteQuery(); file.ListItemAllFields.SetSecurity(parser, page.Security); } } } return(parser); }
public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { GlobalNavigationType globalNavigationType; CurrentNavigationType currentNavigationType; // The Navigation handler works only for sites with Publishing Features enabled if (!web.IsPublishingWeb()) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Navigation_Context_web_is_not_publishing); return(template); } // Retrieve the current web navigation settings var navigationSettings = new WebNavigationSettings(web.Context, web); web.Context.Load(navigationSettings, ns => ns.CurrentNavigation, ns => ns.GlobalNavigation); web.Context.ExecuteQueryRetry(); switch (navigationSettings.GlobalNavigation.Source) { case StandardNavigationSource.InheritFromParentWeb: // Global Navigation is Inherited globalNavigationType = GlobalNavigationType.Inherit; break; case StandardNavigationSource.TaxonomyProvider: // Global Navigation is Managed globalNavigationType = GlobalNavigationType.Managed; break; case StandardNavigationSource.PortalProvider: default: // Global Navigation is Structural globalNavigationType = GlobalNavigationType.Structural; break; } switch (navigationSettings.CurrentNavigation.Source) { case StandardNavigationSource.InheritFromParentWeb: // Current Navigation is Inherited currentNavigationType = CurrentNavigationType.Inherit; break; case StandardNavigationSource.TaxonomyProvider: // Current Navigation is Managed currentNavigationType = CurrentNavigationType.Managed; break; case StandardNavigationSource.PortalProvider: default: // Current Navigation is Structural if (AreSiblingsEnabledForCurrentStructuralNavigation(web)) { currentNavigationType = CurrentNavigationType.Structural; } else { currentNavigationType = CurrentNavigationType.StructuralLocal; } break; } template.Navigation = new Model.Navigation( new GlobalNavigation(globalNavigationType, globalNavigationType == GlobalNavigationType.Structural ? GetGlobalStructuralNavigation(web, navigationSettings) : null, globalNavigationType == GlobalNavigationType.Managed ? GetGlobalManagedNavigation(web, navigationSettings) : null), new CurrentNavigation(currentNavigationType, currentNavigationType == CurrentNavigationType.Structural | currentNavigationType == CurrentNavigationType.StructuralLocal ? GetCurrentStructuralNavigation(web, navigationSettings) : null, currentNavigationType == CurrentNavigationType.Managed ? GetCurrentManagedNavigation(web, navigationSettings) : null) ); } return(template); }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { if (template.Lists.Any()) { var rootWeb = (web.Context as ClientContext).Site.RootWeb; web.EnsureProperties(w => w.ServerRelativeUrl); web.Context.Load(web.Lists, lc => lc.IncludeWithDefaultProperties(l => l.RootFolder.ServerRelativeUrl)); web.Context.ExecuteQueryRetry(); var existingLists = web.Lists.AsEnumerable<List>().Select(existingList => existingList.RootFolder.ServerRelativeUrl).ToList(); var serverRelativeUrl = web.ServerRelativeUrl; #region DataRows foreach (var listInstance in template.Lists) { if (listInstance.DataRows != null && listInstance.DataRows.Any()) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Processing_data_rows_for__0_, listInstance.Title); // Retrieve the target list var list = web.Lists.GetByTitle(listInstance.Title); web.Context.Load(list); // Retrieve the fields' types from the list FieldCollection fields = list.Fields; web.Context.Load(fields, fs => fs.Include(f => f.InternalName, f => f.FieldTypeKind)); web.Context.ExecuteQueryRetry(); foreach (var dataRow in listInstance.DataRows) { try { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Creating_list_item__0_, listInstance.DataRows.IndexOf(dataRow) + 1); var listitemCI = new ListItemCreationInformation(); var listitem = list.AddItem(listitemCI); foreach (var dataValue in dataRow.Values) { Field dataField = fields.FirstOrDefault( f => f.InternalName == parser.ParseString(dataValue.Key)); if (dataField != null) { String fieldValue = parser.ParseString(dataValue.Value); switch (dataField.FieldTypeKind) { case FieldType.Geolocation: // FieldGeolocationValue - Expected format: Altitude,Latitude,Longitude,Measure var geolocationArray = fieldValue.Split(','); if (geolocationArray.Length == 4) { var geolocationValue = new FieldGeolocationValue { Altitude = Double.Parse(geolocationArray[0]), Latitude = Double.Parse(geolocationArray[1]), Longitude = Double.Parse(geolocationArray[2]), Measure = Double.Parse(geolocationArray[3]), }; listitem[parser.ParseString(dataValue.Key)] = geolocationValue; } else { listitem[parser.ParseString(dataValue.Key)] = fieldValue; } break; case FieldType.Lookup: // FieldLookupValue - Expected format: LookupID var lookupValue = new FieldLookupValue { LookupId = Int32.Parse(fieldValue), }; listitem[parser.ParseString(dataValue.Key)] = lookupValue; break; case FieldType.URL: // FieldUrlValue - Expected format: URL,Description var urlArray = fieldValue.Split(','); var linkValue = new FieldUrlValue(); if (urlArray.Length == 2) { linkValue.Url = urlArray[0]; linkValue.Description = urlArray[1]; } else { linkValue.Url = urlArray[0]; linkValue.Description = urlArray[0]; } listitem[parser.ParseString(dataValue.Key)] = linkValue; break; case FieldType.User: // FieldUserValue - Expected format: loginName var user = web.EnsureUser(fieldValue); web.Context.Load(user); web.Context.ExecuteQueryRetry(); if (user != null) { var userValue = new FieldUserValue { LookupId = user.Id, }; listitem[parser.ParseString(dataValue.Key)] = userValue; } else { listitem[parser.ParseString(dataValue.Key)] = fieldValue; } break; default: listitem[parser.ParseString(dataValue.Key)] = fieldValue; break; } } listitem.Update(); } web.Context.ExecuteQueryRetry(); // TODO: Run in batches? if (dataRow.Security != null) { listitem.SetSecurity(parser, dataRow.Security); } } catch (Exception ex) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Creating_listitem_failed___0_____1_, ex.Message, ex.StackTrace); throw; } } } } #endregion } } return parser; }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { // Check if this is not a noscript site as we're not allowed to write to the web property bag is that one bool isNoScriptSite = web.IsNoScriptSite(); var context = web.Context as ClientContext; web.EnsureProperties(w => w.ServerRelativeUrl, w => w.Url); // Build on the fly the list of additional files coming from the Directories var directoryFiles = new List <Model.File>(); foreach (var directory in template.Directories) { var metadataProperties = directory.GetMetadataProperties(); directoryFiles.AddRange(directory.GetDirectoryFiles(metadataProperties)); } var filesToProcess = template.Files.Union(directoryFiles).ToArray(); var currentFileIndex = 0; foreach (var file in filesToProcess) { var targetFileName = !String.IsNullOrEmpty(file.TargetFileName) ? file.TargetFileName : file.Src; currentFileIndex++; WriteMessage($"File|{targetFileName}|{currentFileIndex}|{filesToProcess.Length}", ProvisioningMessageType.Progress); var folderName = parser.ParseString(file.Folder); if (folderName.ToLower().StartsWith((web.ServerRelativeUrl.ToLower()))) { folderName = folderName.Substring(web.ServerRelativeUrl.Length); } if (SkipFile(isNoScriptSite, targetFileName, folderName)) { // add log message scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_Files_SkipFileUpload, targetFileName, folderName); continue; } var folder = web.EnsureFolderPath(folderName); var checkedOut = false; var targetFile = folder.GetFile(template.Connector.GetFilenamePart(targetFileName)); if (targetFile != null) { if (file.Overwrite) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Files_Uploading_and_overwriting_existing_file__0_, targetFileName); checkedOut = CheckOutIfNeeded(web, targetFile); using (var stream = GetFileStream(template, file)) { targetFile = UploadFile(template, file, folder, stream); } } else { checkedOut = CheckOutIfNeeded(web, targetFile); } } else { using (var stream = GetFileStream(template, file)) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Files_Uploading_file__0_, targetFileName); targetFile = UploadFile(template, file, folder, stream); } checkedOut = CheckOutIfNeeded(web, targetFile); } if (targetFile != null) { if (file.Properties != null && file.Properties.Any()) { Dictionary <string, string> transformedProperties = file.Properties.ToDictionary(property => property.Key, property => parser.ParseString(property.Value)); SetFileProperties(targetFile, transformedProperties, false); } #if !SP2013 bool webPartsNeedLocalization = false; #endif if (file.WebParts != null && file.WebParts.Any()) { targetFile.EnsureProperties(f => f.ServerRelativeUrl); var existingWebParts = web.GetWebParts(targetFile.ServerRelativeUrl).ToList(); foreach (var webPart in file.WebParts) { // check if the webpart is already set on the page if (existingWebParts.FirstOrDefault(w => w.WebPart.Title == parser.ParseString(webPart.Title)) == null) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Files_Adding_webpart___0___to_page, webPart.Title); var wpEntity = new WebPartEntity(); wpEntity.WebPartTitle = parser.ParseString(webPart.Title); wpEntity.WebPartXml = parser.ParseXmlString(webPart.Contents).Trim(new[] { '\n', ' ' }); wpEntity.WebPartZone = webPart.Zone; wpEntity.WebPartIndex = (int)webPart.Order; var wpd = web.AddWebPartToWebPartPage(targetFile.ServerRelativeUrl, wpEntity); #if !SP2013 if (webPart.Title.ContainsResourceToken()) { // update data based on where it was added - needed in order to localize wp title #if !SP2016 wpd.EnsureProperties(w => w.ZoneId, w => w.WebPart, w => w.WebPart.Properties); webPart.Zone = wpd.ZoneId; #else wpd.EnsureProperties(w => w.WebPart, w => w.WebPart.Properties); #endif webPart.Order = (uint)wpd.WebPart.ZoneIndex; webPartsNeedLocalization = true; } #endif } } } #if !SP2013 if (webPartsNeedLocalization) { file.LocalizeWebParts(web, parser, targetFile, scope); } #endif switch (file.Level) { case Model.FileLevel.Published: { targetFile.PublishFileToLevel(Microsoft.SharePoint.Client.FileLevel.Published); break; } case Model.FileLevel.Draft: { targetFile.PublishFileToLevel(Microsoft.SharePoint.Client.FileLevel.Draft); break; } default: { if (checkedOut) { targetFile.CheckIn("", CheckinType.MajorCheckIn); web.Context.ExecuteQueryRetry(); } break; } } // Don't set security when nothing is defined. This otherwise breaks on files set outside of a list if (file.Security != null && (file.Security.ClearSubscopes == true || file.Security.CopyRoleAssignments == true || file.Security.RoleAssignments.Count > 0)) { targetFile.ListItemAllFields.SetSecurity(parser, file.Security); } } } } WriteMessage("Done processing files", ProvisioningMessageType.Completed); return(parser); }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { var context = web.Context as ClientContext; web.EnsureProperties(w => w.ServerRelativeUrl, w => w.RootFolder.WelcomePage); // Check if this is not a noscript site as we're not allowed to update some properties bool isNoScriptSite = web.IsNoScriptSite(); foreach (var page in template.Pages) { var url = parser.ParseString(page.Url); if (!url.ToLower().StartsWith(web.ServerRelativeUrl.ToLower())) { url = UrlUtility.Combine(web.ServerRelativeUrl, url); } var exists = true; Microsoft.SharePoint.Client.File file = null; try { file = web.GetFileByServerRelativeUrl(url); web.Context.Load(file); web.Context.ExecuteQueryRetry(); } catch (ServerException ex) { if (ex.ServerErrorTypeName == "System.IO.FileNotFoundException") { exists = false; } } if (exists) { if (page.Overwrite) { try { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Pages_Overwriting_existing_page__0_, url); // determine url of current home page string welcomePageUrl = web.RootFolder.WelcomePage; string welcomePageServerRelativeUrl = welcomePageUrl != null ? UrlUtility.Combine(web.ServerRelativeUrl, web.RootFolder.WelcomePage) : null; bool overwriteWelcomePage = string.Equals(url, welcomePageServerRelativeUrl, StringComparison.InvariantCultureIgnoreCase); // temporarily reset home page so we can delete it if (overwriteWelcomePage) { web.SetHomePage(string.Empty); } file.DeleteObject(); web.Context.ExecuteQueryRetry(); web.AddWikiPageByUrl(url); if (page.Layout == WikiPageLayout.Custom) { web.AddLayoutToWikiPage(WikiPageLayout.OneColumn, url); } else { web.AddLayoutToWikiPage(page.Layout, url); } if (overwriteWelcomePage) { // restore welcome page to previous value web.SetHomePage(welcomePageUrl); } } catch (Exception ex) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_Pages_Overwriting_existing_page__0__failed___1_____2_, url, ex.Message, ex.StackTrace); } } } else { try { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Pages_Creating_new_page__0_, url); web.AddWikiPageByUrl(url); if (page.Layout == WikiPageLayout.Custom) { web.AddLayoutToWikiPage(WikiPageLayout.OneColumn, url); } else { web.AddLayoutToWikiPage(page.Layout, url); } } catch (Exception ex) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_Pages_Creating_new_page__0__failed___1_____2_, url, ex.Message, ex.StackTrace); } } #pragma warning disable 618 if (page.WelcomePage) #pragma warning restore 618 { web.RootFolder.EnsureProperty(p => p.ServerRelativeUrl); var rootFolderRelativeUrl = url.Substring(web.RootFolder.ServerRelativeUrl.Length); web.SetHomePage(rootFolderRelativeUrl); } #if !SP2013 bool webPartsNeedLocalization = false; #endif if (page.WebParts != null & page.WebParts.Any()) { if (!isNoScriptSite) { var existingWebParts = web.GetWebParts(url); foreach (var webPart in page.WebParts) { if (existingWebParts.FirstOrDefault(w => w.WebPart.Title == parser.ParseString(webPart.Title)) == null) { WebPartEntity wpEntity = new WebPartEntity(); wpEntity.WebPartTitle = parser.ParseString(webPart.Title); wpEntity.WebPartXml = parser.ParseXmlString(webPart.Contents.Trim(new[] { '\n', ' ' }), "~sitecollection", "~site"); var wpd = web.AddWebPartToWikiPage(url, wpEntity, (int)webPart.Row, (int)webPart.Column, false); #if !SP2013 if (webPart.Title.ContainsResourceToken()) { // update data based on where it was added - needed in order to localize wp title #if !SP2016 wpd.EnsureProperties(w => w.ZoneId, w => w.WebPart, w => w.WebPart.Properties); webPart.Zone = wpd.ZoneId; #else wpd.EnsureProperties(w => w.WebPart, w => w.WebPart.Properties); #endif webPart.Order = (uint)wpd.WebPart.ZoneIndex; webPartsNeedLocalization = true; } #endif } } // Remove any existing WebPartIdToken tokens in the parser that were added by other pages. They won't apply to this page, // and they'll cause issues if this page contains web parts with the same name as web parts on other pages. parser.Tokens.RemoveAll(t => t is WebPartIdToken); var allWebParts = web.GetWebParts(url); foreach (var webpart in allWebParts) { parser.AddToken(new WebPartIdToken(web, webpart.WebPart.Title, webpart.Id)); } } else { scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_Pages_SkipAddingWebParts, page.Url); } } #if !SP2013 if (webPartsNeedLocalization) { page.LocalizeWebParts(web, parser, scope); } #endif file = web.GetFileByServerRelativeUrl(url); file.EnsureProperty(f => f.ListItemAllFields); if (page.Fields.Any()) { var item = file.ListItemAllFields; foreach (var fieldValue in page.Fields) { item[fieldValue.Key] = parser.ParseString(fieldValue.Value); } item.Update(); web.Context.ExecuteQueryRetry(); } if (page.Security != null && page.Security.RoleAssignments.Count != 0) { web.Context.Load(file.ListItemAllFields); web.Context.ExecuteQueryRetry(); file.ListItemAllFields.SetSecurity(parser, page.Security); } } } return(parser); }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { var context = web.Context as ClientContext; var site = (web.Context as ClientContext).Site; // Check if this is not a noscript site as publishing features are not supported if (web.IsNoScriptSite()) { scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_Publishing_SkipProvisioning); return(parser); } var webFeatureActive = web.IsFeatureActive(Constants.FeatureId_Web_Publishing); var siteFeatureActive = site.IsFeatureActive(Constants.FeatureId_Site_Publishing); if (template.Publishing.AutoCheckRequirements == AutoCheckRequirementsOptions.SkipIfNotCompliant && !webFeatureActive) { scope.LogDebug("Publishing Feature (Web Scoped) not active. Skipping provisioning of Publishing Image Renditions"); return(parser); } else if (template.Publishing.AutoCheckRequirements == AutoCheckRequirementsOptions.MakeCompliant) { if (!siteFeatureActive) { scope.LogDebug("Making site compliant for publishing"); site.ActivateFeature(Constants.FeatureId_Site_Publishing); web.ActivateFeature(Constants.FeatureId_Web_Publishing); } else { if (!web.IsFeatureActive(Constants.FeatureId_Web_Publishing)) { scope.LogDebug("Making site compliant for publishing"); web.ActivateFeature(Constants.FeatureId_Web_Publishing); } } } else if (!webFeatureActive) { throw new Exception("Publishing Feature not active. Provisioning failed"); } if (template.Publishing != null && template.Publishing.ImageRenditions != null && template.Publishing.ImageRenditions.Count > 0) { var renditions = SiteImageRenditions.GetRenditions(context); context.ExecuteQueryRetry(); foreach (var r in template.Publishing.ImageRenditions) { var rendition = new Microsoft.SharePoint.Client.Publishing.ImageRendition(); rendition.Name = r.Name; rendition.Height = r.Height; rendition.Width = r.Width; if (!renditions.Contains(rendition)) { renditions.Add(rendition); } } SiteImageRenditions.SetRenditions(context, renditions); context.ExecuteQueryRetry(); } } return(parser); }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { var site = (web.Context as ClientContext).Site; // Check if this is not a noscript site as publishing features are not supported if (web.IsNoScriptSite()) { scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_Publishing_SkipProvisioning); return(parser); } var webFeatureActive = web.IsFeatureActive(Constants.FeatureId_Web_Publishing); var siteFeatureActive = site.IsFeatureActive(Constants.FeatureId_Site_Publishing); if (template.Publishing.AutoCheckRequirements == AutoCheckRequirementsOptions.SkipIfNotCompliant && !webFeatureActive) { scope.LogDebug("Publishing Feature (Web Scoped) not active. Skipping provisioning of Publishing settings"); return(parser); } else if (template.Publishing.AutoCheckRequirements == AutoCheckRequirementsOptions.MakeCompliant) { if (!siteFeatureActive) { scope.LogDebug("Making site compliant for publishing"); site.ActivateFeature(Constants.FeatureId_Site_Publishing); web.ActivateFeature(Constants.FeatureId_Web_Publishing); } else { if (!web.IsFeatureActive(Constants.FeatureId_Web_Publishing)) { scope.LogDebug("Making site compliant for publishing"); web.ActivateFeature(Constants.FeatureId_Web_Publishing); } } } else if (!webFeatureActive) { throw new Exception("Publishing Feature not active. Provisioning failed"); } // Set allowed web templates var availableWebTemplates = template.Publishing.AvailableWebTemplates.Select(t => new WebTemplateEntity() { LanguageCode = t.LanguageCode.ToString(), TemplateName = t.TemplateName }).ToList(); if (availableWebTemplates.Any()) { web.SetAvailableWebTemplates(availableWebTemplates); } if (template.Publishing.DesignPackage != null) { var package = template.Publishing.DesignPackage; var tempFileName = Path.Combine(Path.GetTempPath(), template.Connector.GetFilenamePart(package.DesignPackagePath)); scope.LogDebug("Saving {0} to temporary file: {1}", package.DesignPackagePath, tempFileName); using (var stream = template.Connector.GetFileStream(package.DesignPackagePath)) { using (var outstream = System.IO.File.Create(tempFileName)) { stream.CopyTo(outstream); } } scope.LogDebug("Installing design package"); site.InstallSolution(package.PackageGuid, tempFileName, package.MajorVersion, package.MinorVersion); System.IO.File.Delete(tempFileName); } // Set allowed page layouts var availablePageLayouts = template.Publishing.PageLayouts.Select(p => p.Path); if (availablePageLayouts.Any()) { web.SetAvailablePageLayouts(site.RootWeb, availablePageLayouts); } // Set default page layout, if any var defaultPageLayout = template.Publishing.PageLayouts.FirstOrDefault(p => p.IsDefault); if (defaultPageLayout != null) { web.SetDefaultPageLayoutForSite(site.RootWeb, defaultPageLayout.Path); } return(parser); } }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { var context = web.Context as ClientContext; web.EnsureProperties(w => w.ServerRelativeUrl); foreach (var file in template.Files) { var folderName = parser.ParseString(file.Folder); if (folderName.ToLower().StartsWith((web.ServerRelativeUrl.ToLower()))) { folderName = folderName.Substring(web.ServerRelativeUrl.Length); } var folder = web.EnsureFolderPath(folderName); File targetFile = null; var checkedOut = false; targetFile = folder.GetFile(template.Connector.GetFilenamePart(file.Src)); if (targetFile != null) { if (file.Overwrite) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Files_Uploading_and_overwriting_existing_file__0_, file.Src); checkedOut = CheckOutIfNeeded(web, targetFile); using (var stream = template.Connector.GetFileStream(file.Src)) { targetFile = folder.UploadFile(template.Connector.GetFilenamePart(file.Src), stream, file.Overwrite); } } else { checkedOut = CheckOutIfNeeded(web, targetFile); } } else { using (var stream = template.Connector.GetFileStream(file.Src)) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Files_Uploading_file__0_, file.Src); targetFile = folder.UploadFile(template.Connector.GetFilenamePart(file.Src), stream, file.Overwrite); } checkedOut = CheckOutIfNeeded(web, targetFile); } if (targetFile != null) { if (file.Properties != null && file.Properties.Any()) { Dictionary <string, string> transformedProperties = file.Properties.ToDictionary(property => property.Key, property => parser.ParseString(property.Value)); targetFile.SetFileProperties(transformedProperties, false); // if needed, the file is already checked out } if (file.WebParts != null && file.WebParts.Any()) { targetFile.EnsureProperties(f => f.ServerRelativeUrl); var existingWebParts = web.GetWebParts(targetFile.ServerRelativeUrl); foreach (var webpart in file.WebParts) { // check if the webpart is already set on the page if (existingWebParts.FirstOrDefault(w => w.WebPart.Title == webpart.Title) == null) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Files_Adding_webpart___0___to_page, webpart.Title); var wpEntity = new WebPartEntity(); wpEntity.WebPartTitle = webpart.Title; wpEntity.WebPartXml = parser.ParseString(webpart.Contents).Trim(new[] { '\n', ' ' }); wpEntity.WebPartZone = webpart.Zone; wpEntity.WebPartIndex = (int)webpart.Order; web.AddWebPartToWebPartPage(targetFile.ServerRelativeUrl, wpEntity); } } } if (checkedOut) { targetFile.CheckIn("", CheckinType.MajorCheckIn); web.Context.ExecuteQueryRetry(); } // Don't set security when nothing is defined. This otherwise breaks on files set outside of a list if (file.Security != null && (file.Security.ClearSubscopes == true || file.Security.CopyRoleAssignments == true || file.Security.RoleAssignments.Count > 0)) { targetFile.ListItemAllFields.SetSecurity(parser, file.Security); } } } } return(parser); }
private void ProvisionCustomActionImplementation(object parent, CustomActionCollection customActions, TokenParser parser, PnPMonitoredScope scope) { Web web = null; Site site = null; if (parent is Site) { site = parent as Site; // Switch parser context; parser.Rebase(site.RootWeb); } else { web = parent as Web; // Switch parser context parser.Rebase(web); } foreach (var customAction in customActions) { var caExists = false; if (site != null) { caExists = site.CustomActionExists(customAction.Name); } else { caExists = web.CustomActionExists(customAction.Name); } if (!caExists) { var customActionEntity = new CustomActionEntity() { CommandUIExtension = customAction.CommandUIExtension != null?parser.ParseString(customAction.CommandUIExtension.ToString()) : string.Empty, Description = customAction.Description, Group = customAction.Group, ImageUrl = parser.ParseString(customAction.ImageUrl), Location = customAction.Location, Name = customAction.Name, RegistrationId = customAction.RegistrationId, RegistrationType = customAction.RegistrationType, Remove = customAction.Remove, Rights = customAction.Rights, ScriptBlock = parser.ParseString(customAction.ScriptBlock), ScriptSrc = parser.ParseString(customAction.ScriptSrc, "~site", "~sitecollection"), Sequence = customAction.Sequence, Title = customAction.Title, Url = parser.ParseString(customAction.Url) }; if (site != null) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Adding_custom_action___0___to_scope_Site, customActionEntity.Name); site.AddCustomAction(customActionEntity); #if !CLIENTSDKV15 if (customAction.Title.ContainsResourceToken() || customAction.Description.ContainsResourceToken()) { var uca = site.GetCustomActions().Where(uc => uc.Name == customAction.Name).FirstOrDefault(); SetCustomActionResourceValues(parser, customAction, uca); } #endif } else { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Adding_custom_action___0___to_scope_Web, customActionEntity.Name); web.AddCustomAction(customActionEntity); #if !CLIENTSDKV15 if (customAction.Title.ContainsResourceToken() || customAction.Description.ContainsResourceToken()) { var uca = web.GetCustomActions().Where(uc => uc.Name == customAction.Name).FirstOrDefault(); SetCustomActionResourceValues(parser, customAction, uca); } #endif } } else { UserCustomAction existingCustomAction = null; if (site != null) { existingCustomAction = site.GetCustomActions().FirstOrDefault(c => c.Name == customAction.Name); } else { existingCustomAction = web.GetCustomActions().FirstOrDefault(c => c.Name == customAction.Name); } if (existingCustomAction != null) { var isDirty = false; if (customAction.CommandUIExtension != null) { if (existingCustomAction.CommandUIExtension != parser.ParseString(customAction.CommandUIExtension.ToString())) { scope.LogPropertyUpdate("CommandUIExtension"); existingCustomAction.CommandUIExtension = parser.ParseString(customAction.CommandUIExtension.ToString()); isDirty = true; } } if (existingCustomAction.Description != customAction.Description) { scope.LogPropertyUpdate("Description"); existingCustomAction.Description = customAction.Description; isDirty = true; } #if !CLIENTSDKV15 if (customAction.Description.ContainsResourceToken()) { if (existingCustomAction.DescriptionResource.SetUserResourceValue(customAction.Description, parser)) { isDirty = true; } } #endif if (existingCustomAction.Group != customAction.Group) { scope.LogPropertyUpdate("Group"); existingCustomAction.Group = customAction.Group; isDirty = true; } if (existingCustomAction.ImageUrl != parser.ParseString(customAction.ImageUrl)) { scope.LogPropertyUpdate("ImageUrl"); existingCustomAction.ImageUrl = parser.ParseString(customAction.ImageUrl); isDirty = true; } if (existingCustomAction.Location != customAction.Location) { scope.LogPropertyUpdate("Location"); existingCustomAction.Location = customAction.Location; isDirty = true; } if (existingCustomAction.RegistrationId != customAction.RegistrationId) { scope.LogPropertyUpdate("RegistrationId"); existingCustomAction.RegistrationId = customAction.RegistrationId; isDirty = true; } if (existingCustomAction.RegistrationType != customAction.RegistrationType) { scope.LogPropertyUpdate("RegistrationType"); existingCustomAction.RegistrationType = customAction.RegistrationType; isDirty = true; } if (existingCustomAction.ScriptBlock != parser.ParseString(customAction.ScriptBlock)) { scope.LogPropertyUpdate("ScriptBlock"); existingCustomAction.ScriptBlock = parser.ParseString(customAction.ScriptBlock); isDirty = true; } if (existingCustomAction.ScriptSrc != parser.ParseString(customAction.ScriptSrc, "~site", "~sitecollection")) { scope.LogPropertyUpdate("ScriptSrc"); existingCustomAction.ScriptSrc = parser.ParseString(customAction.ScriptSrc, "~site", "~sitecollection"); isDirty = true; } if (existingCustomAction.Sequence != customAction.Sequence) { scope.LogPropertyUpdate("Sequence"); existingCustomAction.Sequence = customAction.Sequence; isDirty = true; } if (existingCustomAction.Title != parser.ParseString(customAction.Title)) { scope.LogPropertyUpdate("Title"); existingCustomAction.Title = parser.ParseString(customAction.Title); isDirty = true; } #if !CLIENTSDKV15 if (customAction.Title.ContainsResourceToken()) { if (existingCustomAction.TitleResource.SetUserResourceValue(customAction.Title, parser)) { isDirty = true; } } #endif if (existingCustomAction.Url != parser.ParseString(customAction.Url)) { scope.LogPropertyUpdate("Url"); existingCustomAction.Url = parser.ParseString(customAction.Url); isDirty = true; } if (isDirty) { existingCustomAction.Update(); existingCustomAction.Context.ExecuteQueryRetry(); } } } } }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { // Check if this is not a noscript site as we're not allowed to write to the web property bag is that one bool isNoScriptSite = web.IsNoScriptSite(); var context = web.Context as ClientContext; web.EnsureProperties(w => w.ServerRelativeUrl, w => w.Url); // Build on the fly the list of additional files coming from the Directories var directoryFiles = new List <Model.File>(); foreach (var directory in template.Directories) { var metadataProperties = directory.GetMetadataProperties(); directoryFiles.AddRange(directory.GetDirectoryFiles(metadataProperties)); } var filesToProcess = template.Files.Union(directoryFiles).ToArray(); var currentFileIndex = 0; foreach (var file in filesToProcess) { var targetFileName = !String.IsNullOrEmpty(file.TargetFileName) ? file.TargetFileName : file.Src; currentFileIndex++; WriteMessage($"File|{targetFileName}|{currentFileIndex}|{filesToProcess.Length}", ProvisioningMessageType.Progress); var folderName = parser.ParseString(file.Folder); if (folderName.ToLower().StartsWith((web.ServerRelativeUrl.ToLower()))) { folderName = folderName.Substring(web.ServerRelativeUrl.Length); } if (SkipFile(isNoScriptSite, targetFileName, folderName)) { // add log message scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_Files_SkipFileUpload, targetFileName, folderName); continue; } var folder = web.EnsureFolderPath(folderName); var checkedOut = false; var targetFile = folder.GetFile(template.Connector.GetFilenamePart(targetFileName)); if (targetFile != null) { if (file.Overwrite) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Files_Uploading_and_overwriting_existing_file__0_, targetFileName); checkedOut = CheckOutIfNeeded(web, targetFile); using (var stream = GetFileStream(template, file)) { targetFile = UploadFile(template, file, folder, stream); } } else { checkedOut = CheckOutIfNeeded(web, targetFile); } } else { using (var stream = GetFileStream(template, file)) {
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { if (!template.Lists.Any()) { return(parser); } web.EnsureProperties(w => w.ServerRelativeUrl); web.Context.Load(web.Lists, lc => lc.IncludeWithDefaultProperties(l => l.RootFolder.ServerRelativeUrl)); web.Context.ExecuteQueryRetry(); #region DataRows foreach (var listInstance in template.Lists) { if (listInstance.DataRows == null || !listInstance.DataRows.Any()) { continue; } scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Processing_data_rows_for__0_, listInstance.Title); // Retrieve the target list var list = web.Lists.GetByTitle(parser.ParseString(listInstance.Title)); web.Context.Load(list); // Retrieve the fields' types from the list Microsoft.SharePoint.Client.FieldCollection fields = list.Fields; web.Context.Load(fields, fs => fs.Include(f => f.InternalName, f => f.FieldTypeKind, f => f.TypeAsString, f => f.ReadOnlyField, f => f.Title)); web.Context.ExecuteQueryRetry(); var keyColumnType = "Text"; var parsedKeyColumn = parser.ParseString(listInstance.DataRows.KeyColumn); if (!string.IsNullOrEmpty(parsedKeyColumn)) { var keyColumn = fields.FirstOrDefault(f => f.InternalName.Equals(parsedKeyColumn, StringComparison.InvariantCultureIgnoreCase)); if (keyColumn != null) { switch (keyColumn.FieldTypeKind) { case FieldType.User: case FieldType.Lookup: keyColumnType = "Lookup"; break; case FieldType.URL: keyColumnType = "Url"; break; case FieldType.DateTime: keyColumnType = "DateTime"; break; case FieldType.Number: case FieldType.Counter: keyColumnType = "Number"; break; } } } foreach (var dataRow in listInstance.DataRows) { try { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Creating_list_item__0_, listInstance.DataRows.IndexOf(dataRow) + 1); bool processItem = true; ListItem listitem = null; var updateValues = new List <FieldUpdateValue>(); if (!string.IsNullOrEmpty(listInstance.DataRows.KeyColumn)) { // Get value from key column var dataRowValues = dataRow.Values.Where(v => v.Key == listInstance.DataRows.KeyColumn).ToList(); // if it is empty, skip the check if (dataRowValues.Any()) { var query = $@"<View><Query><Where><Eq><FieldRef Name=""{parsedKeyColumn}""/><Value Type=""{keyColumnType}"">{parser.ParseString(dataRowValues.FirstOrDefault().Value)}</Value></Eq></Where></Query><RowLimit>1</RowLimit></View>"; var camlQuery = new CamlQuery() { ViewXml = query }; var existingItems = list.GetItems(camlQuery); list.Context.Load(existingItems); list.Context.ExecuteQueryRetry(); if (existingItems.Count > 0) { if (listInstance.DataRows.UpdateBehavior == UpdateBehavior.Skip) { processItem = false; } else { listitem = existingItems[0]; processItem = true; } } } } if (!processItem) { continue; } if (listitem == null) { var listitemCI = new ListItemCreationInformation(); listitem = list.AddItem(listitemCI); } foreach (var dataValue in dataRow.Values) { Field dataField = fields.FirstOrDefault( f => f.InternalName == parser.ParseString(dataValue.Key)); if (dataField != null && dataField.ReadOnlyField && !dataField.InternalName.Equals("ContentTypeId", StringComparison.OrdinalIgnoreCase)) { // skip read only fields, except ContentTypeId continue; } if (dataField == null) { continue; } if (dataValue.Value == null) { updateValues.Add(dataField.FieldTypeKind == FieldType.Invalid ? new FieldUpdateValue(dataValue.Key, null, dataField.TypeAsString) : new FieldUpdateValue(dataValue.Key, null)); } else { String fieldValue = parser.ParseString(dataValue.Value); switch (dataField.FieldTypeKind) { case FieldType.Geolocation: // FieldGeolocationValue - Expected format: Altitude,Latitude,Longitude,Measure var geolocationArray = fieldValue.Split(','); if (geolocationArray.Length == 4) { var geolocationValue = new FieldGeolocationValue { Altitude = Double.Parse(geolocationArray[0]), Latitude = Double.Parse(geolocationArray[1]), Longitude = Double.Parse(geolocationArray[2]), Measure = Double.Parse(geolocationArray[3]), }; updateValues.Add(new FieldUpdateValue(dataValue.Key, geolocationValue)); } else { updateValues.Add(new FieldUpdateValue(dataValue.Key, fieldValue)); } break; case FieldType.Lookup: // FieldLookupValue - Expected format: LookupID or LookupID,LookupID,LookupID... if (fieldValue.Contains(",")) { var lookupValues = new List <FieldLookupValue>(); fieldValue.Split(',').All(value => { lookupValues.Add(new FieldLookupValue { LookupId = int.Parse(value), }); return(true); }); updateValues.Add(new FieldUpdateValue(dataValue.Key, lookupValues.ToArray())); } else { var lookupValue = new FieldLookupValue { LookupId = int.Parse(fieldValue), }; updateValues.Add(new FieldUpdateValue(dataValue.Key, lookupValue)); } break; case FieldType.URL: // FieldUrlValue - Expected format: URL,Description var urlArray = fieldValue.Split(','); var linkValue = new FieldUrlValue(); if (urlArray.Length == 2) { linkValue.Url = urlArray[0]; linkValue.Description = urlArray[1]; } else { linkValue.Url = urlArray[0]; linkValue.Description = urlArray[0]; } updateValues.Add(new FieldUpdateValue(dataValue.Key, linkValue)); break; case FieldType.User: // FieldUserValue - Expected format: loginName or loginName,loginName,loginName... if (fieldValue.Contains(",")) { var userValues = new List <FieldUserValue>(); fieldValue.Split(',').All(value => { var user = web.EnsureUser(value); web.Context.Load(user); web.Context.ExecuteQueryRetry(); if (user != null) { userValues.Add(new FieldUserValue { LookupId = user.Id, });; } return(true); }); updateValues.Add(new FieldUpdateValue(dataValue.Key, userValues.ToArray())); } else { var user = web.EnsureUser(fieldValue); web.Context.Load(user); web.Context.ExecuteQueryRetry(); if (user != null) { var userValue = new FieldUserValue { LookupId = user.Id, }; updateValues.Add(new FieldUpdateValue(dataValue.Key, userValue)); } else { updateValues.Add(new FieldUpdateValue(dataValue.Key, fieldValue)); } } break; case FieldType.DateTime: var dateTime = DateTime.MinValue; if (DateTime.TryParse(fieldValue, out dateTime)) { updateValues.Add(new FieldUpdateValue(dataValue.Key, dateTime)); } break; case FieldType.Invalid: switch (dataField.TypeAsString) { case "TaxonomyFieldType": // Single value field - Expected format: term label|term GUID case "TaxonomyFieldTypeMulti": // Multi value field - Expected format: term label|term GUID;term label|term GUID;term label|term GUID;... { if (fieldValue != null) { var termStrings = new List <string>(); var termsArray = fieldValue.Split(new char[] { ';' }); foreach (var term in termsArray) { termStrings.Add($"-1;#{term}"); } updateValues.Add(new FieldUpdateValue(dataValue.Key, termStrings, dataField.TypeAsString)); } break; } default: { //Publishing image case, but can be others too updateValues.Add(new FieldUpdateValue(dataValue.Key, fieldValue)); break; } } break; default: updateValues.Add(new FieldUpdateValue(dataValue.Key, fieldValue)); break; } } } foreach (var itemValue in updateValues.Where(u => u.FieldTypeString != "TaxonomyFieldTypeMulti" && u.FieldTypeString != "TaxonomyFieldType")) { if (string.IsNullOrEmpty(itemValue.FieldTypeString)) { listitem[itemValue.Key] = itemValue.Value; } } listitem.Update(); web.Context.Load(listitem); web.Context.ExecuteQueryRetry(); foreach (var itemValue in updateValues.Where(u => u.FieldTypeString == "TaxonomyFieldTypeMulti" || u.FieldTypeString == "TaxonomyFieldType")) { switch (itemValue.FieldTypeString) { case "TaxonomyFieldTypeMulti": { var field = fields.FirstOrDefault(f => f.InternalName == itemValue.Key as string || f.Title == itemValue.Key as string); var taxField = web.Context.CastTo <TaxonomyField>(field); if (itemValue.Value != null) { var valueCollection = new TaxonomyFieldValueCollection(web.Context, string.Join(";#", itemValue.Value as List <string>), taxField); taxField.SetFieldValueByValueCollection(listitem, valueCollection); } else { var valueCollection = new TaxonomyFieldValueCollection(web.Context, null, taxField); taxField.SetFieldValueByValueCollection(listitem, valueCollection); } listitem.Update(); web.Context.Load(listitem); web.Context.ExecuteQueryRetry(); break; } case "TaxonomyFieldType": { var field = fields.FirstOrDefault(f => f.InternalName == itemValue.Key as string || f.Title == itemValue.Key as string); var taxField = web.Context.CastTo <TaxonomyField>(field); taxField.EnsureProperty(f => f.TextField); var taxValue = new TaxonomyFieldValue(); if (itemValue.Value != null) { var termString = (itemValue.Value as List <string>).First(); taxValue.Label = termString.Split(new string[] { ";#" }, StringSplitOptions.None)[1].Split(new char[] { '|' })[0]; taxValue.TermGuid = termString.Split(new string[] { ";#" }, StringSplitOptions.None)[1].Split(new char[] { '|' })[1]; taxValue.WssId = -1; taxField.SetFieldValueByValue(listitem, taxValue); } else { taxValue.Label = string.Empty; taxValue.TermGuid = "11111111-1111-1111-1111-111111111111"; taxValue.WssId = -1; Field hiddenField = list.Fields.GetById(taxField.TextField); listitem.Context.Load(hiddenField, tf => tf.InternalName); listitem.Context.ExecuteQueryRetry(); taxField.SetFieldValueByValue(listitem, taxValue); // this order of updates is important. listitem[hiddenField.InternalName] = string.Empty; // this order of updates is important. } listitem.Update(); web.Context.Load(listitem); web.Context.ExecuteQueryRetry(); break; } } } if (dataRow.Security != null && (dataRow.Security.ClearSubscopes == true || dataRow.Security.CopyRoleAssignments == true || dataRow.Security.RoleAssignments.Count > 0)) { listitem.SetSecurity(parser, dataRow.Security); } } catch (Exception ex) { if (ex.GetType().Equals(typeof(ServerException)) && (ex as ServerException).ServerErrorTypeName.Equals("Microsoft.SharePoint.SPDuplicateValuesFoundException", StringComparison.InvariantCultureIgnoreCase) && applyingInformation.IgnoreDuplicateDataRowErrors) { scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Creating_listitem_duplicate); continue; } else { scope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Creating_listitem_failed___0_____1_, ex.Message, ex.StackTrace); throw; } } } } #endregion } return(parser); }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { if (template.Navigation != null) { if (!WebSupportsProvisionNavigation(web, template)) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Navigation_Context_web_is_not_publishing); return(parser); } // Check if this is not a noscript site as navigation features are not supported if (web.IsNoScriptSite()) { scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_Navigation_SkipProvisioning); return(parser); } // Retrieve the current web navigation settings var navigationSettings = new WebNavigationSettings(web.Context, web); web.Context.Load(navigationSettings, ns => ns.CurrentNavigation, ns => ns.GlobalNavigation); web.Context.ExecuteQueryRetry(); navigationSettings.AddNewPagesToNavigation = template.Navigation.AddNewPagesToNavigation; navigationSettings.CreateFriendlyUrlsForNewPages = template.Navigation.CreateFriendlyUrlsForNewPages; if (template.Navigation.GlobalNavigation != null) { switch (template.Navigation.GlobalNavigation.NavigationType) { case GlobalNavigationType.Inherit: navigationSettings.GlobalNavigation.Source = StandardNavigationSource.InheritFromParentWeb; web.Navigation.UseShared = true; break; case GlobalNavigationType.Managed: if (template.Navigation.GlobalNavigation.ManagedNavigation == null) { throw new ApplicationException(CoreResources.Provisioning_ObjectHandlers_Navigation_missing_global_managed_navigation); } navigationSettings.GlobalNavigation.Source = StandardNavigationSource.TaxonomyProvider; navigationSettings.GlobalNavigation.TermStoreId = Guid.Parse(parser.ParseString(template.Navigation.GlobalNavigation.ManagedNavigation.TermStoreId)); navigationSettings.GlobalNavigation.TermSetId = Guid.Parse(parser.ParseString(template.Navigation.GlobalNavigation.ManagedNavigation.TermSetId)); break; case GlobalNavigationType.Structural: default: if (template.Navigation.GlobalNavigation.StructuralNavigation == null) { throw new ApplicationException(CoreResources.Provisioning_ObjectHandlers_Navigation_missing_global_structural_navigation); } navigationSettings.GlobalNavigation.Source = StandardNavigationSource.PortalProvider; ProvisionGlobalStructuralNavigation(web, template.Navigation.GlobalNavigation.StructuralNavigation, parser, applyingInformation.ClearNavigation, scope); break; } navigationSettings.Update(TaxonomySession.GetTaxonomySession(web.Context)); web.Context.ExecuteQueryRetry(); } if (template.Navigation.CurrentNavigation != null) { switch (template.Navigation.CurrentNavigation.NavigationType) { case CurrentNavigationType.Inherit: navigationSettings.CurrentNavigation.Source = StandardNavigationSource.InheritFromParentWeb; break; case CurrentNavigationType.Managed: if (template.Navigation.CurrentNavigation.ManagedNavigation == null) { throw new ApplicationException(CoreResources.Provisioning_ObjectHandlers_Navigation_missing_current_managed_navigation); } navigationSettings.CurrentNavigation.Source = StandardNavigationSource.TaxonomyProvider; navigationSettings.CurrentNavigation.TermStoreId = Guid.Parse(parser.ParseString(template.Navigation.CurrentNavigation.ManagedNavigation.TermStoreId)); navigationSettings.CurrentNavigation.TermSetId = Guid.Parse(parser.ParseString(template.Navigation.CurrentNavigation.ManagedNavigation.TermSetId)); break; case CurrentNavigationType.StructuralLocal: web.SetPropertyBagValue(NavigationShowSiblings, "false"); if (template.Navigation.CurrentNavigation.StructuralNavigation == null) { throw new ApplicationException(CoreResources.Provisioning_ObjectHandlers_Navigation_missing_current_structural_navigation); } navigationSettings.CurrentNavigation.Source = StandardNavigationSource.PortalProvider; ProvisionCurrentStructuralNavigation(web, template.Navigation.CurrentNavigation.StructuralNavigation, parser, applyingInformation.ClearNavigation, scope); break; case CurrentNavigationType.Structural: default: web.SetPropertyBagValue(NavigationShowSiblings, "true"); if (template.Navigation.CurrentNavigation.StructuralNavigation == null) { throw new ApplicationException(CoreResources.Provisioning_ObjectHandlers_Navigation_missing_current_structural_navigation); } navigationSettings.CurrentNavigation.Source = StandardNavigationSource.PortalProvider; ProvisionCurrentStructuralNavigation(web, template.Navigation.CurrentNavigation.StructuralNavigation, parser, applyingInformation.ClearNavigation, scope); break; } navigationSettings.Update(TaxonomySession.GetTaxonomySession(web.Context)); web.Context.ExecuteQueryRetry(); } } } return(parser); }
private static void AddUserToGroup(Web web, Group group, List<User> members, PnPMonitoredScope scope) { if (members.Any()) { scope.LogDebug("Adding users to group {0}", group.Title); try { foreach (var user in members) { scope.LogDebug("Adding user {0}", user.Name); var existingUser = web.EnsureUser(user.Name); group.Users.AddUser(existingUser); } web.Context.ExecuteQueryRetry(); } catch (Exception ex) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_SiteSecurity_Add_users_failed_for_group___0_____1_____2_, group.Title, ex.Message, ex.StackTrace); throw; } } }
public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { GlobalNavigationType globalNavigationType; CurrentNavigationType currentNavigationType; if (!WebSupportsExtractNavigation(web)) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Navigation_Context_web_is_not_publishing); return(template); } // Retrieve the current web navigation settings var navigationSettings = new WebNavigationSettings(web.Context, web); navigationSettings.EnsureProperties(ns => ns.AddNewPagesToNavigation, ns => ns.CreateFriendlyUrlsForNewPages, ns => ns.CurrentNavigation, ns => ns.GlobalNavigation); switch (navigationSettings.GlobalNavigation.Source) { case StandardNavigationSource.InheritFromParentWeb: // Global Navigation is Inherited globalNavigationType = GlobalNavigationType.Inherit; break; case StandardNavigationSource.TaxonomyProvider: // Global Navigation is Managed globalNavigationType = GlobalNavigationType.Managed; break; case StandardNavigationSource.PortalProvider: default: // Global Navigation is Structural globalNavigationType = GlobalNavigationType.Structural; break; } switch (navigationSettings.CurrentNavigation.Source) { case StandardNavigationSource.InheritFromParentWeb: // Current Navigation is Inherited currentNavigationType = CurrentNavigationType.Inherit; break; case StandardNavigationSource.TaxonomyProvider: // Current Navigation is Managed currentNavigationType = CurrentNavigationType.Managed; break; case StandardNavigationSource.PortalProvider: default: // Current Navigation is Structural if (AreSiblingsEnabledForCurrentStructuralNavigation(web)) { currentNavigationType = CurrentNavigationType.Structural; } else { currentNavigationType = CurrentNavigationType.StructuralLocal; } break; } var navigationEntity = new Model.Navigation(new GlobalNavigation(globalNavigationType, globalNavigationType == GlobalNavigationType.Structural ? GetGlobalStructuralNavigation(web, navigationSettings) : null, globalNavigationType == GlobalNavigationType.Managed ? GetGlobalManagedNavigation(web, navigationSettings) : null), new CurrentNavigation(currentNavigationType, currentNavigationType == CurrentNavigationType.Structural | currentNavigationType == CurrentNavigationType.StructuralLocal ? GetCurrentStructuralNavigation(web, navigationSettings) : null, currentNavigationType == CurrentNavigationType.Managed ? GetCurrentManagedNavigation(web, navigationSettings) : null) ); navigationEntity.AddNewPagesToNavigation = navigationSettings.AddNewPagesToNavigation; navigationEntity.CreateFriendlyUrlsForNewPages = navigationSettings.CreateFriendlyUrlsForNewPages; // If a base template is specified then use that one to "cleanup" the generated template model if (creationInfo.BaseTemplate != null) { if (!navigationEntity.Equals(creationInfo.BaseTemplate.Navigation)) { template.Navigation = navigationEntity; } } else { template.Navigation = navigationEntity; } } return(template); }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { var context = web.Context as ClientContext; web.EnsureProperties(w => w.ServerRelativeUrl, w => w.RootFolder.WelcomePage); foreach (var page in template.Pages) { var url = parser.ParseString(page.Url); if (!url.ToLower().StartsWith(web.ServerRelativeUrl.ToLower())) { url = UrlUtility.Combine(web.ServerRelativeUrl, url); } var exists = true; Microsoft.SharePoint.Client.File file = null; try { file = web.GetFileByServerRelativeUrl(url); web.Context.Load(file); web.Context.ExecuteQuery(); } catch (ServerException ex) { if (ex.ServerErrorTypeName == "System.IO.FileNotFoundException") { exists = false; } } if (exists) { if (page.Overwrite) { try { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Pages_Overwriting_existing_page__0_, url); if (page.WelcomePage && url.Contains(web.RootFolder.WelcomePage)) web.SetHomePage(string.Empty); file.DeleteObject(); web.Context.ExecuteQueryRetry(); web.AddWikiPageByUrl(url); if (page.Layout == WikiPageLayout.Custom) { web.AddLayoutToWikiPage(WikiPageLayout.OneColumn, url); } else { web.AddLayoutToWikiPage(page.Layout, url); } } catch (Exception ex) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_Pages_Overwriting_existing_page__0__failed___1_____2_, url, ex.Message, ex.StackTrace); } } } else { try { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Pages_Creating_new_page__0_, url); web.AddWikiPageByUrl(url); web.AddLayoutToWikiPage(page.Layout, url); } catch (Exception ex) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_Pages_Creating_new_page__0__failed___1_____2_, url, ex.Message, ex.StackTrace); } } if (page.WelcomePage) { web.RootFolder.EnsureProperty(p => p.ServerRelativeUrl); var rootFolderRelativeUrl = url.Substring(web.RootFolder.ServerRelativeUrl.Length); web.SetHomePage(rootFolderRelativeUrl); } if (page.WebParts != null & page.WebParts.Any()) { var existingWebParts = web.GetWebParts(url); foreach (var webpart in page.WebParts) { if (existingWebParts.FirstOrDefault(w => w.WebPart.Title == webpart.Title) == null) { WebPartEntity wpEntity = new WebPartEntity(); wpEntity.WebPartTitle = webpart.Title; wpEntity.WebPartXml = parser.ParseString(webpart.Contents.Trim(new[] { '\n', ' ' })); web.AddWebPartToWikiPage(url, wpEntity, (int)webpart.Row, (int)webpart.Column, false); } } var allWebParts = web.GetWebParts(url); foreach (var webpart in allWebParts) { parser.AddToken(new WebPartIdToken(web, webpart.WebPart.Title, webpart.Id)); } } file = web.GetFileByServerRelativeUrl(url); file.EnsureProperty(f => f.ListItemAllFields); if (page.Fields.Any()) { var item = file.ListItemAllFields; foreach (var fieldValue in page.Fields) { item[fieldValue.Key] = parser.ParseString(fieldValue.Value); } item.Update(); web.Context.ExecuteQueryRetry(); } if (page.Security != null && page.Security.RoleAssignments.Count != 0) { web.Context.Load(file.ListItemAllFields); web.Context.ExecuteQuery(); file.ListItemAllFields.SetSecurity(parser, page.Security); } } } return parser; }
public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { // if this is a sub site then we're not creating security entities as by default security is inherited from the root site if (web.IsSubSite()) { return(template); } web.Context.Load(web, w => w.HasUniqueRoleAssignments, w => w.Title); var ownerGroup = web.AssociatedOwnerGroup; var memberGroup = web.AssociatedMemberGroup; var visitorGroup = web.AssociatedVisitorGroup; web.Context.ExecuteQueryRetry(); if (!ownerGroup.ServerObjectIsNull.Value) { web.Context.Load(ownerGroup, o => o.Id, o => o.Users, o => o.Title); } if (!memberGroup.ServerObjectIsNull.Value) { web.Context.Load(memberGroup, o => o.Id, o => o.Users, o => o.Title); } if (!visitorGroup.ServerObjectIsNull.Value) { web.Context.Load(visitorGroup, o => o.Id, o => o.Users, o => o.Title); } web.Context.ExecuteQueryRetry(); List <int> associatedGroupIds = new List <int>(); var owners = new List <User>(); var members = new List <User>(); var visitors = new List <User>(); if (!ownerGroup.ServerObjectIsNull.Value) { associatedGroupIds.Add(ownerGroup.Id); foreach (var member in ownerGroup.Users) { owners.Add(new User() { Name = member.LoginName }); } } if (!memberGroup.ServerObjectIsNull.Value) { associatedGroupIds.Add(memberGroup.Id); foreach (var member in memberGroup.Users) { members.Add(new User() { Name = member.LoginName }); } } if (!visitorGroup.ServerObjectIsNull.Value) { associatedGroupIds.Add(visitorGroup.Id); foreach (var member in visitorGroup.Users) { visitors.Add(new User() { Name = member.LoginName }); } } var siteSecurity = new SiteSecurity(); siteSecurity.AdditionalOwners.AddRange(owners); siteSecurity.AdditionalMembers.AddRange(members); siteSecurity.AdditionalVisitors.AddRange(visitors); var query = from user in web.SiteUsers where user.IsSiteAdmin select user; var allUsers = web.Context.LoadQuery(query); web.Context.ExecuteQueryRetry(); var admins = new List <User>(); foreach (var member in allUsers) { admins.Add(new User() { Name = member.LoginName }); } siteSecurity.AdditionalAdministrators.AddRange(admins); if (creationInfo.IncludeSiteGroups) { web.Context.Load(web.SiteGroups, o => o.IncludeWithDefaultProperties( gr => gr.Title, gr => gr.AllowMembersEditMembership, gr => gr.AutoAcceptRequestToJoinLeave, gr => gr.AllowRequestToJoinLeave, gr => gr.Description, gr => gr.Users.Include(u => u.LoginName), gr => gr.OnlyAllowMembersViewMembership, gr => gr.Owner.LoginName, gr => gr.RequestToJoinLeaveEmailSetting )); web.Context.ExecuteQueryRetry(); foreach (var group in web.SiteGroups.AsEnumerable().Where(o => !associatedGroupIds.Contains(o.Id))) { scope.LogDebug("Processing group {0}", group.Title); var siteGroup = new SiteGroup() { Title = group.Title.Replace(web.Title, "{sitename}"), AllowMembersEditMembership = group.AllowMembersEditMembership, AutoAcceptRequestToJoinLeave = group.AutoAcceptRequestToJoinLeave, AllowRequestToJoinLeave = group.AllowRequestToJoinLeave, Description = group.Description, OnlyAllowMembersViewMembership = group.OnlyAllowMembersViewMembership, Owner = ReplaceGroupTokens(web, group.Owner.LoginName), RequestToJoinLeaveEmailSetting = group.RequestToJoinLeaveEmailSetting }; foreach (var member in group.Users) { siteGroup.Members.Add(new User() { Name = member.LoginName }); } siteSecurity.SiteGroups.Add(siteGroup); } } var webRoleDefinitions = web.Context.LoadQuery(web.RoleDefinitions.Include(r => r.Name, r => r.Description, r => r.BasePermissions, r => r.RoleTypeKind)); web.Context.ExecuteQueryRetry(); if (web.HasUniqueRoleAssignments) { var permissionKeys = Enum.GetNames(typeof(PermissionKind)); foreach (var webRoleDefinition in webRoleDefinitions) { if (webRoleDefinition.RoleTypeKind == RoleType.None) { scope.LogDebug("Processing custom role definition {0}", webRoleDefinition.Name); var modelRoleDefinitions = new Model.RoleDefinition(); modelRoleDefinitions.Description = webRoleDefinition.Description; modelRoleDefinitions.Name = webRoleDefinition.Name; var permissions = new List <PermissionKind>(); foreach (var permissionKey in permissionKeys) { var permissionKind = (PermissionKind)Enum.Parse(typeof(PermissionKind), permissionKey); if (webRoleDefinition.BasePermissions.Has(permissionKind)) { modelRoleDefinitions.Permissions.Add(permissionKind); } } siteSecurity.SiteSecurityPermissions.RoleDefinitions.Add(modelRoleDefinitions); } else { scope.LogDebug("Skipping OOTB role definition {0}", webRoleDefinition.Name); } } var webRoleAssignments = web.Context.LoadQuery(web.RoleAssignments.Include( r => r.RoleDefinitionBindings.Include( rd => rd.Name, rd => rd.RoleTypeKind), r => r.Member.LoginName)); web.Context.ExecuteQueryRetry(); foreach (var webRoleAssignment in webRoleAssignments) { if (webRoleAssignment.Member.LoginName != "Excel Services Viewers") { foreach (var roleDefinition in webRoleAssignment.RoleDefinitionBindings) { if (roleDefinition.RoleTypeKind != RoleType.Guest) { var modelRoleAssignment = new Model.RoleAssignment(); modelRoleAssignment.RoleDefinition = roleDefinition.Name; modelRoleAssignment.Principal = ReplaceGroupTokens(web, webRoleAssignment.Member.LoginName); siteSecurity.SiteSecurityPermissions.RoleAssignments.Add(modelRoleAssignment); } } } } template.Security = siteSecurity; } // If a base template is specified then use that one to "cleanup" the generated template model if (creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate); } } return(template); }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { if (template.Lists.Any()) { var rootWeb = (web.Context as ClientContext).Site.RootWeb; web.EnsureProperties(w => w.ServerRelativeUrl); web.Context.Load(web.Lists, lc => lc.IncludeWithDefaultProperties(l => l.RootFolder.ServerRelativeUrl)); web.Context.ExecuteQueryRetry(); var existingLists = web.Lists.AsEnumerable().ToList(); var serverRelativeUrl = web.ServerRelativeUrl; var processedLists = new List<ListInfo>(); // Check if this is not a noscript site as we're not allowed to update some properties bool isNoScriptSite = web.IsNoScriptSite(); #region Lists foreach (var templateList in template.Lists) { // Check for the presence of the references content types and throw an exception if not present or in template if (templateList.ContentTypesEnabled) { var existingCts = web.Context.LoadQuery(web.AvailableContentTypes); web.Context.ExecuteQueryRetry(); foreach (var ct in templateList.ContentTypeBindings) { var found = template.ContentTypes.Any(t => t.Id.ToUpperInvariant() == ct.ContentTypeId.ToUpperInvariant()); if (found == false) { found = existingCts.Any(t => t.StringId.ToUpperInvariant() == ct.ContentTypeId.ToUpperInvariant()); } if (!found) { scope.LogError("Referenced content type {0} not available in site or in template", ct.ContentTypeId); throw new Exception(string.Format("Referenced content type {0} not available in site or in template", ct.ContentTypeId)); } } } // check if the List exists by url or by title var index = existingLists.FindIndex(x => x.Title.Equals(templateList.Title, StringComparison.OrdinalIgnoreCase) || x.RootFolder.ServerRelativeUrl.Equals(UrlUtility.Combine(serverRelativeUrl, templateList.Url), StringComparison.OrdinalIgnoreCase)); if (index == -1) { try { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Creating_list__0_, templateList.Title); var returnTuple = CreateList(web, templateList, parser, scope, isNoScriptSite); var createdList = returnTuple.Item1; parser = returnTuple.Item2; processedLists.Add(new ListInfo { SiteList = createdList, TemplateList = templateList }); parser.AddToken(new ListIdToken(web, templateList.Title, createdList.Id)); parser.AddToken(new ListUrlToken(web, templateList.Title, createdList.RootFolder.ServerRelativeUrl.Substring(web.ServerRelativeUrl.Length + 1))); } catch (Exception ex) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Creating_list__0__failed___1_____2_, templateList.Title, ex.Message, ex.StackTrace); throw; } } else { try { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Updating_list__0_, templateList.Title); var existingList = web.Lists[index]; var returnTuple = UpdateList(web, existingList, templateList, parser, scope, isNoScriptSite); var updatedList = returnTuple.Item1; parser = returnTuple.Item2; if (updatedList != null) { processedLists.Add(new ListInfo { SiteList = updatedList, TemplateList = templateList }); } } catch (Exception ex) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Updating_list__0__failed___1_____2_, templateList.Title, ex.Message, ex.StackTrace); throw; } } } #endregion #region FieldRefs foreach (var listInfo in processedLists) { if (listInfo.TemplateList.FieldRefs.Any()) { foreach (var fieldRef in listInfo.TemplateList.FieldRefs) { var field = rootWeb.GetFieldById<Field>(fieldRef.Id); if (field == null) { // log missing referenced field this.WriteWarning(string.Format(CoreResources.Provisioning_ObjectHandlers_ListInstances_InvalidFieldReference, listInfo.TemplateList.Title, fieldRef.Name, fieldRef.Id), ProvisioningMessageType.Error); // move onto next field reference continue; } if (!listInfo.SiteList.FieldExistsById(fieldRef.Id)) { field = CreateFieldRef(listInfo, field, fieldRef); } else { field = UpdateFieldRef(listInfo.SiteList, field.Id, fieldRef); } field.EnsureProperties(f => f.InternalName, f => f.Title); parser.AddToken(new FieldTitleToken(web, field.InternalName, field.Title)); #if !SP2013 var siteField = template.SiteFields.FirstOrDefault(f => Guid.Parse(XElement.Parse(f.SchemaXml).Attribute("ID").Value).Equals(field.Id)); if (siteField != null && siteField.SchemaXml.ContainsResourceToken()) { var isDirty = false; var originalFieldElement = XElement.Parse(siteField.SchemaXml); var nameAttributeValue = originalFieldElement.Attribute("DisplayName") != null ? originalFieldElement.Attribute("DisplayName").Value : ""; if (nameAttributeValue.ContainsResourceToken()) { if (field.TitleResource.SetUserResourceValue(nameAttributeValue, parser)) { isDirty = true; } } var descriptionAttributeValue = originalFieldElement.Attribute("Description") != null ? originalFieldElement.Attribute("Description").Value : ""; if (descriptionAttributeValue.ContainsResourceToken()) { if (field.DescriptionResource.SetUserResourceValue(descriptionAttributeValue, parser)) { isDirty = true; } } if (isDirty) { field.Update(); field.Context.ExecuteQueryRetry(); } } #endif } listInfo.SiteList.Update(); web.Context.ExecuteQueryRetry(); } } #endregion #region Fields foreach (var listInfo in processedLists) { if (listInfo.TemplateList.Fields.Any()) { foreach (var field in listInfo.TemplateList.Fields) { var fieldElement = XElement.Parse(parser.ParseString(field.SchemaXml, "~sitecollection", "~site")); if (fieldElement.Attribute("ID") == null) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstances_Field_schema_has_no_ID_attribute___0_, field.SchemaXml); throw new Exception(string.Format(CoreResources.Provisioning_ObjectHandlers_ListInstances_Field_schema_has_no_ID_attribute___0_, field.SchemaXml)); } var id = fieldElement.Attribute("ID").Value; Guid fieldGuid; if (!Guid.TryParse(id, out fieldGuid)) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstances_ID_for_field_is_not_a_valid_Guid___0_, field.SchemaXml); throw new Exception(string.Format(CoreResources.Provisioning_ObjectHandlers_ListInstances_ID_for_field_is_not_a_valid_Guid___0_, id)); } else { var fieldFromList = listInfo.SiteList.GetFieldById<Field>(fieldGuid); if (fieldFromList == null) { try { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Creating_field__0_, fieldGuid); var createdField = CreateField(fieldElement, listInfo, parser, field.SchemaXml, web.Context, scope); if (createdField != null) { createdField.EnsureProperties(f => f.InternalName, f => f.Title); parser.AddToken(new FieldTitleToken(web, createdField.InternalName, createdField.Title)); } } catch (Exception ex) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstances_Creating_field__0__failed___1_____2_, fieldGuid, ex.Message, ex.StackTrace); throw; } } else { try { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Updating_field__0_, fieldGuid); var updatedField = UpdateField(web, listInfo, fieldGuid, fieldElement, fieldFromList, scope, parser, field.SchemaXml); if (updatedField != null) { updatedField.EnsureProperties(f => f.InternalName, f => f.Title); parser.AddToken(new FieldTitleToken(web, updatedField.InternalName, updatedField.Title)); } } catch (Exception ex) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstances_Updating_field__0__failed___1_____2_, fieldGuid, ex.Message, ex.StackTrace); throw; } } } } } listInfo.SiteList.Update(); web.Context.ExecuteQueryRetry(); } #endregion #region Default Field Values foreach (var listInfo in processedLists) { if (listInfo.TemplateList.FieldDefaults.Any()) { foreach (var fieldDefault in listInfo.TemplateList.FieldDefaults) { var field = listInfo.SiteList.Fields.GetByInternalNameOrTitle(fieldDefault.Key); field.DefaultValue = fieldDefault.Value; field.Update(); web.Context.ExecuteQueryRetry(); } } } #endregion #region Views foreach (var listInfo in processedLists) { var list = listInfo.TemplateList; var createdList = listInfo.SiteList; if (list.Views.Any() && list.RemoveExistingViews) { while (createdList.Views.Any()) { createdList.Views[0].DeleteObject(); } web.Context.ExecuteQueryRetry(); } var existingViews = createdList.Views; web.Context.Load(existingViews, vs => vs.Include(v => v.Title, v => v.Id)); web.Context.ExecuteQueryRetry(); foreach (var view in list.Views) { CreateView(web, view, existingViews, createdList, scope); } //// Removing existing views set the OnQuickLaunch option to false and need to be re-set. //if (list.OnQuickLaunch && list.RemoveExistingViews && list.Views.Count > 0) //{ // createdList.RefreshLoad(); // web.Context.ExecuteQueryRetry(); // createdList.OnQuickLaunch = list.OnQuickLaunch; // createdList.Update(); // web.Context.ExecuteQueryRetry(); //} } #endregion #region Folders // Folders are supported for document libraries and generic lists only foreach (var list in processedLists) { list.SiteList.EnsureProperties(l => l.BaseType); if ((list.SiteList.BaseType == BaseType.DocumentLibrary | list.SiteList.BaseType == BaseType.GenericList) && list.TemplateList.Folders != null && list.TemplateList.Folders.Count > 0) { list.SiteList.EnableFolderCreation = true; list.SiteList.Update(); web.Context.ExecuteQueryRetry(); var rootFolder = list.SiteList.RootFolder; foreach (var folder in list.TemplateList.Folders) { CreateFolderInList(rootFolder, folder, parser, scope); } } } #endregion // If an existing view is updated, and the list is to be listed on the QuickLaunch, it is removed because the existing view will be deleted and recreated from scratch. foreach (var listInfo in processedLists) { listInfo.SiteList.OnQuickLaunch = listInfo.TemplateList.OnQuickLaunch; listInfo.SiteList.Update(); } web.Context.ExecuteQueryRetry(); } } return parser; }
private ProvisioningTemplate CleanupEntities(ProvisioningTemplate template, ProvisioningTemplate baseTemplate, bool isSubSite, PnPMonitoredScope scope) { if (!isSubSite) { foreach (var customAction in baseTemplate.CustomActions.SiteCustomActions) { int index = template.CustomActions.SiteCustomActions.FindIndex(f => f.Name.Equals(customAction.Name)); if (index > -1) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Removing_site_scoped_custom_action___0___from_template_because_already_available_in_base_template, customAction.Name); template.CustomActions.SiteCustomActions.RemoveAt(index); } } } foreach (var customAction in baseTemplate.CustomActions.WebCustomActions) { int index = template.CustomActions.WebCustomActions.FindIndex(f => f.Name.Equals(customAction.Name)); if (index > -1) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Removing_web_scoped_custom_action___0___from_template_because_already_available_in_base_template, customAction.Name); template.CustomActions.WebCustomActions.RemoveAt(index); } } return template; }
private void ProvisionCustomActionImplementation(object parent, CustomActionCollection customActions, TokenParser parser, PnPMonitoredScope scope, bool isNoScriptSite = false) { Web web = null; Site site = null; if (parent is Site) { site = parent as Site; // Switch parser context; parser.Rebase(site.RootWeb); } else { web = parent as Web; // Switch parser context parser.Rebase(web); } foreach (var customAction in customActions) { if (isNoScriptSite && Guid.Empty == customAction.ClientSideComponentId) { scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_CustomActions_SkippingAddUpdateDueToNoScript, customAction.Name); continue; } var caExists = false; if (site != null) { caExists = site.CustomActionExists(customAction.Name); } else { caExists = web.CustomActionExists(customAction.Name); } // If the CustomAction does not exist, we don't have to remove it, and it is enabled if (!caExists && !customAction.Remove && customAction.Enabled) { // Then we add it to the target var customActionEntity = new CustomActionEntity() { #if !ONPREMISES ClientSideComponentId = customAction.ClientSideComponentId, ClientSideComponentProperties = customAction.ClientSideComponentProperties != null?parser.ParseString(customAction.ClientSideComponentProperties) : customAction.ClientSideComponentProperties, #endif CommandUIExtension = customAction.CommandUIExtension != null?parser.ParseString(customAction.CommandUIExtension.ToString()) : string.Empty, Description = parser.ParseString(customAction.Description), Group = customAction.Group, ImageUrl = parser.ParseString(customAction.ImageUrl), Location = customAction.Location, Name = customAction.Name, RegistrationId = customAction.RegistrationId, RegistrationType = customAction.RegistrationType, Remove = customAction.Remove, Rights = customAction.Rights, ScriptBlock = parser.ParseString(customAction.ScriptBlock), ScriptSrc = parser.ParseString(customAction.ScriptSrc, "~site", "~sitecollection"), Sequence = customAction.Sequence, Title = parser.ParseString(customAction.Title), Url = parser.ParseString(customAction.Url) }; if (site != null) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Adding_custom_action___0___to_scope_Site, customActionEntity.Name); site.AddCustomAction(customActionEntity); #if !ONPREMISES if ((!string.IsNullOrEmpty(customAction.Title) && customAction.Title.ContainsResourceToken()) || (!string.IsNullOrEmpty(customAction.Description) && customAction.Description.ContainsResourceToken())) { var uca = site.GetCustomActions().FirstOrDefault(uc => uc.Name == customAction.Name); SetCustomActionResourceValues(parser, customAction, uca); } #endif } else { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Adding_custom_action___0___to_scope_Web, customActionEntity.Name); web.AddCustomAction(customActionEntity); #if !ONPREMISES if (customAction.Title.ContainsResourceToken() || customAction.Description.ContainsResourceToken()) { var uca = web.GetCustomActions().FirstOrDefault(uc => uc.Name == customAction.Name); SetCustomActionResourceValues(parser, customAction, uca); } #endif } } else { UserCustomAction existingCustomAction; if (site != null) { existingCustomAction = site.GetCustomActions().FirstOrDefault(c => c.Name == customAction.Name); } else { existingCustomAction = web.GetCustomActions().FirstOrDefault(c => c.Name == customAction.Name); } if (existingCustomAction != null) { // If we have to remove the existing CustomAction if (customAction.Remove) { // We simply remove it existingCustomAction.DeleteObject(); existingCustomAction.Context.ExecuteQueryRetry(); } else { UpdateCustomAction(parser, scope, customAction, existingCustomAction, isNoScriptSite); } } } } }
public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { // if this is a sub site then we're not creating field entities. if (web.IsSubSite()) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Fields_Context_web_is_subweb__skipping_site_columns); return(template); } var existingFields = web.Fields; web.Context.Load(web, w => w.ServerRelativeUrl); web.Context.Load(existingFields, fs => fs.Include(f => f.Id, f => f.SchemaXml, f => f.TypeAsString, f => f.InternalName, f => f.Title)); web.Context.Load(web.Lists, ls => ls.Include(l => l.Id, l => l.Title)); web.Context.ExecuteQueryRetry(); var taxTextFieldsToMoveUp = new List <Guid>(); foreach (var field in existingFields) { if (!BuiltInFieldId.Contains(field.Id)) { var fieldXml = field.SchemaXml; XElement element = XElement.Parse(fieldXml); // Check if the field contains a reference to a list. If by Guid, rewrite the value of the attribute to use web relative paths var listIdentifier = element.Attribute("List") != null?element.Attribute("List").Value : null; if (!string.IsNullOrEmpty(listIdentifier)) { var listGuid = Guid.Empty; fieldXml = ParseFieldSchema(fieldXml, web.Lists); element = XElement.Parse(fieldXml); //if (Guid.TryParse(listIdentifier, out listGuid)) //{ // fieldXml = ParseListSchema(fieldXml, web.Lists); //if (newfieldXml == fieldXml) //{ // var list = web.Lists.GetById(listGuid); // web.Context.Load(list, l => l.RootFolder.ServerRelativeUrl); // web.Context.ExecuteQueryRetry(); // var listUrl = list.RootFolder.ServerRelativeUrl.Substring(web.ServerRelativeUrl.Length).TrimStart('/'); // element.Attribute("List").SetValue(listUrl); // fieldXml = element.ToString(); //} //} } // Check if the field is of type TaxonomyField if (field.TypeAsString.StartsWith("TaxonomyField")) { var taxField = (TaxonomyField)field; web.Context.Load(taxField, tf => tf.TextField, tf => tf.Id); web.Context.ExecuteQueryRetry(); taxTextFieldsToMoveUp.Add(taxField.TextField); fieldXml = TokenizeTaxonomyField(web, element); } // Check if we have version attribute. Remove if exists if (element.Attribute("Version") != null) { element.Attributes("Version").Remove(); fieldXml = element.ToString(); } if (element.Attribute("Type").Value == "Calculated") { fieldXml = TokenizeFieldFormula(fieldXml); } if (creationInfo.PersistMultiLanguageResources) { #if !SP2013 // only persist language values for fields we actually will keep...no point in spending time on this is we clean the field afterwards bool persistLanguages = true; if (creationInfo.BaseTemplate != null) { int index = creationInfo.BaseTemplate.SiteFields.FindIndex(f => Guid.Parse(XElement.Parse(f.SchemaXml).Attribute("ID").Value).Equals(field.Id)); if (index > -1) { persistLanguages = false; } } if (persistLanguages) { var fieldElement = XElement.Parse(fieldXml); if (UserResourceExtensions.PersistResourceValue(field.TitleResource, string.Format("Field_{0}_DisplayName", field.Title.Replace(" ", "_")), template, creationInfo)) { var fieldTitle = string.Format("{{res:Field_{0}_DisplayName}}", field.Title.Replace(" ", "_")); fieldElement.SetAttributeValue("DisplayName", fieldTitle); } if (UserResourceExtensions.PersistResourceValue(field.DescriptionResource, string.Format("Field_{0}_Description", field.Title.Replace(" ", "_")), template, creationInfo)) { var fieldDescription = string.Format("{{res:Field_{0}_Description}}", field.Title.Replace(" ", "_")); fieldElement.SetAttributeValue("Description", fieldDescription); } fieldXml = fieldElement.ToString(); } #endif } template.SiteFields.Add(new Field() { SchemaXml = fieldXml }); } } // move hidden taxonomy text fields to the top of the list foreach (var textFieldId in taxTextFieldsToMoveUp) { var field = template.SiteFields.First(f => Guid.Parse(f.SchemaXml.ElementAttributeValue("ID")).Equals(textFieldId)); template.SiteFields.RemoveAll(f => Guid.Parse(f.SchemaXml.ElementAttributeValue("ID")).Equals(textFieldId)); template.SiteFields.Insert(0, field); } // If a base template is specified then use that one to "cleanup" the generated template model if (creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate); } } return(template); }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { var systemPropertyBagEntriesExclusions = new List <string>(new[] { "_", "vti_", "dlc_", "ecm_", "profileschemaversion", "DesignPreview" }); // Check if this is not a noscript site as we're not allowed to write to the web property bag is that one bool isNoScriptSite = web.IsNoScriptSite(); if (isNoScriptSite) { return(parser); } // To handle situations where the propertybag is not updated fully when applying a theme, // we need to create a new context and use that one. Reloading the propertybag does not solve this. var webUrl = web.EnsureProperty(w => w.Url); var newContext = web.Context.Clone(webUrl); web = newContext.Web; foreach (var propbagEntry in template.PropertyBagEntries) { bool propExists = web.PropertyBagContainsKey(propbagEntry.Key); if (propbagEntry.Overwrite) { var systemProp = systemPropertyBagEntriesExclusions.Any(k => propbagEntry.Key.StartsWith(k, StringComparison.OrdinalIgnoreCase)); if (!systemProp || (systemProp && applyingInformation.OverwriteSystemPropertyBagValues)) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_PropertyBagEntries_Overwriting_existing_propertybag_entry__0__with_value__1_, propbagEntry.Key, propbagEntry.Value); web.SetPropertyBagValue(propbagEntry.Key, parser.ParseString(propbagEntry.Value)); if (propbagEntry.Indexed) { web.AddIndexedPropertyBagKey(propbagEntry.Key); } } } else { if (!propExists) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_PropertyBagEntries_Creating_new_propertybag_entry__0__with_value__1__2_, propbagEntry.Key, propbagEntry.Value, propbagEntry.Indexed ? ",Indexed = true" : ""); web.SetPropertyBagValue(propbagEntry.Key, parser.ParseString(propbagEntry.Value)); if (propbagEntry.Indexed) { web.AddIndexedPropertyBagKey(propbagEntry.Key); } } } } } return(parser); }
public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { // if this is a sub site then we're not creating field entities. if (web.IsSubSite()) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Fields_Context_web_is_subweb__skipping_site_columns); return template; } var existingFields = web.Fields; web.Context.Load(web, w => w.ServerRelativeUrl); web.Context.Load(existingFields, fs => fs.Include(f => f.Id, f => f.SchemaXml, f => f.TypeAsString, f => f.InternalName, f => f.Title)); web.Context.Load(web.Lists, ls => ls.Include(l => l.Id, l => l.Title)); web.Context.ExecuteQueryRetry(); var taxTextFieldsToMoveUp = new List<Guid>(); foreach (var field in existingFields) { if (!BuiltInFieldId.Contains(field.Id)) { var fieldXml = field.SchemaXml; XElement element = XElement.Parse(fieldXml); // Check if the field contains a reference to a list. If by Guid, rewrite the value of the attribute to use web relative paths var listIdentifier = element.Attribute("List") != null ? element.Attribute("List").Value : null; if (!string.IsNullOrEmpty(listIdentifier)) { var listGuid = Guid.Empty; fieldXml = ParseFieldSchema(fieldXml, web.Lists); element = XElement.Parse(fieldXml); //if (Guid.TryParse(listIdentifier, out listGuid)) //{ // fieldXml = ParseListSchema(fieldXml, web.Lists); //if (newfieldXml == fieldXml) //{ // var list = web.Lists.GetById(listGuid); // web.Context.Load(list, l => l.RootFolder.ServerRelativeUrl); // web.Context.ExecuteQueryRetry(); // var listUrl = list.RootFolder.ServerRelativeUrl.Substring(web.ServerRelativeUrl.Length).TrimStart('/'); // element.Attribute("List").SetValue(listUrl); // fieldXml = element.ToString(); //} //} } // Check if the field is of type TaxonomyField if (field.TypeAsString.StartsWith("TaxonomyField")) { var taxField = (TaxonomyField)field; web.Context.Load(taxField, tf => tf.TextField, tf => tf.Id); web.Context.ExecuteQueryRetry(); taxTextFieldsToMoveUp.Add(taxField.TextField); // Replace Taxonomy field references to SspId, TermSetId with tokens TaxonomySession session = TaxonomySession.GetTaxonomySession(web.Context); TermStore store = session.GetDefaultSiteCollectionTermStore(); var sspIdElement = element.XPathSelectElement("./Customization/ArrayOfProperty/Property[Name = 'SspId']/Value"); if (sspIdElement != null) { sspIdElement.Value = "{sitecollectiontermstoreid}"; } var termSetIdElement = element.XPathSelectElement("./Customization/ArrayOfProperty/Property[Name = 'TermSetId']/Value"); if (termSetIdElement != null) { Guid termSetId = Guid.Parse(termSetIdElement.Value); if (termSetId != Guid.Empty) { Microsoft.SharePoint.Client.Taxonomy.TermSet termSet = store.GetTermSet(termSetId); if (!termSet.ServerObjectIsNull()) { termSet.EnsureProperties(ts => ts.Name, ts => ts.Group); termSetIdElement.Value = String.Format("{{termsetid:{0}:{1}}}", termSet.Group.Name, termSet.Name); // TODO } } } } // Check if we have version attribute. Remove if exists if (element.Attribute("Version") != null) { element.Attributes("Version").Remove(); fieldXml = element.ToString(); } if (element.Attribute("Type").Value == "Calculated") { fieldXml = TokenizeFieldFormula(fieldXml); } template.SiteFields.Add(new Field() { SchemaXml = fieldXml }); } } // move hidden taxonomy text fields to the top of the list foreach (var textFieldId in taxTextFieldsToMoveUp) { var field = template.SiteFields.First(f => Guid.Parse(f.SchemaXml.ElementAttributeValue("ID")).Equals(textFieldId)); template.SiteFields.RemoveAll(f => Guid.Parse(f.SchemaXml.ElementAttributeValue("ID")).Equals(textFieldId)); template.SiteFields.Insert(0, field); } // If a base template is specified then use that one to "cleanup" the generated template model if (creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate); } } return template; }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { if (template.Navigation != null) { // The Navigation handler works only for sites with Publishing Features enabled if (!web.IsPublishingWeb()) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Navigation_Context_web_is_not_publishing); return(parser); } // Retrieve the current web navigation settings var navigationSettings = new WebNavigationSettings(web.Context, web); web.Context.Load(navigationSettings, ns => ns.CurrentNavigation, ns => ns.GlobalNavigation); web.Context.ExecuteQueryRetry(); if (template.Navigation.GlobalNavigation != null) { switch (template.Navigation.GlobalNavigation.NavigationType) { case GlobalNavigationType.Inherit: navigationSettings.GlobalNavigation.Source = StandardNavigationSource.InheritFromParentWeb; break; case GlobalNavigationType.Managed: if (template.Navigation.GlobalNavigation.ManagedNavigation == null) { throw new ApplicationException(CoreResources.Provisioning_ObjectHandlers_Navigation_missing_global_managed_navigation); } navigationSettings.GlobalNavigation.Source = StandardNavigationSource.TaxonomyProvider; navigationSettings.GlobalNavigation.TermStoreId = Guid.Parse(parser.ParseString(template.Navigation.GlobalNavigation.ManagedNavigation.TermStoreId)); navigationSettings.GlobalNavigation.TermSetId = Guid.Parse(parser.ParseString(template.Navigation.GlobalNavigation.ManagedNavigation.TermSetId)); break; case GlobalNavigationType.Structural: default: if (template.Navigation.GlobalNavigation.StructuralNavigation == null) { throw new ApplicationException(CoreResources.Provisioning_ObjectHandlers_Navigation_missing_global_structural_navigation); } ProvisionGlobalStructuralNavigation(web, template.Navigation.GlobalNavigation.StructuralNavigation, parser); break; } web.Context.ExecuteQueryRetry(); } if (template.Navigation.CurrentNavigation != null) { switch (template.Navigation.CurrentNavigation.NavigationType) { case CurrentNavigationType.Inherit: navigationSettings.CurrentNavigation.Source = StandardNavigationSource.InheritFromParentWeb; break; case CurrentNavigationType.Managed: if (template.Navigation.CurrentNavigation.ManagedNavigation == null) { throw new ApplicationException(CoreResources.Provisioning_ObjectHandlers_Navigation_missing_current_managed_navigation); } navigationSettings.CurrentNavigation.Source = StandardNavigationSource.TaxonomyProvider; navigationSettings.CurrentNavigation.TermStoreId = Guid.Parse(parser.ParseString(template.Navigation.CurrentNavigation.ManagedNavigation.TermStoreId)); navigationSettings.CurrentNavigation.TermSetId = Guid.Parse(parser.ParseString(template.Navigation.CurrentNavigation.ManagedNavigation.TermSetId)); break; case CurrentNavigationType.StructuralLocal: web.SetPropertyBagValue(NavigationShowSiblings, "false"); if (template.Navigation.CurrentNavigation.StructuralNavigation == null) { throw new ApplicationException(CoreResources.Provisioning_ObjectHandlers_Navigation_missing_current_structural_navigation); } ProvisionCurrentStructuralNavigation(web, template.Navigation.CurrentNavigation.StructuralNavigation, parser); break; case CurrentNavigationType.Structural: default: if (template.Navigation.CurrentNavigation.StructuralNavigation == null) { throw new ApplicationException(CoreResources.Provisioning_ObjectHandlers_Navigation_missing_current_structural_navigation); } ProvisionCurrentStructuralNavigation(web, template.Navigation.CurrentNavigation.StructuralNavigation, parser); break; } web.Context.ExecuteQueryRetry(); } } } return(parser); }
public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { web.EnsureProperties(w => w.ServerRelativeUrl, w => w.Url); var serverRelativeUrl = web.ServerRelativeUrl; // For each list in the site var lists = web.Lists; web.Context.Load(lists, lc => lc.IncludeWithDefaultProperties( l => l.ContentTypes, l => l.Views, l => l.BaseTemplate, l => l.OnQuickLaunch, l => l.RootFolder.ServerRelativeUrl, l => l.Fields.IncludeWithDefaultProperties( f => f.Id, f => f.Title, f => f.Hidden, f => f.InternalName, f => f.Required))); web.Context.ExecuteQueryRetry(); // Let's see if there are workflow subscriptions Microsoft.SharePoint.Client.WorkflowServices.WorkflowSubscription[] workflowSubscriptions = null; try { workflowSubscriptions = web.GetWorkflowSubscriptions(); } catch (ServerException) { // If there is no workflow service present in the farm this method will throw an error. // Swallow the exception } // Retrieve all not hidden lists and the Workflow History Lists, just in case there are active workflow subscriptions var includeWorkflowSubscriptions = workflowSubscriptions != null && workflowSubscriptions.Length > 0; // var allowedLists = lists.Where(l => !l.Hidden || includeWorkflowSubscriptions && l.BaseTemplate == 140); foreach (var siteList in lists) { ListInstance baseTemplateList = null; if (creationInfo.BaseTemplate != null) { // Check if we need to skip this list...if so let's do it before we gather all the other information for this list...improves performance var index = creationInfo.BaseTemplate.Lists.FindIndex(f => f.Url.Equals(siteList.RootFolder.ServerRelativeUrl.Substring(serverRelativeUrl.Length + 1)) && f.TemplateType.Equals(siteList.BaseTemplate)); if (index != -1) { baseTemplateList = creationInfo.BaseTemplate.Lists[index]; if (siteList.Hidden && !(includeWorkflowSubscriptions && siteList.BaseTemplate == 140)) { continue; } } } var contentTypeFields = new List<FieldRef>(); var list = new ListInstance { Description = siteList.Description, EnableVersioning = siteList.EnableVersioning, TemplateType = siteList.BaseTemplate, Title = siteList.Title, Hidden = siteList.Hidden, EnableFolderCreation = siteList.EnableFolderCreation, DocumentTemplate = Tokenize(siteList.DocumentTemplateUrl, web.Url), ContentTypesEnabled = siteList.ContentTypesEnabled, Url = siteList.RootFolder.ServerRelativeUrl.Substring(serverRelativeUrl.Length).TrimStart('/'), TemplateFeatureID = siteList.TemplateFeatureId, EnableAttachments = siteList.EnableAttachments, OnQuickLaunch = siteList.OnQuickLaunch, MaxVersionLimit = siteList.IsObjectPropertyInstantiated("MajorVersionLimit") ? siteList.MajorVersionLimit : 0, EnableMinorVersions = siteList.EnableMinorVersions, MinorVersionLimit = siteList.IsObjectPropertyInstantiated("MajorWithMinorVersionsLimit") ? siteList.MajorWithMinorVersionsLimit : 0 }; list = ExtractContentTypes(web, siteList, contentTypeFields, list); list = ExtractViews(siteList, list); list = ExtractFields(web, siteList, contentTypeFields, list, lists); list.Security = siteList.GetSecurity(); var logCTWarning = false; if (baseTemplateList != null) { if (!baseTemplateList.Equals(list)) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Adding_list___0_____1_, list.Title, list.Url); template.Lists.Add(list); if (list.ContentTypesEnabled && list.ContentTypeBindings.Any() && web.IsSubSite()) { logCTWarning = true; } } } else { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Adding_list___0_____1_, list.Title, list.Url); template.Lists.Add(list); if (list.ContentTypesEnabled && list.ContentTypeBindings.Any() && web.IsSubSite()) { logCTWarning = true; } } if (logCTWarning) { scope.LogWarning("You are extracting a template from a subweb. List '{0}' refers to content types. Content types are not exported when extracting a template from a subweb", list.Title); WriteWarning(string.Format("You are extracting a template from a subweb. List '{0}' refers to content types. Content types are not exported when extracting a template from a subweb", list.Title), ProvisioningMessageType.Warning); } } } return template; }
private void DownLoadFile(SharePointConnector reader, SharePointConnector readerRoot, FileConnectorBase writer, string webUrl, string asset, PnPMonitoredScope scope) { // No file passed...leave if (String.IsNullOrEmpty(asset)) { return; } scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_DownLoadFile_Downloading_asset___0_, asset); ; SharePointConnector readerToUse; Model.File f = GetComposedLookFile(asset); // Strip the /sites/root part from /sites/root/lib/folder structure Uri u = new Uri(webUrl); if (f.Folder.IndexOf(u.PathAndQuery, StringComparison.InvariantCultureIgnoreCase) > -1) { f.Folder = f.Folder.Replace(u.PathAndQuery, ""); } // in case of a theme catalog we need to use the root site reader as that list only exists on root site level if (f.Folder.IndexOf("/_catalogs/theme", StringComparison.InvariantCultureIgnoreCase) > -1) { readerToUse = readerRoot; } else { readerToUse = reader; } using (Stream s = readerToUse.GetFileStream(f.Src, f.Folder)) { if (s != null) { writer.SaveFileStream(f.Src, s); } } }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { // if this is a sub site then we're not provisioning security as by default security is inherited from the root site if (web.IsSubSite()) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_SiteSecurity_Context_web_is_subweb__skipping_site_security_provisioning); return parser; } var siteSecurity = template.Security; var ownerGroup = web.AssociatedOwnerGroup; var memberGroup = web.AssociatedMemberGroup; var visitorGroup = web.AssociatedVisitorGroup; web.Context.Load(ownerGroup, o => o.Title, o => o.Users); web.Context.Load(memberGroup, o => o.Title, o => o.Users); web.Context.Load(visitorGroup, o => o.Title, o => o.Users); web.Context.ExecuteQueryRetry(); if (!ownerGroup.ServerObjectIsNull.Value) { AddUserToGroup(web, ownerGroup, siteSecurity.AdditionalOwners, scope); } if (!memberGroup.ServerObjectIsNull.Value) { AddUserToGroup(web, memberGroup, siteSecurity.AdditionalMembers, scope); } if (!visitorGroup.ServerObjectIsNull.Value) { AddUserToGroup(web, visitorGroup, siteSecurity.AdditionalVisitors, scope); } foreach (var siteGroup in siteSecurity.SiteGroups) { Group group = null; var allGroups = web.Context.LoadQuery(web.SiteGroups.Include(gr => gr.LoginName)); web.Context.ExecuteQueryRetry(); if (!web.GroupExists(siteGroup.Title)) { scope.LogDebug("Creating group {0}", siteGroup.Title); group = web.AddGroup( parser.ParseString(siteGroup.Title), parser.ParseString(siteGroup.Description), parser.ParseString(siteGroup.Title) == parser.ParseString(siteGroup.Owner)); group.AllowMembersEditMembership = siteGroup.AllowMembersEditMembership; group.AllowRequestToJoinLeave = siteGroup.AllowRequestToJoinLeave; group.AutoAcceptRequestToJoinLeave = siteGroup.AutoAcceptRequestToJoinLeave; if (parser.ParseString(siteGroup.Title) != parser.ParseString(siteGroup.Owner)) { Principal ownerPrincipal = allGroups.FirstOrDefault(gr => gr.LoginName == parser.ParseString(siteGroup.Owner)); if (ownerPrincipal == null) { ownerPrincipal = web.EnsureUser(parser.ParseString(siteGroup.Owner)); } group.Owner = ownerPrincipal; } group.Update(); web.Context.ExecuteQueryRetry(); } else { group = web.SiteGroups.GetByName(parser.ParseString(siteGroup.Title)); web.Context.Load(group, g => g.Title, g => g.Description, g => g.AllowMembersEditMembership, g => g.AllowRequestToJoinLeave, g => g.AutoAcceptRequestToJoinLeave, g => g.Owner.LoginName); web.Context.ExecuteQueryRetry(); var isDirty = false; if (group.Description != parser.ParseString(siteGroup.Description)) { group.Description = parser.ParseString(siteGroup.Description); isDirty = true; } if (group.AllowMembersEditMembership != siteGroup.AllowMembersEditMembership) { group.AllowMembersEditMembership = siteGroup.AllowMembersEditMembership; isDirty = true; } if (group.AllowRequestToJoinLeave != siteGroup.AllowRequestToJoinLeave) { group.AllowRequestToJoinLeave = siteGroup.AllowRequestToJoinLeave; isDirty = true; } if (group.AutoAcceptRequestToJoinLeave != siteGroup.AutoAcceptRequestToJoinLeave) { group.AutoAcceptRequestToJoinLeave = siteGroup.AutoAcceptRequestToJoinLeave; isDirty = true; } if (group.Owner.LoginName != parser.ParseString(siteGroup.Owner)) { if (parser.ParseString(siteGroup.Title) != parser.ParseString(siteGroup.Owner)) { Principal ownerPrincipal = allGroups.FirstOrDefault(gr => gr.LoginName == parser.ParseString(siteGroup.Owner)); if (ownerPrincipal == null) { ownerPrincipal = web.EnsureUser(parser.ParseString(siteGroup.Owner)); } group.Owner = ownerPrincipal; } else { group.Owner = group; } isDirty = true; } if (isDirty) { scope.LogDebug("Updating existing group {0}", group.Title); group.Update(); web.Context.ExecuteQueryRetry(); } } if (group != null && siteGroup.Members.Any()) { AddUserToGroup(web, group, siteGroup.Members, scope); } } foreach (var admin in siteSecurity.AdditionalAdministrators) { var user = web.EnsureUser(admin.Name); user.IsSiteAdmin = true; user.Update(); web.Context.ExecuteQueryRetry(); } if (siteSecurity.SiteSecurityPermissions != null) { var existingRoleDefinitions = web.Context.LoadQuery(web.RoleDefinitions.Include(wr => wr.Name, wr => wr.BasePermissions, wr => wr.Description)); web.Context.ExecuteQueryRetry(); if (siteSecurity.SiteSecurityPermissions.RoleDefinitions.Any()) { foreach (var templateRoleDefinition in siteSecurity.SiteSecurityPermissions.RoleDefinitions) { var siteRoleDefinition = existingRoleDefinitions.FirstOrDefault(erd => erd.Name == parser.ParseString(templateRoleDefinition.Name)); if (siteRoleDefinition == null) { scope.LogDebug("Creation role definition {0}", parser.ParseString(templateRoleDefinition.Name)); var roleDefinitionCI = new RoleDefinitionCreationInformation(); roleDefinitionCI.Name = parser.ParseString(templateRoleDefinition.Name); roleDefinitionCI.Description = parser.ParseString(templateRoleDefinition.Description); BasePermissions basePermissions = new BasePermissions(); foreach (var permission in templateRoleDefinition.Permissions) { basePermissions.Set(permission); } roleDefinitionCI.BasePermissions = basePermissions; web.RoleDefinitions.Add(roleDefinitionCI); web.Context.ExecuteQueryRetry(); } else { var isDirty = false; if (siteRoleDefinition.Description != parser.ParseString(templateRoleDefinition.Description)) { siteRoleDefinition.Description = parser.ParseString(templateRoleDefinition.Description); isDirty = true; } var templateBasePermissions = new BasePermissions(); templateRoleDefinition.Permissions.ForEach(p => templateBasePermissions.Set(p)); if (siteRoleDefinition.BasePermissions != templateBasePermissions) { isDirty = true; foreach (var permission in templateRoleDefinition.Permissions) { siteRoleDefinition.BasePermissions.Set(permission); } } if (isDirty) { scope.LogDebug("Updating role definition {0}", parser.ParseString(templateRoleDefinition.Name)); siteRoleDefinition.Update(); web.Context.ExecuteQueryRetry(); } } } } var webRoleDefinitions = web.Context.LoadQuery(web.RoleDefinitions); var groups = web.Context.LoadQuery(web.SiteGroups.Include(g => g.LoginName)); web.Context.ExecuteQueryRetry(); if (siteSecurity.SiteSecurityPermissions.RoleAssignments.Any()) { foreach (var roleAssignment in siteSecurity.SiteSecurityPermissions.RoleAssignments) { Principal principal = groups.FirstOrDefault(g => g.LoginName == parser.ParseString(roleAssignment.Principal)); if (principal == null) { principal = web.EnsureUser(parser.ParseString(roleAssignment.Principal)); } var roleDefinitionBindingCollection = new RoleDefinitionBindingCollection(web.Context); var roleDefinition = webRoleDefinitions.FirstOrDefault(r => r.Name == roleAssignment.RoleDefinition); if (roleDefinition != null) { roleDefinitionBindingCollection.Add(roleDefinition); } web.RoleAssignments.Add(principal, roleDefinitionBindingCollection); web.Context.ExecuteQueryRetry(); } } } } return parser; }
/// <summary> /// Actual implementation of extracting configuration from existing site. /// </summary> /// <param name="web"></param> /// <param name="creationInfo"></param> /// <returns></returns> internal ProvisioningTemplate GetRemoteTemplate(Web web, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(CoreResources.Provisioning_ObjectHandlers_Extraction)) { ProvisioningProgressDelegate progressDelegate = null; ProvisioningMessagesDelegate messagesDelegate = null; if (creationInfo != null) { if (creationInfo.BaseTemplate != null) { scope.LogDebug(CoreResources.SiteToTemplateConversion_Base_template_available___0_, creationInfo.BaseTemplate.Id); } progressDelegate = creationInfo.ProgressDelegate; if (creationInfo.ProgressDelegate != null) { scope.LogDebug(CoreResources.SiteToTemplateConversion_ProgressDelegate_registered); } messagesDelegate = creationInfo.MessagesDelegate; if (creationInfo.MessagesDelegate != null) { scope.LogDebug(CoreResources.SiteToTemplateConversion_MessagesDelegate_registered); } if (creationInfo.IncludeAllTermGroups) { scope.LogDebug(CoreResources.SiteToTemplateConversion_IncludeAllTermGroups_is_set_to_true); } if (creationInfo.IncludeSiteCollectionTermGroup) { scope.LogDebug(CoreResources.SiteToTemplateConversion_IncludeSiteCollectionTermGroup_is_set_to_true); } if (creationInfo.PersistComposedLookFiles) { scope.LogDebug(CoreResources.SiteToTemplateConversion_PersistComposedLookFiles_is_set_to_true); } } // Create empty object ProvisioningTemplate template = new ProvisioningTemplate(); // Hookup connector, is handy when the generated template object is used to apply to another site template.Connector = creationInfo.FileConnector; List <ObjectHandlerBase> objectHandlers = new List <ObjectHandlerBase>(); objectHandlers.Add(new ObjectRegionalSettings()); objectHandlers.Add(new ObjectSupportedUILanguages()); objectHandlers.Add(new ObjectAuditSettings()); objectHandlers.Add(new ObjectSitePolicy()); objectHandlers.Add(new ObjectSiteSecurity()); objectHandlers.Add(new ObjectTermGroups()); objectHandlers.Add(new ObjectField()); objectHandlers.Add(new ObjectContentType()); objectHandlers.Add(new ObjectListInstance()); objectHandlers.Add(new ObjectCustomActions()); objectHandlers.Add(new ObjectFeatures()); objectHandlers.Add(new ObjectComposedLook()); objectHandlers.Add(new ObjectSearchSettings()); objectHandlers.Add(new ObjectFiles()); objectHandlers.Add(new ObjectPages()); objectHandlers.Add(new ObjectPropertyBagEntry()); objectHandlers.Add(new ObjectPublishing()); objectHandlers.Add(new ObjectWorkflows()); objectHandlers.Add(new ObjectRetrieveTemplateInfo()); int step = 1; var count = objectHandlers.Count(o => o.ReportProgress && o.WillExtract(web, template, creationInfo)); foreach (var handler in objectHandlers) { if (handler.WillExtract(web, template, creationInfo)) { if (messagesDelegate != null) { handler.MessagesDelegate = messagesDelegate; } if (handler.ReportProgress && progressDelegate != null) { progressDelegate(handler.Name, step, count); step++; } template = handler.ExtractObjects(web, template, creationInfo); } } return(template); } }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { if (template.Lists.Any()) { var rootWeb = (web.Context as ClientContext).Site.RootWeb; web.EnsureProperties(w => w.ServerRelativeUrl); web.Context.Load(web.Lists, lc => lc.IncludeWithDefaultProperties(l => l.RootFolder.ServerRelativeUrl)); web.Context.ExecuteQueryRetry(); var existingLists = web.Lists.AsEnumerable <List>().Select(existingList => existingList.RootFolder.ServerRelativeUrl).ToList(); var serverRelativeUrl = web.ServerRelativeUrl; #region DataRows foreach (var listInstance in template.Lists) { if (listInstance.DataRows != null && listInstance.DataRows.Any()) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Processing_data_rows_for__0_, listInstance.Title); // Retrieve the target list var list = web.Lists.GetByTitle(parser.ParseString(listInstance.Title)); web.Context.Load(list); // Retrieve the fields' types from the list Microsoft.SharePoint.Client.FieldCollection fields = list.Fields; web.Context.Load(fields, fs => fs.Include(f => f.InternalName, f => f.FieldTypeKind)); web.Context.ExecuteQueryRetry(); foreach (var dataRow in listInstance.DataRows) { try { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Creating_list_item__0_, listInstance.DataRows.IndexOf(dataRow) + 1); var listitemCI = new ListItemCreationInformation(); var listitem = list.AddItem(listitemCI); foreach (var dataValue in dataRow.Values) { Field dataField = fields.FirstOrDefault( f => f.InternalName == parser.ParseString(dataValue.Key)); if (dataField != null) { String fieldValue = parser.ParseString(dataValue.Value); switch (dataField.FieldTypeKind) { case FieldType.Geolocation: // FieldGeolocationValue - Expected format: Altitude,Latitude,Longitude,Measure var geolocationArray = fieldValue.Split(','); if (geolocationArray.Length == 4) { var geolocationValue = new FieldGeolocationValue { Altitude = Double.Parse(geolocationArray[0]), Latitude = Double.Parse(geolocationArray[1]), Longitude = Double.Parse(geolocationArray[2]), Measure = Double.Parse(geolocationArray[3]), }; listitem[parser.ParseString(dataValue.Key)] = geolocationValue; } else { listitem[parser.ParseString(dataValue.Key)] = fieldValue; } break; case FieldType.Lookup: // FieldLookupValue - Expected format: LookupID or LookupID,LookupID,LookupID... if (fieldValue.Contains(",")) { var lookupValues = new List <FieldLookupValue>(); fieldValue.Split(',').All(value => { lookupValues.Add(new FieldLookupValue { LookupId = int.Parse(value), }); return(true); }); listitem[parser.ParseString(dataValue.Key)] = lookupValues.ToArray(); } else { var lookupValue = new FieldLookupValue { LookupId = int.Parse(fieldValue), }; listitem[parser.ParseString(dataValue.Key)] = lookupValue; } break; case FieldType.URL: // FieldUrlValue - Expected format: URL,Description var urlArray = fieldValue.Split(','); var linkValue = new FieldUrlValue(); if (urlArray.Length == 2) { linkValue.Url = urlArray[0]; linkValue.Description = urlArray[1]; } else { linkValue.Url = urlArray[0]; linkValue.Description = urlArray[0]; } listitem[parser.ParseString(dataValue.Key)] = linkValue; break; case FieldType.User: // FieldUserValue - Expected format: loginName or loginName,loginName,loginName... if (fieldValue.Contains(",")) { var userValues = new List <FieldUserValue>(); fieldValue.Split(',').All(value => { var user = web.EnsureUser(value); web.Context.Load(user); web.Context.ExecuteQueryRetry(); if (user != null) { userValues.Add(new FieldUserValue { LookupId = user.Id, });; } return(true); }); listitem[parser.ParseString(dataValue.Key)] = userValues.ToArray(); } else { var user = web.EnsureUser(fieldValue); web.Context.Load(user); web.Context.ExecuteQueryRetry(); if (user != null) { var userValue = new FieldUserValue { LookupId = user.Id, }; listitem[parser.ParseString(dataValue.Key)] = userValue; } else { listitem[parser.ParseString(dataValue.Key)] = fieldValue; } } break; case FieldType.DateTime: var dateTime = DateTime.MinValue; if (DateTime.TryParse(fieldValue, out dateTime)) { listitem[parser.ParseString(dataValue.Key)] = dateTime; } break; default: listitem[parser.ParseString(dataValue.Key)] = fieldValue; break; } } } listitem.Update(); web.Context.ExecuteQueryRetry(); // TODO: Run in batches? if (dataRow.Security != null && dataRow.Security.RoleAssignments.Count != 0) { listitem.SetSecurity(parser, dataRow.Security); } } catch (Exception ex) { if (ex.GetType().Equals(typeof(ServerException)) && (ex as ServerException).ServerErrorTypeName.Equals("Microsoft.SharePoint.SPDuplicateValuesFoundException", StringComparison.InvariantCultureIgnoreCase) && applyingInformation.IgnoreDuplicateDataRowErrors) { scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Creating_listitem_duplicate); continue; } else { scope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Creating_listitem_failed___0_____1_, ex.Message, ex.StackTrace); throw; } } } } } #endregion } } return(parser); }
private void ProvisionCustomActionImplementation(object parent, List<CustomAction> customActions, TokenParser parser, PnPMonitoredScope scope) { Web web = null; Site site = null; if (parent is Site) { site = parent as Site; // Switch parser context; parser.Rebase(site.RootWeb); } else { web = parent as Web; // Switch parser context parser.Rebase(web); } foreach (var customAction in customActions) { var caExists = false; if (site != null) { caExists = site.CustomActionExists(customAction.Name); } else { caExists = web.CustomActionExists(customAction.Name); } if (!caExists) { var customActionEntity = new CustomActionEntity() { CommandUIExtension = customAction.CommandUIExtension != null ? parser.ParseString(customAction.CommandUIExtension.ToString()) : string.Empty, Description = customAction.Description, Group = customAction.Group, ImageUrl = parser.ParseString(customAction.ImageUrl), Location = customAction.Location, Name = customAction.Name, RegistrationId = customAction.RegistrationId, RegistrationType = customAction.RegistrationType, Remove = customAction.Remove, Rights = customAction.Rights, ScriptBlock = parser.ParseString(customAction.ScriptBlock), ScriptSrc = parser.ParseString(customAction.ScriptSrc, "~site", "~sitecollection"), Sequence = customAction.Sequence, Title = customAction.Title, Url = parser.ParseString(customAction.Url) }; if (site != null) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Adding_custom_action___0___to_scope_Site, customActionEntity.Name); site.AddCustomAction(customActionEntity); } else { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Adding_custom_action___0___to_scope_Web, customActionEntity.Name); web.AddCustomAction(customActionEntity); } } else { UserCustomAction existingCustomAction = null; if (site != null) { existingCustomAction = site.GetCustomActions().FirstOrDefault(c => c.Name == customAction.Name); } else { existingCustomAction = web.GetCustomActions().FirstOrDefault(c => c.Name == customAction.Name); } if (existingCustomAction != null) { var isDirty = false; if (customAction.CommandUIExtension != null) { if (existingCustomAction.CommandUIExtension != parser.ParseString(customAction.CommandUIExtension.ToString())) { scope.LogPropertyUpdate("CommandUIExtension"); existingCustomAction.CommandUIExtension = parser.ParseString(customAction.CommandUIExtension.ToString()); isDirty = true; } } if (existingCustomAction.Description != customAction.Description) { scope.LogPropertyUpdate("Description"); existingCustomAction.Description = customAction.Description; isDirty = true; } if (existingCustomAction.Group != customAction.Group) { scope.LogPropertyUpdate("Group"); existingCustomAction.Group = customAction.Group; isDirty = true; } if (existingCustomAction.ImageUrl != parser.ParseString(customAction.ImageUrl)) { scope.LogPropertyUpdate("ImageUrl"); existingCustomAction.ImageUrl = parser.ParseString(customAction.ImageUrl); isDirty = true; } if (existingCustomAction.Location != customAction.Location) { scope.LogPropertyUpdate("Location"); existingCustomAction.Location = customAction.Location; isDirty = true; } if (existingCustomAction.RegistrationId != customAction.RegistrationId) { scope.LogPropertyUpdate("RegistrationId"); existingCustomAction.RegistrationId = customAction.RegistrationId; isDirty = true; } if (existingCustomAction.RegistrationType != customAction.RegistrationType) { scope.LogPropertyUpdate("RegistrationType"); existingCustomAction.RegistrationType = customAction.RegistrationType; isDirty = true; } if (existingCustomAction.ScriptBlock != parser.ParseString(customAction.ScriptBlock)) { scope.LogPropertyUpdate("ScriptBlock"); existingCustomAction.ScriptBlock = parser.ParseString(customAction.ScriptBlock); isDirty = true; } if (existingCustomAction.ScriptSrc != parser.ParseString(customAction.ScriptSrc, "~site", "~sitecollection")) { scope.LogPropertyUpdate("ScriptSrc"); existingCustomAction.ScriptSrc = parser.ParseString(customAction.ScriptSrc, "~site", "~sitecollection"); isDirty = true; } if (existingCustomAction.Title != parser.ParseString(customAction.Title)) { scope.LogPropertyUpdate("Title"); existingCustomAction.Title = parser.ParseString(customAction.Title); isDirty = true; } if (existingCustomAction.Url != parser.ParseString(customAction.Url)) { scope.LogPropertyUpdate("Url"); existingCustomAction.Url = parser.ParseString(customAction.Url); isDirty = true; } if (isDirty) { existingCustomAction.Update(); existingCustomAction.Context.ExecuteQueryRetry(); } } } } }
private static TokenParser ProvisionFeaturesImplementation <T>(T parent, IEnumerable <Feature> features, TokenParser parser, PnPMonitoredScope scope) { var activeFeatures = new List <Microsoft.SharePoint.Client.Feature>(); Web web = null; Site site = null; if (parent is Site) { site = parent as Site; site.Context.Load(site.Features, fs => fs.Include(f => f.DefinitionId)); site.Context.ExecuteQueryRetry(); activeFeatures = site.Features.ToList(); } else { web = parent as Web; web.Context.Load(web.Features, fs => fs.Include(f => f.DefinitionId)); web.Context.ExecuteQueryRetry(); activeFeatures = web.Features.ToList(); } if (features != null) { foreach (var feature in features) { if (!feature.Deactivate) { if (activeFeatures.FirstOrDefault(f => f.DefinitionId == feature.Id) == null) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Features_Activating__0__scoped_feature__1_, site != null ? "site" : "web", feature.Id); if (site != null) { try { site.ActivateFeature(feature.Id); } catch (ServerException ex) { scope.LogError("Error activating feature {0}: {1}", feature.Id, ex.Message); } } else { try { web.ActivateFeature(feature.Id); } catch (ServerException ex) { scope.LogError("Error activating feature {0}: {1}", feature.Id, ex.Message); } } } } else { if (activeFeatures.FirstOrDefault(f => f.DefinitionId == feature.Id) != null) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Features_Deactivating__0__scoped_feature__1_, site != null ? "site" : "web", feature.Id); if (site != null) { try { site.DeactivateFeature(feature.Id); } catch (ServerException ex) { scope.LogError("Error deactivating feature {0}: {1}", feature.Id, ex.Message); } } else { try { web.DeactivateFeature(feature.Id); } catch (ServerException ex) { scope.LogError("Error deactivating feature {0}: {1}", feature.Id, ex.Message); } } } } } } if (parent is Site) { parser.RebuildListTokens((parent as Site).RootWeb); } else { parser.RebuildListTokens(parent as Web); } return(parser); }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { // Changed by Paolo Pialorsi to embrace the new sub-site attributes for break role inheritance and copy role assignments // if this is a sub site then we're not provisioning security as by default security is inherited from the root site //if (web.IsSubSite() && !template.Security.BreakRoleInheritance) //{ // scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_SiteSecurity_Context_web_is_subweb__skipping_site_security_provisioning); // return parser; //} if (web.IsSubSite() && template.Security.BreakRoleInheritance) { web.BreakRoleInheritance(template.Security.CopyRoleAssignments, template.Security.ClearSubscopes); web.Update(); web.Context.ExecuteQueryRetry(); } var siteSecurity = template.Security; var ownerGroup = web.AssociatedOwnerGroup; var memberGroup = web.AssociatedMemberGroup; var visitorGroup = web.AssociatedVisitorGroup; web.Context.Load(ownerGroup, o => o.Title, o => o.Users); web.Context.Load(memberGroup, o => o.Title, o => o.Users); web.Context.Load(visitorGroup, o => o.Title, o => o.Users); web.Context.ExecuteQueryRetry(); if (!ownerGroup.ServerObjectIsNull.Value) { AddUserToGroup(web, ownerGroup, siteSecurity.AdditionalOwners, scope, parser); } if (!memberGroup.ServerObjectIsNull.Value) { AddUserToGroup(web, memberGroup, siteSecurity.AdditionalMembers, scope, parser); } if (!visitorGroup.ServerObjectIsNull.Value) { AddUserToGroup(web, visitorGroup, siteSecurity.AdditionalVisitors, scope, parser); } foreach (var siteGroup in siteSecurity.SiteGroups) { Group group; var allGroups = web.Context.LoadQuery(web.SiteGroups.Include(gr => gr.LoginName)); web.Context.ExecuteQueryRetry(); string parsedGroupTitle = parser.ParseString(siteGroup.Title); string parsedGroupOwner = parser.ParseString(siteGroup.Owner); string parsedGroupDescription = parser.ParseString(siteGroup.Description); if (!web.GroupExists(parsedGroupTitle)) { scope.LogDebug("Creating group {0}", parsedGroupTitle); group = web.AddGroup( parsedGroupTitle, parsedGroupDescription, parsedGroupTitle == parsedGroupOwner); group.AllowMembersEditMembership = siteGroup.AllowMembersEditMembership; group.AllowRequestToJoinLeave = siteGroup.AllowRequestToJoinLeave; group.AutoAcceptRequestToJoinLeave = siteGroup.AutoAcceptRequestToJoinLeave; if (parsedGroupTitle != parsedGroupOwner) { Principal ownerPrincipal = allGroups.FirstOrDefault(gr => gr.LoginName == parsedGroupOwner); if (ownerPrincipal == null) { ownerPrincipal = web.EnsureUser(parsedGroupOwner); } group.Owner = ownerPrincipal; } group.Update(); web.Context.Load(group, g => g.Id, g => g.Title); web.Context.ExecuteQueryRetry(); parser.AddToken(new GroupIdToken(web, group.Title, group.Id)); } else { group = web.SiteGroups.GetByName(parsedGroupTitle); web.Context.Load(group, g => g.Title, g => g.Description, g => g.AllowMembersEditMembership, g => g.AllowRequestToJoinLeave, g => g.AutoAcceptRequestToJoinLeave, g => g.Owner.LoginName); web.Context.ExecuteQueryRetry(); var isDirty = false; if (!String.IsNullOrEmpty(group.Description) && group.Description != parsedGroupDescription) { group.Description = parsedGroupDescription; isDirty = true; } if (group.AllowMembersEditMembership != siteGroup.AllowMembersEditMembership) { group.AllowMembersEditMembership = siteGroup.AllowMembersEditMembership; isDirty = true; } if (group.AllowRequestToJoinLeave != siteGroup.AllowRequestToJoinLeave) { group.AllowRequestToJoinLeave = siteGroup.AllowRequestToJoinLeave; isDirty = true; } if (group.AutoAcceptRequestToJoinLeave != siteGroup.AutoAcceptRequestToJoinLeave) { group.AutoAcceptRequestToJoinLeave = siteGroup.AutoAcceptRequestToJoinLeave; isDirty = true; } if (group.Owner.LoginName != parsedGroupOwner) { if (parsedGroupTitle != parsedGroupOwner) { Principal ownerPrincipal = allGroups.FirstOrDefault(gr => gr.LoginName == parsedGroupOwner); if (ownerPrincipal == null) { ownerPrincipal = web.EnsureUser(parsedGroupOwner); } group.Owner = ownerPrincipal; } else { group.Owner = group; } isDirty = true; } if (isDirty) { scope.LogDebug("Updating existing group {0}", group.Title); group.Update(); web.Context.ExecuteQueryRetry(); } } if (group != null && siteGroup.Members.Any()) { AddUserToGroup(web, group, siteGroup.Members, scope, parser); } } foreach (var admin in siteSecurity.AdditionalAdministrators) { var parsedAdminName = parser.ParseString(admin.Name); var user = web.EnsureUser(parsedAdminName); user.IsSiteAdmin = true; user.Update(); web.Context.ExecuteQueryRetry(); } if (!web.IsSubSite() && siteSecurity.SiteSecurityPermissions != null) // Only manage permissions levels on sitecol level { var existingRoleDefinitions = web.Context.LoadQuery(web.RoleDefinitions.Include(wr => wr.Name, wr => wr.BasePermissions, wr => wr.Description)); web.Context.ExecuteQueryRetry(); if (siteSecurity.SiteSecurityPermissions.RoleDefinitions.Any()) { foreach (var templateRoleDefinition in siteSecurity.SiteSecurityPermissions.RoleDefinitions) { var roleDefinitions = existingRoleDefinitions as RoleDefinition[] ?? existingRoleDefinitions.ToArray(); var siteRoleDefinition = roleDefinitions.FirstOrDefault(erd => erd.Name == parser.ParseString(templateRoleDefinition.Name)); if (siteRoleDefinition == null) { scope.LogDebug("Creation role definition {0}", parser.ParseString(templateRoleDefinition.Name)); var roleDefinitionCI = new RoleDefinitionCreationInformation(); roleDefinitionCI.Name = parser.ParseString(templateRoleDefinition.Name); roleDefinitionCI.Description = parser.ParseString(templateRoleDefinition.Description); BasePermissions basePermissions = new BasePermissions(); foreach (var permission in templateRoleDefinition.Permissions) { basePermissions.Set(permission); } roleDefinitionCI.BasePermissions = basePermissions; web.RoleDefinitions.Add(roleDefinitionCI); web.Context.ExecuteQueryRetry(); } else { var isDirty = false; if (siteRoleDefinition.Description != parser.ParseString(templateRoleDefinition.Description)) { siteRoleDefinition.Description = parser.ParseString(templateRoleDefinition.Description); isDirty = true; } var templateBasePermissions = new BasePermissions(); templateRoleDefinition.Permissions.ForEach(p => templateBasePermissions.Set(p)); if (siteRoleDefinition.BasePermissions != templateBasePermissions) { isDirty = true; foreach (var permission in templateRoleDefinition.Permissions) { siteRoleDefinition.BasePermissions.Set(permission); } } if (isDirty) { scope.LogDebug("Updating role definition {0}", parser.ParseString(templateRoleDefinition.Name)); siteRoleDefinition.Update(); web.Context.ExecuteQueryRetry(); } } } } var webRoleDefinitions = web.Context.LoadQuery(web.RoleDefinitions); var groups = web.Context.LoadQuery(web.SiteGroups.Include(g => g.LoginName)); web.Context.ExecuteQueryRetry(); if (siteSecurity.SiteSecurityPermissions.RoleAssignments.Any()) { foreach (var roleAssignment in siteSecurity.SiteSecurityPermissions.RoleAssignments) { Principal principal = groups.FirstOrDefault(g => g.LoginName == parser.ParseString(roleAssignment.Principal)); if (principal == null) { principal = web.EnsureUser(parser.ParseString(roleAssignment.Principal)); } var roleDefinitionBindingCollection = new RoleDefinitionBindingCollection(web.Context); var roleDefinition = webRoleDefinitions.FirstOrDefault(r => r.Name == parser.ParseString(roleAssignment.RoleDefinition)); if (roleDefinition != null) { roleDefinitionBindingCollection.Add(roleDefinition); } web.RoleAssignments.Add(principal, roleDefinitionBindingCollection); web.Context.ExecuteQueryRetry(); } } } } return(parser); }
public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { web.EnsureProperties(w => w.HasUniqueRoleAssignments, w => w.Title); // Changed by Paolo Pialorsi to embrace the new sub-site attributes for break role inheritance and copy role assignments // if this is a sub site then we're not creating security entities as by default security is inherited from the root site if (web.IsSubSite() && !web.HasUniqueRoleAssignments) { return(template); } var ownerGroup = web.AssociatedOwnerGroup; var memberGroup = web.AssociatedMemberGroup; var visitorGroup = web.AssociatedVisitorGroup; web.Context.ExecuteQueryRetry(); if (!ownerGroup.ServerObjectIsNull.Value) { web.Context.Load(ownerGroup, o => o.Id, o => o.Users, o => o.Title); } if (!memberGroup.ServerObjectIsNull.Value) { web.Context.Load(memberGroup, o => o.Id, o => o.Users, o => o.Title); } if (!visitorGroup.ServerObjectIsNull.Value) { web.Context.Load(visitorGroup, o => o.Id, o => o.Users, o => o.Title); } web.Context.ExecuteQueryRetry(); List <int> associatedGroupIds = new List <int>(); var owners = new List <User>(); var members = new List <User>(); var visitors = new List <User>(); if (!ownerGroup.ServerObjectIsNull.Value) { associatedGroupIds.Add(ownerGroup.Id); foreach (var member in ownerGroup.Users) { owners.Add(new User() { Name = member.LoginName }); } } if (!memberGroup.ServerObjectIsNull.Value) { associatedGroupIds.Add(memberGroup.Id); foreach (var member in memberGroup.Users) { members.Add(new User() { Name = member.LoginName }); } } if (!visitorGroup.ServerObjectIsNull.Value) { associatedGroupIds.Add(visitorGroup.Id); foreach (var member in visitorGroup.Users) { visitors.Add(new User() { Name = member.LoginName }); } } var siteSecurity = new SiteSecurity(); siteSecurity.AdditionalOwners.AddRange(owners); siteSecurity.AdditionalMembers.AddRange(members); siteSecurity.AdditionalVisitors.AddRange(visitors); var query = from user in web.SiteUsers where user.IsSiteAdmin select user; var allUsers = web.Context.LoadQuery(query); web.Context.ExecuteQueryRetry(); var admins = new List <User>(); foreach (var member in allUsers) { admins.Add(new User() { Name = member.LoginName }); } siteSecurity.AdditionalAdministrators.AddRange(admins); if (creationInfo.IncludeSiteGroups) { web.Context.Load(web.SiteGroups, o => o.IncludeWithDefaultProperties( gr => gr.Title, gr => gr.AllowMembersEditMembership, gr => gr.AutoAcceptRequestToJoinLeave, gr => gr.AllowRequestToJoinLeave, gr => gr.Description, gr => gr.Users.Include(u => u.LoginName), gr => gr.OnlyAllowMembersViewMembership, gr => gr.Owner.LoginName, gr => gr.RequestToJoinLeaveEmailSetting )); web.Context.ExecuteQueryRetry(); if (web.IsSubSite()) { WriteWarning("You are requesting to export sitegroups from a subweb. Notice that ALL sitegroups from the site collection are included in the result.", ProvisioningMessageType.Warning); } foreach (var group in web.SiteGroups.AsEnumerable().Where(o => !associatedGroupIds.Contains(o.Id))) { try { scope.LogDebug("Processing group {0}", group.Title); var siteGroup = new SiteGroup() { Title = !string.IsNullOrEmpty(web.Title) ? group.Title.Replace(web.Title, "{sitename}") : group.Title, AllowMembersEditMembership = group.AllowMembersEditMembership, AutoAcceptRequestToJoinLeave = group.AutoAcceptRequestToJoinLeave, AllowRequestToJoinLeave = group.AllowRequestToJoinLeave, Description = group.Description, OnlyAllowMembersViewMembership = group.OnlyAllowMembersViewMembership, Owner = ReplaceGroupTokens(web, group.Owner.LoginName), RequestToJoinLeaveEmailSetting = group.RequestToJoinLeaveEmailSetting }; foreach (var member in group.Users) { scope.LogDebug("Processing member {0} of group {0}", member.LoginName, group.Title); siteGroup.Members.Add(new User() { Name = member.LoginName }); } siteSecurity.SiteGroups.Add(siteGroup); } catch (Exception ee) { scope.LogError(ee.StackTrace); scope.LogError(ee.Message); scope.LogError(ee.InnerException.StackTrace); } } } var webRoleDefinitions = web.Context.LoadQuery(web.RoleDefinitions.Include(r => r.Name, r => r.Description, r => r.BasePermissions, r => r.RoleTypeKind)); web.Context.ExecuteQueryRetry(); if (web.HasUniqueRoleAssignments) { var permissionKeys = Enum.GetNames(typeof(PermissionKind)); if (!web.IsSubSite()) { foreach (var webRoleDefinition in webRoleDefinitions) { if (webRoleDefinition.RoleTypeKind == RoleType.None) { scope.LogDebug("Processing custom role definition {0}", webRoleDefinition.Name); var modelRoleDefinitions = new Model.RoleDefinition(); modelRoleDefinitions.Description = webRoleDefinition.Description; modelRoleDefinitions.Name = webRoleDefinition.Name; foreach (var permissionKey in permissionKeys) { scope.LogDebug("Processing custom permissionKey definition {0}", permissionKey); var permissionKind = (PermissionKind)Enum.Parse(typeof(PermissionKind), permissionKey); if (webRoleDefinition.BasePermissions.Has(permissionKind)) { modelRoleDefinitions.Permissions.Add(permissionKind); } } siteSecurity.SiteSecurityPermissions.RoleDefinitions.Add(modelRoleDefinitions); } else { scope.LogDebug("Skipping OOTB role definition {0}", webRoleDefinition.Name); } } } var webRoleAssignments = web.Context.LoadQuery(web.RoleAssignments.Include( r => r.RoleDefinitionBindings.Include( rd => rd.Name, rd => rd.RoleTypeKind), r => r.Member.LoginName, r => r.Member.PrincipalType)); web.Context.ExecuteQueryRetry(); foreach (var webRoleAssignment in webRoleAssignments) { scope.LogDebug("Processing Role Assignment {0}", webRoleAssignment.ToString()); if (webRoleAssignment.Member.PrincipalType == PrincipalType.SharePointGroup && !creationInfo.IncludeSiteGroups) { continue; } if (webRoleAssignment.Member.LoginName != "Excel Services Viewers") { foreach (var roleDefinition in webRoleAssignment.RoleDefinitionBindings) { if (roleDefinition.RoleTypeKind != RoleType.Guest) { var modelRoleAssignment = new Model.RoleAssignment(); var roleDefinitionValue = roleDefinition.Name; if (roleDefinition.RoleTypeKind != RoleType.None) { // Replace with token roleDefinitionValue = $"{{roledefinition:{roleDefinition.RoleTypeKind}}}"; } modelRoleAssignment.RoleDefinition = roleDefinitionValue; if (webRoleAssignment.Member.PrincipalType == PrincipalType.SharePointGroup) { modelRoleAssignment.Principal = ReplaceGroupTokens(web, webRoleAssignment.Member.LoginName); } else { modelRoleAssignment.Principal = webRoleAssignment.Member.LoginName; } siteSecurity.SiteSecurityPermissions.RoleAssignments.Add(modelRoleAssignment); } } } } } template.Security = siteSecurity; // If a base template is specified then use that one to "cleanup" the generated template model if (creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate); } } return(template); }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { if (template.Lists.Any()) { var rootWeb = (web.Context as ClientContext).Site.RootWeb; web.EnsureProperties(w => w.ServerRelativeUrl); web.Context.Load(web.Lists, lc => lc.IncludeWithDefaultProperties(l => l.RootFolder.ServerRelativeUrl)); web.Context.ExecuteQueryRetry(); var existingLists = web.Lists.AsEnumerable().Select(existingList => existingList.RootFolder.ServerRelativeUrl).ToList(); var serverRelativeUrl = web.ServerRelativeUrl; var processedLists = new List<ListInfo>(); #region Lists foreach (var templateList in template.Lists) { // Check for the presence of the references content types and throw an exception if not present or in template if (templateList.ContentTypesEnabled) { var existingCts = web.Context.LoadQuery(web.AvailableContentTypes); web.Context.ExecuteQueryRetry(); foreach (var ct in templateList.ContentTypeBindings) { var found = template.ContentTypes.Any(t => t.Id.ToUpperInvariant() == ct.ContentTypeId.ToUpperInvariant()); if (found == false) { found = existingCts.Any(t => t.StringId.ToUpperInvariant() == ct.ContentTypeId.ToUpperInvariant()); } if (!found) { scope.LogError("Referenced content type {0} not available in site or in template", ct.ContentTypeId); throw new Exception(string.Format("Referenced content type {0} not available in site or in template", ct.ContentTypeId)); } } } var index = existingLists.FindIndex(x => x.Equals(UrlUtility.Combine(serverRelativeUrl, templateList.Url), StringComparison.OrdinalIgnoreCase)); if (index == -1) { try { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Creating_list__0_, templateList.Title); var returnTuple = CreateList(web, templateList, parser, scope); var createdList = returnTuple.Item1; parser = returnTuple.Item2; processedLists.Add(new ListInfo { SiteList = createdList, TemplateList = templateList }); parser.AddToken(new ListIdToken(web, templateList.Title, createdList.Id)); parser.AddToken(new ListUrlToken(web, templateList.Title, createdList.RootFolder.ServerRelativeUrl.Substring(web.ServerRelativeUrl.Length + 1))); } catch (Exception ex) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Creating_list__0__failed___1_____2_, templateList.Title, ex.Message, ex.StackTrace); throw; } } else { try { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Updating_list__0_, templateList.Title); var existingList = web.Lists[index]; var returnTuple = UpdateList(web, existingList, templateList, parser, scope); var updatedList = returnTuple.Item1; parser = returnTuple.Item2; if (updatedList != null) { processedLists.Add(new ListInfo { SiteList = updatedList, TemplateList = templateList }); } } catch (Exception ex) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Updating_list__0__failed___1_____2_, templateList.Title, ex.Message, ex.StackTrace); throw; } } } #endregion #region FieldRefs foreach (var listInfo in processedLists) { if (listInfo.TemplateList.FieldRefs.Any()) { foreach (var fieldRef in listInfo.TemplateList.FieldRefs) { var field = rootWeb.GetFieldById<Field>(fieldRef.Id); if (field != null) { if (!listInfo.SiteList.FieldExistsById(fieldRef.Id)) { CreateFieldRef(listInfo, field, fieldRef); } else { UpdateFieldRef(listInfo.SiteList, field.Id, fieldRef); } } } listInfo.SiteList.Update(); web.Context.ExecuteQueryRetry(); } } #endregion #region Fields foreach (var listInfo in processedLists) { if (listInfo.TemplateList.Fields.Any()) { foreach (var field in listInfo.TemplateList.Fields) { var fieldElement = XElement.Parse(parser.ParseString(field.SchemaXml, "~sitecollection", "~site")); if (fieldElement.Attribute("ID") == null) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstances_Field_schema_has_no_ID_attribute___0_, field.SchemaXml); throw new Exception(string.Format(CoreResources.Provisioning_ObjectHandlers_ListInstances_Field_schema_has_no_ID_attribute___0_, field.SchemaXml)); } var id = fieldElement.Attribute("ID").Value; Guid fieldGuid; if (!Guid.TryParse(id, out fieldGuid)) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstances_ID_for_field_is_not_a_valid_Guid___0_, field.SchemaXml); throw new Exception(string.Format(CoreResources.Provisioning_ObjectHandlers_ListInstances_ID_for_field_is_not_a_valid_Guid___0_, id)); } else { var fieldFromList = listInfo.SiteList.GetFieldById<Field>(fieldGuid); if (fieldFromList == null) { try { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Creating_field__0_, fieldGuid); CreateField(fieldElement, listInfo, parser); } catch (Exception ex) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstances_Creating_field__0__failed___1_____2_, fieldGuid, ex.Message, ex.StackTrace); throw; } } else { try { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Updating_field__0_, fieldGuid); UpdateField(web, listInfo, fieldGuid, fieldElement, fieldFromList, scope, parser); } catch (Exception ex) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstances_Updating_field__0__failed___1_____2_, fieldGuid, ex.Message, ex.StackTrace); throw; } } } } } listInfo.SiteList.Update(); web.Context.ExecuteQueryRetry(); } #endregion #region Default Field Values foreach (var listInfo in processedLists) { if (listInfo.TemplateList.FieldDefaults.Any()) { foreach (var fieldDefault in listInfo.TemplateList.FieldDefaults) { var field = listInfo.SiteList.Fields.GetByInternalNameOrTitle(fieldDefault.Key); field.DefaultValue = fieldDefault.Value; field.Update(); web.Context.ExecuteQueryRetry(); } } } #endregion #region Views foreach (var listInfo in processedLists) { var list = listInfo.TemplateList; var createdList = listInfo.SiteList; if (list.Views.Any() && list.RemoveExistingViews) { while (createdList.Views.Any()) { createdList.Views[0].DeleteObject(); } web.Context.ExecuteQueryRetry(); } var existingViews = createdList.Views; web.Context.Load(existingViews, vs => vs.Include(v => v.Title, v => v.Id)); web.Context.ExecuteQueryRetry(); foreach (var view in list.Views) { CreateView(web, view, existingViews, createdList, scope); } //// Removing existing views set the OnQuickLaunch option to false and need to be re-set. //if (list.OnQuickLaunch && list.RemoveExistingViews && list.Views.Count > 0) //{ // createdList.RefreshLoad(); // web.Context.ExecuteQueryRetry(); // createdList.OnQuickLaunch = list.OnQuickLaunch; // createdList.Update(); // web.Context.ExecuteQueryRetry(); //} } #endregion // If an existing view is updated, and the list is to be listed on the QuickLaunch, it is removed because the existing view will be deleted and recreated from scratch. foreach (var listInfo in processedLists) { listInfo.SiteList.OnQuickLaunch = listInfo.TemplateList.OnQuickLaunch; listInfo.SiteList.Update(); } web.Context.ExecuteQueryRetry(); } } return parser; }
private ProvisioningTemplate DetectComposedLook(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo, PnPMonitoredScope scope, SharePointConnector spConnector, SharePointConnector spConnectorRoot) { var theme = web.GetCurrentComposedLook(); if (theme != null) { if (creationInfo != null) { // Don't exclude the DesignPreviewThemedCssFolderUrl property bag, if any creationInfo.PropertyBagPropertiesToPreserve.Add("DesignPreviewThemedCssFolderUrl"); } template.ComposedLook.Name = theme.Name != null ? theme.Name : String.Empty; if (theme.IsCustomComposedLook) { // Set the URL pointers to files template.ComposedLook.BackgroundFile = FixFileUrl(Tokenize(theme.BackgroundImage, web.Url)); template.ComposedLook.ColorFile = FixFileUrl(Tokenize(theme.Theme, web.Url)); template.ComposedLook.FontFile = FixFileUrl(Tokenize(theme.Font, web.Url)); // Download files if this is root site, since theme files are only stored there if (!web.IsSubSite() && creationInfo != null && creationInfo.PersistBrandingFiles && creationInfo.FileConnector != null) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Creating_SharePointConnector); // Let's create a SharePoint connector since our files anyhow are in SharePoint at this moment // Download the theme/branding specific files DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.BackgroundImage, scope); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.Theme, scope); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.Font, scope); } // Create file entries for the custom theme files, but only if it's a root site // If it's root site we do not extract or set theme files, since those are in the root of the site collection if (!web.IsSubSite()) { if (!string.IsNullOrEmpty(template.ComposedLook.BackgroundFile)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.BackgroundFile)); } if (!string.IsNullOrEmpty(template.ComposedLook.ColorFile)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.ColorFile)); } if (!string.IsNullOrEmpty(template.ComposedLook.FontFile)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.FontFile)); } } // If a base template is specified then use that one to "cleanup" the generated template model if (creationInfo != null && creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate); } } else { template.ComposedLook.BackgroundFile = ""; template.ComposedLook.ColorFile = ""; template.ComposedLook.FontFile = ""; } } else { template.ComposedLook = null; } return(template); }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { var context = web.Context as ClientContext; web.EnsureProperties(w => w.ServerRelativeUrl, w => w.Url); foreach (PublishingPage page in template.Publishing.PublishingPages) { string parsedFileName = parser.ParseString(page.FileName); string parsedFullFileName = parser.ParseString(page.FullFileName); Microsoft.SharePoint.Client.Publishing.PublishingPage existingPage = web.GetPublishingPage(parsedFileName + ".aspx"); if (!web.IsPropertyAvailable("RootFolder")) { web.Context.Load(web.RootFolder); web.Context.ExecuteQueryRetry(); } if (existingPage != null && existingPage.ServerObjectIsNull.Value == false) { if (!page.Overwrite) { scope.LogDebug( CoreResources.Provisioning_ObjectHandlers_PublishingPages_Skipping_As_Overwrite_false, parsedFileName); continue; } if (page.WelcomePage && web.RootFolder.WelcomePage.Contains(parsedFullFileName)) { //set the welcome page to a Temp page to allow page deletion web.RootFolder.WelcomePage = "home.aspx"; web.RootFolder.Update(); web.Update(); context.ExecuteQueryRetry(); } existingPage.ListItem.DeleteObject(); context.ExecuteQuery(); } web.AddPublishingPage( parsedFileName, page.Layout, parser.ParseString(page.Title) ); Microsoft.SharePoint.Client.Publishing.PublishingPage publishingPage = web.GetPublishingPage(parsedFullFileName); Microsoft.SharePoint.Client.File pageFile = publishingPage.ListItem.File; pageFile.CheckOut(); if (page.Properties != null && page.Properties.Count > 0) { context.Load(pageFile, p => p.Name, p => p.CheckOutType); context.ExecuteQueryRetry(); var parsedProperties = page.Properties.ToDictionary(p => p.Key, p => parser.ParseString(p.Value)); pageFile.SetFileProperties(parsedProperties, false); } if (page.WebParts != null && page.WebParts.Count > 0) { Microsoft.SharePoint.Client.WebParts.LimitedWebPartManager mgr = pageFile.GetLimitedWebPartManager( Microsoft.SharePoint.Client.WebParts.PersonalizationScope.Shared); context.Load(mgr); context.ExecuteQueryRetry(); AddWebPartsToPublishingPage(page, context, mgr, parser); } List pagesLibrary = publishingPage.ListItem.ParentList; context.Load(pagesLibrary); context.ExecuteQueryRetry(); ListItem pageItem = publishingPage.ListItem; web.Context.Load(pageItem, p => p.File.CheckOutType); web.Context.ExecuteQueryRetry(); if (pageItem.File.CheckOutType != CheckOutType.None) { pageItem.File.CheckIn(String.Empty, CheckinType.MajorCheckIn); } if (page.Publish && pagesLibrary.EnableMinorVersions) { pageItem.File.Publish(String.Empty); if (pagesLibrary.EnableModeration) { pageItem.File.Approve(String.Empty); } } if (page.WelcomePage) { SetWelcomePage(web, pageFile); } context.ExecuteQueryRetry(); } } return parser; }
public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { scope.LogInfo(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Retrieving_current_composed_look); // Ensure that we have URL property loaded for web and site web.EnsureProperty(w => w.Url); Site site = (web.Context as ClientContext).Site; site.EnsureProperty(s => s.Url); SharePointConnector spConnector = new SharePointConnector(web.Context, web.Url, "dummy"); // to get files from theme catalog we need a connector linked to the root site SharePointConnector spConnectorRoot; if (!site.Url.Equals(web.Url, StringComparison.InvariantCultureIgnoreCase)) { spConnectorRoot = new SharePointConnector(web.Context.Clone(site.Url), site.Url, "dummy"); } else { spConnectorRoot = spConnector; } // Check if we have composed look info in the property bag, if so, use that, otherwise try to detect the current composed look if (web.PropertyBagContainsKey("_PnP_ProvisioningTemplateComposedLookInfo")) { scope.LogInfo(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Using_ComposedLookInfoFromPropertyBag); try { var composedLook = JsonConvert.DeserializeObject <ComposedLook>(web.GetPropertyBagValueString("_PnP_ProvisioningTemplateComposedLookInfo", "")); if (composedLook.Name == null) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_ComposedLookInfoFailedToDeserialize); throw new JsonSerializationException(); } composedLook.BackgroundFile = Tokenize(composedLook.BackgroundFile, web.Url); composedLook.FontFile = Tokenize(composedLook.FontFile, web.Url); composedLook.ColorFile = Tokenize(composedLook.ColorFile, web.Url); template.ComposedLook = composedLook; if (!web.IsSubSite() && creationInfo != null && creationInfo.PersistBrandingFiles && creationInfo.FileConnector != null) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Creating_SharePointConnector); // Let's create a SharePoint connector since our files anyhow are in SharePoint at this moment TokenParser parser = new TokenParser(web, template); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, parser.ParseString(composedLook.BackgroundFile), scope); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, parser.ParseString(composedLook.ColorFile), scope); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, parser.ParseString(composedLook.FontFile), scope); } // Create file entries for the custom theme files if (!string.IsNullOrEmpty(template.ComposedLook.BackgroundFile)) { var f = GetComposedLookFile(template.ComposedLook.BackgroundFile); f.Folder = Tokenize(f.Folder, web.Url); template.Files.Add(f); } if (!string.IsNullOrEmpty(template.ComposedLook.ColorFile)) { var f = GetComposedLookFile(template.ComposedLook.ColorFile); f.Folder = Tokenize(f.Folder, web.Url); template.Files.Add(f); } if (!string.IsNullOrEmpty(template.ComposedLook.FontFile)) { var f = GetComposedLookFile(template.ComposedLook.FontFile); f.Folder = Tokenize(f.Folder, web.Url); template.Files.Add(f); } } catch (JsonSerializationException) { // cannot deserialize the object, fall back to composed look detection template = DetectComposedLook(web, template, creationInfo, scope, spConnector, spConnectorRoot); } } else { template = DetectComposedLook(web, template, creationInfo, scope, spConnector, spConnectorRoot); } if (creationInfo != null && creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate); } } return(template); }
public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { // if this is a sub site then we're not creating security entities as by default security is inherited from the root site if (web.IsSubSite()) { return template; } web.Context.Load(web, w => w.HasUniqueRoleAssignments, w => w.Title); var ownerGroup = web.AssociatedOwnerGroup; var memberGroup = web.AssociatedMemberGroup; var visitorGroup = web.AssociatedVisitorGroup; web.Context.ExecuteQueryRetry(); if (!ownerGroup.ServerObjectIsNull.Value) { web.Context.Load(ownerGroup, o => o.Id, o => o.Users, o => o.Title); } if (!memberGroup.ServerObjectIsNull.Value) { web.Context.Load(memberGroup, o => o.Id, o => o.Users, o => o.Title); } if (!visitorGroup.ServerObjectIsNull.Value) { web.Context.Load(visitorGroup, o => o.Id, o => o.Users, o => o.Title); } web.Context.ExecuteQueryRetry(); List<int> associatedGroupIds = new List<int>(); var owners = new List<User>(); var members = new List<User>(); var visitors = new List<User>(); if (!ownerGroup.ServerObjectIsNull.Value) { associatedGroupIds.Add(ownerGroup.Id); foreach (var member in ownerGroup.Users) { owners.Add(new User() { Name = member.LoginName }); } } if (!memberGroup.ServerObjectIsNull.Value) { associatedGroupIds.Add(memberGroup.Id); foreach (var member in memberGroup.Users) { members.Add(new User() { Name = member.LoginName }); } } if (!visitorGroup.ServerObjectIsNull.Value) { associatedGroupIds.Add(visitorGroup.Id); foreach (var member in visitorGroup.Users) { visitors.Add(new User() { Name = member.LoginName }); } } var siteSecurity = new SiteSecurity(); siteSecurity.AdditionalOwners.AddRange(owners); siteSecurity.AdditionalMembers.AddRange(members); siteSecurity.AdditionalVisitors.AddRange(visitors); var query = from user in web.SiteUsers where user.IsSiteAdmin select user; var allUsers = web.Context.LoadQuery(query); web.Context.ExecuteQueryRetry(); var admins = new List<User>(); foreach (var member in allUsers) { admins.Add(new User() { Name = member.LoginName }); } siteSecurity.AdditionalAdministrators.AddRange(admins); if (creationInfo.IncludeSiteGroups) { web.Context.Load(web.SiteGroups, o => o.IncludeWithDefaultProperties( gr => gr.Title, gr => gr.AllowMembersEditMembership, gr => gr.AutoAcceptRequestToJoinLeave, gr => gr.AllowRequestToJoinLeave, gr => gr.Description, gr => gr.Users.Include(u => u.LoginName), gr => gr.OnlyAllowMembersViewMembership, gr => gr.Owner.LoginName, gr => gr.RequestToJoinLeaveEmailSetting )); web.Context.ExecuteQueryRetry(); foreach (var group in web.SiteGroups.AsEnumerable().Where(o => !associatedGroupIds.Contains(o.Id))) { scope.LogDebug("Processing group {0}", group.Title); var siteGroup = new SiteGroup() { Title = group.Title.Replace(web.Title, "{sitename}"), AllowMembersEditMembership = group.AllowMembersEditMembership, AutoAcceptRequestToJoinLeave = group.AutoAcceptRequestToJoinLeave, AllowRequestToJoinLeave = group.AllowRequestToJoinLeave, Description = group.Description, OnlyAllowMembersViewMembership = group.OnlyAllowMembersViewMembership, Owner = ReplaceGroupTokens(web, group.Owner.LoginName), RequestToJoinLeaveEmailSetting = group.RequestToJoinLeaveEmailSetting }; foreach (var member in group.Users) { siteGroup.Members.Add(new User() { Name = member.LoginName }); } siteSecurity.SiteGroups.Add(siteGroup); } } var webRoleDefinitions = web.Context.LoadQuery(web.RoleDefinitions.Include(r => r.Name, r => r.Description, r => r.BasePermissions, r => r.RoleTypeKind)); web.Context.ExecuteQueryRetry(); if (web.HasUniqueRoleAssignments) { var permissionKeys = Enum.GetNames(typeof(PermissionKind)); foreach (var webRoleDefinition in webRoleDefinitions) { if (webRoleDefinition.RoleTypeKind == RoleType.None) { scope.LogDebug("Processing custom role definition {0}", webRoleDefinition.Name); var modelRoleDefinitions = new Model.RoleDefinition(); modelRoleDefinitions.Description = webRoleDefinition.Description; modelRoleDefinitions.Name = webRoleDefinition.Name; var permissions = new List<PermissionKind>(); foreach (var permissionKey in permissionKeys) { var permissionKind = (PermissionKind)Enum.Parse(typeof(PermissionKind), permissionKey); if (webRoleDefinition.BasePermissions.Has(permissionKind)) { modelRoleDefinitions.Permissions.Add(permissionKind); } } siteSecurity.SiteSecurityPermissions.RoleDefinitions.Add(modelRoleDefinitions); } else { scope.LogDebug("Skipping OOTB role definition {0}", webRoleDefinition.Name); } } var webRoleAssignments = web.Context.LoadQuery(web.RoleAssignments.Include( r => r.RoleDefinitionBindings.Include( rd => rd.Name, rd => rd.RoleTypeKind), r => r.Member.LoginName)); web.Context.ExecuteQueryRetry(); foreach (var webRoleAssignment in webRoleAssignments) { if (webRoleAssignment.Member.LoginName != "Excel Services Viewers") { foreach (var roleDefinition in webRoleAssignment.RoleDefinitionBindings) { if (roleDefinition.RoleTypeKind != RoleType.Guest) { var modelRoleAssignment = new Model.RoleAssignment(); modelRoleAssignment.RoleDefinition = roleDefinition.Name; modelRoleAssignment.Principal = ReplaceGroupTokens(web, webRoleAssignment.Member.LoginName); siteSecurity.SiteSecurityPermissions.RoleAssignments.Add(modelRoleAssignment); } } } } template.Security = siteSecurity; } // If a base template is specified then use that one to "cleanup" the generated template model if (creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate); } } return template; }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { if (!template.Lists.Any()) { return(parser); } web.EnsureProperties(w => w.ServerRelativeUrl); web.Context.Load(web.Lists, lc => lc.IncludeWithDefaultProperties(l => l.RootFolder.ServerRelativeUrl)); web.Context.ExecuteQueryRetry(); #region DataRows foreach (var listInstance in template.Lists) { if (listInstance.DataRows != null && listInstance.DataRows.Any()) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Processing_data_rows_for__0_, listInstance.Title); // Retrieve the target list var list = web.Lists.GetByTitle(parser.ParseString(listInstance.Title)); web.Context.Load(list); // Retrieve the fields' types from the list Microsoft.SharePoint.Client.FieldCollection fields = list.Fields; web.Context.Load(fields, fs => fs.Include(f => f.InternalName, f => f.FieldTypeKind, f => f.TypeAsString, f => f.ReadOnlyField, f => f.Title)); web.Context.ExecuteQueryRetry(); var keyColumnType = "Text"; var parsedKeyColumn = parser.ParseString(listInstance.DataRows.KeyColumn); if (!string.IsNullOrEmpty(parsedKeyColumn)) { var keyColumn = fields.FirstOrDefault(f => f.InternalName.Equals(parsedKeyColumn, StringComparison.InvariantCultureIgnoreCase)); if (keyColumn != null) { switch (keyColumn.FieldTypeKind) { case FieldType.User: case FieldType.Lookup: keyColumnType = "Lookup"; break; case FieldType.URL: keyColumnType = "Url"; break; case FieldType.DateTime: keyColumnType = "DateTime"; break; case FieldType.Number: case FieldType.Counter: keyColumnType = "Number"; break; } } } foreach (var dataRow in listInstance.DataRows) { try { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Creating_list_item__0_, listInstance.DataRows.IndexOf(dataRow) + 1); bool processItem = true; ListItem listitem = null; if (!string.IsNullOrEmpty(listInstance.DataRows.KeyColumn)) { // Get value from key column var dataRowValues = dataRow.Values.Where(v => v.Key == listInstance.DataRows.KeyColumn).ToList(); // if it is empty, skip the check if (dataRowValues.Any()) { var query = $@"<View><Query><Where><Eq><FieldRef Name=""{parsedKeyColumn}""/><Value Type=""{keyColumnType}"">{parser.ParseString(dataRowValues.FirstOrDefault().Value)}</Value></Eq></Where></Query><RowLimit>1</RowLimit></View>"; var camlQuery = new CamlQuery() { ViewXml = query }; var existingItems = list.GetItems(camlQuery); list.Context.Load(existingItems); list.Context.ExecuteQueryRetry(); if (existingItems.Count > 0) { if (listInstance.DataRows.UpdateBehavior == UpdateBehavior.Skip) { processItem = false; } else { listitem = existingItems[0]; processItem = true; } } } } if (processItem) { bool IsNewItem = false; if (listitem == null) { var listitemCI = new ListItemCreationInformation(); listitem = list.AddItem(listitemCI); IsNewItem = true; } ListItemUtilities.UpdateListItem(listitem, parser, dataRow.Values, ListItemUtilities.ListItemUpdateType.UpdateOverwriteVersion, IsNewItem); if (dataRow.Security != null && (dataRow.Security.ClearSubscopes || dataRow.Security.CopyRoleAssignments || dataRow.Security.RoleAssignments.Count > 0)) { listitem.SetSecurity(parser, dataRow.Security); } if (dataRow.Attachments != null && dataRow.Attachments.Count > 0) { foreach (var attachment in dataRow.Attachments) { attachment.Name = parser.ParseString(attachment.Name); attachment.Src = parser.ParseString(attachment.Src); if (!IsNewItem) { var overwrite = attachment.Overwrite; listitem.EnsureProperty(l => l.AttachmentFiles); Attachment existingItem = null; if (listitem.AttachmentFiles.Count > 0) { existingItem = listitem.AttachmentFiles.FirstOrDefault(a => a.FileName.Equals(attachment.Name, StringComparison.OrdinalIgnoreCase)); } if (existingItem != null) { if (overwrite) { existingItem.DeleteObject(); web.Context.ExecuteQueryRetry(); AddAttachment(template, listitem, attachment); } } else { AddAttachment(template, listitem, attachment); } } else { AddAttachment(template, listitem, attachment, IsNewItem); } } if (IsNewItem) { listitem.Context.ExecuteQueryRetry(); } } } } catch (ServerException ex) { if (ex.ServerErrorTypeName.Equals("Microsoft.SharePoint.SPDuplicateValuesFoundException", StringComparison.InvariantCultureIgnoreCase) && applyingInformation.IgnoreDuplicateDataRowErrors) { scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Creating_listitem_duplicate); continue; } if (ex.ServerErrorTypeName.Equals("Microsoft.SharePoint.SPException", StringComparison.InvariantCultureIgnoreCase) && ex.Message.Equals("To add an item to a document library, use SPFileCollection.Add()", StringComparison.InvariantCultureIgnoreCase)) { // somebody tries to add new items to a document library var warning = string.Format(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Creating_listitem_notsupported_0, listInstance.Title); scope.LogWarning(warning); WriteMessage(warning, ProvisioningMessageType.Warning); continue; } } catch (Exception ex) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Creating_listitem_failed___0_____1_, ex.Message, ex.StackTrace); throw; } } } } #endregion DataRows } return(parser); }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { var site = (web.Context as ClientContext).Site; var webFeatureActive = web.IsFeatureActive(PUBLISHING_FEATURE_WEB); var siteFeatureActive = site.IsFeatureActive(PUBLISHING_FEATURE_SITE); if (template.Publishing.AutoCheckRequirements == AutoCheckRequirementsOptions.SkipIfNotCompliant && !webFeatureActive) { scope.LogDebug("Publishing Feature (Web Scoped) not active. Skipping provisioning of Publishing settings"); return parser; } else if (template.Publishing.AutoCheckRequirements == AutoCheckRequirementsOptions.MakeCompliant) { if (!siteFeatureActive) { scope.LogDebug("Making site compliant for publishing"); site.ActivateFeature(PUBLISHING_FEATURE_SITE); web.ActivateFeature(PUBLISHING_FEATURE_WEB); } else { if (!web.IsFeatureActive(PUBLISHING_FEATURE_WEB)) { scope.LogDebug("Making site compliant for publishing"); web.ActivateFeature(PUBLISHING_FEATURE_WEB); } } } else { throw new Exception("Publishing Feature not active. Provisioning failed"); } // Set allowed web templates var availableWebTemplates = template.Publishing.AvailableWebTemplates.Select(t => new WebTemplateEntity() { LanguageCode = t.LanguageCode.ToString(), TemplateName = t.TemplateName }).ToList(); if (availableWebTemplates.Any()) { web.SetAvailableWebTemplates(availableWebTemplates); } // Set allowed page layouts var availablePageLayouts = template.Publishing.PageLayouts.Select(p => p.Path); if (availablePageLayouts.Any()) { web.SetAvailablePageLayouts(site.RootWeb, availablePageLayouts); } // Set default page layout, if any var defaultPageLayout = template.Publishing.PageLayouts.FirstOrDefault(p => p.IsDefault); if (defaultPageLayout != null) { web.SetDefaultPageLayoutForSite(site.RootWeb, defaultPageLayout.Path); } if (template.Publishing.DesignPackage != null) { var package = template.Publishing.DesignPackage; var tempFileName = Path.Combine(Path.GetTempPath(), template.Connector.GetFilenamePart(package.DesignPackagePath)); scope.LogDebug("Saving {0} to temporary file: {1}", package.DesignPackagePath, tempFileName); using (var stream = template.Connector.GetFileStream(package.DesignPackagePath)) { using (var outstream = System.IO.File.Create(tempFileName)) { stream.CopyTo(outstream); } } scope.LogDebug("Installing design package"); site.InstallSolution(package.PackageGuid, tempFileName, package.MajorVersion, package.MinorVersion); System.IO.File.Delete(tempFileName); } return parser; } }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { // Check if this is not a noscript site as we're not allowed to write to the web property bag is that one bool isNoScriptSite = web.IsNoScriptSite(); web.EnsureProperties(w => w.ServerRelativeUrl, w => w.Url); // Build on the fly the list of additional files coming from the Directories var directoryFiles = new List <Model.File>(); foreach (var directory in template.Directories) { var metadataProperties = directory.GetMetadataProperties(); directoryFiles.AddRange(directory.GetDirectoryFiles(metadataProperties)); } var filesToProcess = template.Files.Union(directoryFiles).ToArray(); var siteAssetsFiles = filesToProcess.Where(f => f.Folder.ToLower().Contains("siteassets")).FirstOrDefault(); if (siteAssetsFiles != null) { // Need this so that we dont have access denied error during the first time upload, especially for modern sites web.Lists.EnsureSiteAssetsLibrary(); web.Context.ExecuteQueryRetry(); } var currentFileIndex = 0; var originalWeb = web; // Used to store and re-store context in case files are deployed to masterpage gallery foreach (var file in filesToProcess) { file.Src = parser.ParseString(file.Src); var targetFileName = parser.ParseString( !String.IsNullOrEmpty(file.TargetFileName) ? file.TargetFileName : template.Connector.GetFilenamePart(file.Src) ); currentFileIndex++; WriteSubProgress("File", targetFileName, currentFileIndex, filesToProcess.Length); var folderName = parser.ParseString(file.Folder); if (folderName.ToLower().Contains("/_catalogs/")) { // Edge case where you have files in the template which should be provisioned to the site collection // master page gallery and not to a connected subsite web = web.Context.GetSiteCollectionContext().Web; web.EnsureProperties(w => w.ServerRelativeUrl, w => w.Url); } if (folderName.ToLower().StartsWith((web.ServerRelativeUrl.ToLower()))) { folderName = folderName.Substring(web.ServerRelativeUrl.Length); } if (SkipFile(isNoScriptSite, targetFileName, folderName)) { // add log message scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_Files_SkipFileUpload, targetFileName, folderName); continue; } var folder = web.EnsureFolderPath(folderName); var checkedOut = false; var targetFile = folder.GetFile(template.Connector.GetFilenamePart(targetFileName)); if (targetFile != null) { if (file.Overwrite) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Files_Uploading_and_overwriting_existing_file__0_, targetFileName); checkedOut = CheckOutIfNeeded(web, targetFile); using (var stream = FileUtilities.GetFileStream(template, file)) { targetFile = UploadFile(folder, stream, targetFileName, file.Overwrite); } } else { checkedOut = CheckOutIfNeeded(web, targetFile); } } else { using (var stream = FileUtilities.GetFileStream(template, file)) { if (stream == null) { throw new FileNotFoundException($"File {file.Src} does not exist"); } else { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Files_Uploading_file__0_, targetFileName); targetFile = UploadFile(folder, stream, targetFileName, file.Overwrite); } } checkedOut = CheckOutIfNeeded(web, targetFile); } if (targetFile != null) { // Add the fileuniqueid tokens targetFile.EnsureProperties(p => p.UniqueId, p => p.ServerRelativeUrl); parser.AddToken(new FileUniqueIdToken(web, targetFile.ServerRelativeUrl.Substring(web.ServerRelativeUrl.Length).TrimStart("/".ToCharArray()), targetFile.UniqueId)); parser.AddToken(new FileUniqueIdEncodedToken(web, targetFile.ServerRelativeUrl.Substring(web.ServerRelativeUrl.Length).TrimStart("/".ToCharArray()), targetFile.UniqueId)); bool webPartsNeedLocalization = false; if (file.WebParts != null && file.WebParts.Any()) { targetFile.EnsureProperties(f => f.ServerRelativeUrl); var existingWebParts = web.GetWebParts(targetFile.ServerRelativeUrl).ToList(); foreach (var webPart in file.WebParts) { // check if the webpart is already set on the page if (existingWebParts.FirstOrDefault(w => w.WebPart.Title == parser.ParseString(webPart.Title)) == null) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Files_Adding_webpart___0___to_page, webPart.Title); var wpEntity = new WebPartEntity { WebPartTitle = parser.ParseString(webPart.Title), WebPartXml = parser.ParseXmlString(webPart.Contents).Trim(new[] { '\n', ' ' }), WebPartZone = webPart.Zone, WebPartIndex = (int)webPart.Order }; var wpd = web.AddWebPartToWebPartPage(targetFile.ServerRelativeUrl, wpEntity); if (webPart.Title.ContainsResourceToken()) { // update data based on where it was added - needed in order to localize wp title wpd.EnsureProperties(w => w.ZoneId, w => w.WebPart, w => w.WebPart.Properties); webPart.Zone = wpd.ZoneId; webPart.Order = (uint)wpd.WebPart.ZoneIndex; webPartsNeedLocalization = true; } } } } if (webPartsNeedLocalization) { file.LocalizeWebParts(web, parser, targetFile, scope); } //Set Properties before Checkin if (file.Properties != null && file.Properties.Any()) { Dictionary <string, string> transformedProperties = file.Properties.ToDictionary(property => property.Key, property => parser.ParseString(property.Value)); SetFileProperties(targetFile, transformedProperties, parser, false); } switch (file.Level) { case Model.FileLevel.Published: { targetFile.PublishFileToLevel(Microsoft.SharePoint.Client.FileLevel.Published); break; } case Model.FileLevel.Draft: { targetFile.PublishFileToLevel(Microsoft.SharePoint.Client.FileLevel.Draft); break; } default: { if (checkedOut) { targetFile.CheckIn("", CheckinType.MajorCheckIn); web.Context.ExecuteQueryRetry(); } break; } } // Don't set security when nothing is defined. This otherwise breaks on files set outside of a list if (file.Security != null && (file.Security.ClearSubscopes == true || file.Security.CopyRoleAssignments == true || file.Security.RoleAssignments.Count > 0)) { targetFile.ListItemAllFields.SetSecurity(parser, file.Security, WriteMessage); } } web = originalWeb; // restore context in case files are provisioned to the master page gallery #1059 } } WriteMessage("Done processing files", ProvisioningMessageType.Completed); return(parser); }
public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { // if this is a sub site then we're not creating field entities. if (web.IsSubSite()) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Fields_Context_web_is_subweb__skipping_site_columns); return template; } var existingFields = web.Fields; web.Context.Load(web, w => w.ServerRelativeUrl); web.Context.Load(existingFields, fs => fs.Include(f => f.Id, f => f.SchemaXml, f => f.TypeAsString)); web.Context.ExecuteQueryRetry(); var taxTextFieldsToRemove = new List<Guid>(); foreach (var field in existingFields) { if (!BuiltInFieldId.Contains(field.Id)) { var fieldXml = field.SchemaXml; XElement element = XElement.Parse(fieldXml); // Check if the field contains a reference to a list. If by Guid, rewrite the value of the attribute to use web relative paths var listIdentifier = element.Attribute("List") != null ? element.Attribute("List").Value : null; if (!string.IsNullOrEmpty(listIdentifier)) { var listGuid = Guid.Empty; if (Guid.TryParse(listIdentifier, out listGuid)) { var list = web.Lists.GetById(listGuid); web.Context.Load(list, l => l.RootFolder.ServerRelativeUrl); web.Context.ExecuteQueryRetry(); var listUrl = list.RootFolder.ServerRelativeUrl.Substring(web.ServerRelativeUrl.Length).TrimStart('/'); element.Attribute("List").SetValue(listUrl); fieldXml = element.ToString(); } } // Check if the field is of type TaxonomyField if (field.TypeAsString.StartsWith("TaxonomyField")) { var taxField = (TaxonomyField)field; web.Context.Load(taxField, tf => tf.TextField, tf => tf.Id); web.Context.ExecuteQueryRetry(); taxTextFieldsToRemove.Add(taxField.TextField); } // Check if we have version attribute. Remove if exists if (element.Attribute("Version") != null) { element.Attributes("Version").Remove(); fieldXml = element.ToString(); } template.SiteFields.Add(new Field() { SchemaXml = fieldXml }); } } // Remove hidden taxonomy text fields foreach (var textFieldId in taxTextFieldsToRemove) { template.SiteFields.RemoveAll(f => Guid.Parse(f.SchemaXml.ElementAttributeValue("ID")).Equals(textFieldId)); } // If a base template is specified then use that one to "cleanup" the generated template model if (creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate); } } return template; }
public void Provision(ClientContext ctx, ProvisioningTemplate template, ProvisioningTemplateApplyingInformation applyingInformation, TokenParser tokenParser, PnPMonitoredScope scope, string configurationData) { Log.Info( this.logSource, "ProcessRequest. Template: {0}. Config: {1}", template.Id, configurationData); Web web; TokenParser parser = tokenParser; var usingRootWeb = false; if (ctx.Web.IsSubSite()) { // This extension only works on sub webs with unique permissions! ctx.Web.Context.Load(ctx.Web, o => o.HasUniqueRoleAssignments); ctx.Web.Context.ExecuteQueryRetry(); if (!ctx.Web.HasUniqueRoleAssignments) { scope.LogDebug("Sub web does not have unique permissions, skipping Security provisioning on it!"); return; } else { web = ctx.GetSiteCollectionContext().Site.RootWeb; usingRootWeb = true; } } else { // Business as usual web = ctx.Web; } var siteSecurity = template.Security; var ownerGroup = web.AssociatedOwnerGroup; var memberGroup = web.AssociatedMemberGroup; var visitorGroup = web.AssociatedVisitorGroup; web.Context.Load(ownerGroup, o => o.Title, o => o.Users); web.Context.Load(memberGroup, o => o.Title, o => o.Users); web.Context.Load(visitorGroup, o => o.Title, o => o.Users); web.Context.ExecuteQueryRetry(); if (!ownerGroup.ServerObjectIsNull.Value) { AddUserToGroup(web, ownerGroup, siteSecurity.AdditionalOwners, scope); } if (!memberGroup.ServerObjectIsNull.Value) { AddUserToGroup(web, memberGroup, siteSecurity.AdditionalMembers, scope); } if (!visitorGroup.ServerObjectIsNull.Value) { AddUserToGroup(web, visitorGroup, siteSecurity.AdditionalVisitors, scope); } foreach (var siteGroup in siteSecurity.SiteGroups) { Group group = null; var allGroups = web.Context.LoadQuery(web.SiteGroups.Include(gr => gr.LoginName)); web.Context.ExecuteQueryRetry(); string parsedGroupTitle = parser.ParseString(siteGroup.Title); string parsedGroupOwner = parser.ParseString(siteGroup.Owner); string parsedGroupDescription = parser.ParseString(siteGroup.Description); if (!web.GroupExists(parsedGroupTitle)) { scope.LogDebug("Creating group {0}", parsedGroupTitle); group = web.AddGroup( parsedGroupTitle, parsedGroupDescription, parsedGroupTitle == parsedGroupOwner); group.AllowMembersEditMembership = siteGroup.AllowMembersEditMembership; group.AllowRequestToJoinLeave = siteGroup.AllowRequestToJoinLeave; group.AutoAcceptRequestToJoinLeave = siteGroup.AutoAcceptRequestToJoinLeave; if (parsedGroupTitle != parsedGroupOwner) { Principal ownerPrincipal = allGroups.FirstOrDefault(gr => gr.LoginName == parsedGroupOwner); if (ownerPrincipal == null) { ownerPrincipal = web.EnsureUser(parsedGroupOwner); } group.Owner = ownerPrincipal; } group.Update(); web.Context.ExecuteQueryRetry(); } else { group = web.SiteGroups.GetByName(parsedGroupTitle); web.Context.Load(group, g => g.Title, g => g.Description, g => g.AllowMembersEditMembership, g => g.AllowRequestToJoinLeave, g => g.AutoAcceptRequestToJoinLeave, g => g.Owner.LoginName); web.Context.ExecuteQueryRetry(); var isDirty = false; if (!String.IsNullOrEmpty(group.Description) && group.Description != parsedGroupDescription) { group.Description = parsedGroupDescription; isDirty = true; } if (group.AllowMembersEditMembership != siteGroup.AllowMembersEditMembership) { group.AllowMembersEditMembership = siteGroup.AllowMembersEditMembership; isDirty = true; } if (group.AllowRequestToJoinLeave != siteGroup.AllowRequestToJoinLeave) { group.AllowRequestToJoinLeave = siteGroup.AllowRequestToJoinLeave; isDirty = true; } if (group.AutoAcceptRequestToJoinLeave != siteGroup.AutoAcceptRequestToJoinLeave) { group.AutoAcceptRequestToJoinLeave = siteGroup.AutoAcceptRequestToJoinLeave; isDirty = true; } if (group.Owner.LoginName != parsedGroupOwner) { if (parsedGroupTitle != parsedGroupOwner) { Principal ownerPrincipal = allGroups.FirstOrDefault(gr => gr.LoginName == parsedGroupOwner); if (ownerPrincipal == null) { ownerPrincipal = web.EnsureUser(parsedGroupOwner); } group.Owner = ownerPrincipal; } else { group.Owner = group; } isDirty = true; } if (isDirty) { scope.LogDebug("Updating existing group {0}", group.Title); group.Update(); web.Context.ExecuteQueryRetry(); } } if (group != null && siteGroup.Members.Any()) { AddUserToGroup(web, group, siteGroup.Members, scope); } } foreach (var admin in siteSecurity.AdditionalAdministrators) { var user = web.EnsureUser(admin.Name); user.IsSiteAdmin = true; user.Update(); web.Context.ExecuteQueryRetry(); } if (siteSecurity.SiteSecurityPermissions != null) { var existingRoleDefinitions = web.Context.LoadQuery(web.RoleDefinitions.Include(wr => wr.Name, wr => wr.BasePermissions, wr => wr.Description)); web.Context.ExecuteQueryRetry(); if (siteSecurity.SiteSecurityPermissions.RoleDefinitions.Any()) { foreach (var templateRoleDefinition in siteSecurity.SiteSecurityPermissions.RoleDefinitions) { var siteRoleDefinition = existingRoleDefinitions.FirstOrDefault(erd => erd.Name == parser.ParseString(templateRoleDefinition.Name)); if (siteRoleDefinition == null) { scope.LogDebug("Creation role definition {0}", parser.ParseString(templateRoleDefinition.Name)); var roleDefinitionCI = new RoleDefinitionCreationInformation(); roleDefinitionCI.Name = parser.ParseString(templateRoleDefinition.Name); roleDefinitionCI.Description = parser.ParseString(templateRoleDefinition.Description); BasePermissions basePermissions = new BasePermissions(); foreach (var permission in templateRoleDefinition.Permissions) { basePermissions.Set(permission); } roleDefinitionCI.BasePermissions = basePermissions; web.RoleDefinitions.Add(roleDefinitionCI); web.Context.ExecuteQueryRetry(); } else { var isDirty = false; if (siteRoleDefinition.Description != parser.ParseString(templateRoleDefinition.Description)) { siteRoleDefinition.Description = parser.ParseString(templateRoleDefinition.Description); isDirty = true; } var templateBasePermissions = new BasePermissions(); templateRoleDefinition.Permissions.ForEach(p => templateBasePermissions.Set(p)); if (siteRoleDefinition.BasePermissions != templateBasePermissions) { isDirty = true; foreach (var permission in templateRoleDefinition.Permissions) { siteRoleDefinition.BasePermissions.Set(permission); } } if (isDirty) { scope.LogDebug("Updating role definition {0}", parser.ParseString(templateRoleDefinition.Name)); siteRoleDefinition.Update(); web.Context.ExecuteQueryRetry(); } } } } if (usingRootWeb) { web = ctx.Web; } var webRoleDefinitions = web.Context.LoadQuery(web.RoleDefinitions); var groups = web.Context.LoadQuery(web.SiteGroups.Include(g => g.LoginName)); web.Context.ExecuteQueryRetry(); if (siteSecurity.SiteSecurityPermissions.RoleAssignments.Any()) { foreach (var roleAssignment in siteSecurity.SiteSecurityPermissions.RoleAssignments) { Principal principal = groups.FirstOrDefault(g => g.LoginName == parser.ParseString(roleAssignment.Principal)); if (principal == null) { principal = web.EnsureUser(parser.ParseString(roleAssignment.Principal)); } var roleDefinitionBindingCollection = new RoleDefinitionBindingCollection(web.Context); var roleDefinition = webRoleDefinitions.FirstOrDefault(r => r.Name == parser.ParseString(roleAssignment.RoleDefinition)); if (roleDefinition != null) { roleDefinitionBindingCollection.Add(roleDefinition); } web.RoleAssignments.Add(principal, roleDefinitionBindingCollection); web.Context.ExecuteQueryRetry(); } } } }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(CoreResources.Provisioning_ObjectHandlers_Pages)) { var context = web.Context as ClientContext; if (!web.IsPropertyAvailable("ServerRelativeUrl")) { context.Load(web, w => w.ServerRelativeUrl); context.ExecuteQueryRetry(); } foreach (var page in template.Pages) { var url = parser.ParseString(page.Url); if (!url.ToLower().StartsWith(web.ServerRelativeUrl.ToLower())) { url = UrlUtility.Combine(web.ServerRelativeUrl, url); } var exists = true; Microsoft.SharePoint.Client.File file = null; try { file = web.GetFileByServerRelativeUrl(url); web.Context.Load(file); web.Context.ExecuteQuery(); } catch (ServerException ex) { if (ex.ServerErrorTypeName == "System.IO.FileNotFoundException") { exists = false; } } if (exists) { if (page.Overwrite) { try { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Pages_Overwriting_existing_page__0_, url); file.DeleteObject(); web.Context.ExecuteQueryRetry(); web.AddWikiPageByUrl(url); web.AddLayoutToWikiPage(page.Layout, url); } catch (Exception ex) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_Pages_Overwriting_existing_page__0__failed___1_____2_,url,ex.Message,ex.StackTrace); } } } else { try { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Pages_Creating_new_page__0_, url); web.AddWikiPageByUrl(url); web.AddLayoutToWikiPage(page.Layout, url); } catch (Exception ex) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_Pages_Creating_new_page__0__failed___1_____2_,url, ex.Message,ex.StackTrace); } } if (page.WelcomePage) { if (!web.IsPropertyAvailable("RootFolder")) { web.Context.Load(web.RootFolder); web.Context.ExecuteQueryRetry(); } var rootFolderRelativeUrl = url.Substring(web.RootFolder.ServerRelativeUrl.Length); web.SetHomePage(rootFolderRelativeUrl); } if (page.WebParts != null & page.WebParts.Any()) { var existingWebParts = web.GetWebParts(url); foreach (var webpart in page.WebParts) { if (existingWebParts.FirstOrDefault(w => w.WebPart.Title == webpart.Title) == null) { WebPartEntity wpEntity = new WebPartEntity(); wpEntity.WebPartTitle = webpart.Title; wpEntity.WebPartXml = parser.ParseString(webpart.Contents).Trim(new[] {'\n', ' '}); web.AddWebPartToWikiPage(url, wpEntity, (int) webpart.Row, (int) webpart.Column, false); } } } } } return parser; }
/// <summary> /// Actual implementation of extracting configuration from existing site. /// </summary> /// <param name="web"></param> /// <param name="creationInfo"></param> /// <returns></returns> internal ProvisioningTemplate GetRemoteTemplate(Web web, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(CoreResources.Provisioning_ObjectHandlers_Extraction)) { ProvisioningProgressDelegate progressDelegate = null; ProvisioningMessagesDelegate messagesDelegate = null; if (creationInfo != null) { if (creationInfo.BaseTemplate != null) { scope.LogDebug(CoreResources.SiteToTemplateConversion_Base_template_available___0_, creationInfo.BaseTemplate.Id); } progressDelegate = creationInfo.ProgressDelegate; if (creationInfo.ProgressDelegate != null) { scope.LogDebug(CoreResources.SiteToTemplateConversion_ProgressDelegate_registered); } messagesDelegate = creationInfo.MessagesDelegate; if (creationInfo.MessagesDelegate != null) { scope.LogDebug(CoreResources.SiteToTemplateConversion_MessagesDelegate_registered); } if (creationInfo.IncludeAllTermGroups) { scope.LogDebug(CoreResources.SiteToTemplateConversion_IncludeAllTermGroups_is_set_to_true); } if (creationInfo.IncludeSiteCollectionTermGroup) { scope.LogDebug(CoreResources.SiteToTemplateConversion_IncludeSiteCollectionTermGroup_is_set_to_true); } if (creationInfo.PersistBrandingFiles) { scope.LogDebug(CoreResources.SiteToTemplateConversion_PersistBrandingFiles_is_set_to_true); } } else { // When no provisioning info was passed then we want to execute all handlers creationInfo = new ProvisioningTemplateCreationInformation(web); creationInfo.HandlersToProcess = Handlers.All; } // Create empty object ProvisioningTemplate template = new ProvisioningTemplate(); // Hookup connector, is handy when the generated template object is used to apply to another site template.Connector = creationInfo.FileConnector; List <ObjectHandlerBase> objectHandlers = new List <ObjectHandlerBase>(); if (creationInfo.HandlersToProcess.HasFlag(Handlers.RegionalSettings)) { objectHandlers.Add(new ObjectRegionalSettings()); } if (creationInfo.HandlersToProcess.HasFlag(Handlers.SupportedUILanguages)) { objectHandlers.Add(new ObjectSupportedUILanguages()); } if (creationInfo.HandlersToProcess.HasFlag(Handlers.AuditSettings)) { objectHandlers.Add(new ObjectAuditSettings()); } if (creationInfo.HandlersToProcess.HasFlag(Handlers.SitePolicy)) { objectHandlers.Add(new ObjectSitePolicy()); } if (creationInfo.HandlersToProcess.HasFlag(Handlers.SiteSecurity)) { objectHandlers.Add(new ObjectSiteSecurity()); } if (creationInfo.HandlersToProcess.HasFlag(Handlers.TermGroups)) { objectHandlers.Add(new ObjectTermGroups()); } if (creationInfo.HandlersToProcess.HasFlag(Handlers.Fields)) { objectHandlers.Add(new ObjectField()); } if (creationInfo.HandlersToProcess.HasFlag(Handlers.ContentTypes)) { objectHandlers.Add(new ObjectContentType()); } if (creationInfo.HandlersToProcess.HasFlag(Handlers.Lists)) { objectHandlers.Add(new ObjectListInstance()); } if (creationInfo.HandlersToProcess.HasFlag(Handlers.CustomActions)) { objectHandlers.Add(new ObjectCustomActions()); } if (creationInfo.HandlersToProcess.HasFlag(Handlers.Features)) { objectHandlers.Add(new ObjectFeatures()); } if (creationInfo.HandlersToProcess.HasFlag(Handlers.ComposedLook)) { objectHandlers.Add(new ObjectComposedLook()); } if (creationInfo.HandlersToProcess.HasFlag(Handlers.SearchSettings)) { objectHandlers.Add(new ObjectSearchSettings()); } if (creationInfo.HandlersToProcess.HasFlag(Handlers.Publishing)) { objectHandlers.Add(new ObjectPublishing()); } if (creationInfo.HandlersToProcess.HasFlag(Handlers.Files)) { objectHandlers.Add(new ObjectFiles()); } if (creationInfo.HandlersToProcess.HasFlag(Handlers.Pages)) { objectHandlers.Add(new ObjectPages()); } if (creationInfo.HandlersToProcess.HasFlag(Handlers.PageContents)) { objectHandlers.Add(new ObjectPageContents()); } if (creationInfo.HandlersToProcess.HasFlag(Handlers.PropertyBagEntries)) { objectHandlers.Add(new ObjectPropertyBagEntry()); } if (creationInfo.HandlersToProcess.HasFlag(Handlers.Workflows)) { objectHandlers.Add(new ObjectWorkflows()); } if (creationInfo.HandlersToProcess.HasFlag(Handlers.WebSettings)) { objectHandlers.Add(new ObjectWebSettings()); } if (creationInfo.HandlersToProcess.HasFlag(Handlers.Navigation)) { objectHandlers.Add(new ObjectNavigation()); } objectHandlers.Add(new ObjectLocalization()); // Always add this one, check is done in the handler if (creationInfo.HandlersToProcess.HasFlag(Handlers.ExtensibilityProviders)) { objectHandlers.Add(new ObjectExtensibilityHandlers()); } objectHandlers.Add(new ObjectRetrieveTemplateInfo()); int step = 1; var count = objectHandlers.Count(o => o.ReportProgress && o.WillExtract(web, template, creationInfo)); web.EnsureProperty(w => w.Url); foreach (var handler in objectHandlers) { if (handler.WillExtract(web, template, creationInfo)) { if (messagesDelegate != null) { handler.MessagesDelegate = messagesDelegate; } if (handler.ReportProgress && progressDelegate != null) { progressDelegate(handler.Name, step, count); step++; } using (var handlerContext = web.Context.Clone(web.Url)) { template = handler.ExtractObjects(handlerContext.Web, template, creationInfo); } } } //if (creationInfo.PersistMultiLanguageResources) //{ // template = UserResourceExtensions.SaveResourceValues(template, creationInfo); //} return(template); } }
private void CreateView(Web web, View view, Microsoft.SharePoint.Client.ViewCollection existingViews, List createdList, PnPMonitoredScope monitoredScope) { try { var viewElement = XElement.Parse(view.SchemaXml); var displayNameElement = viewElement.Attribute("DisplayName"); if (displayNameElement == null) { throw new ApplicationException("Invalid View element, missing a valid value for the attribute DisplayName."); } monitoredScope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Creating_view__0_, displayNameElement.Value); var existingView = existingViews.FirstOrDefault(v => v.Title == displayNameElement.Value); if (existingView != null) { existingView.DeleteObject(); web.Context.ExecuteQueryRetry(); } var viewTitle = displayNameElement.Value; // Type var viewTypeString = viewElement.Attribute("Type") != null ? viewElement.Attribute("Type").Value : "None"; viewTypeString = viewTypeString[0].ToString().ToUpper() + viewTypeString.Substring(1).ToLower(); var viewType = (ViewType)Enum.Parse(typeof(ViewType), viewTypeString); // Fields string[] viewFields = null; var viewFieldsElement = viewElement.Descendants("ViewFields").FirstOrDefault(); if (viewFieldsElement != null) { viewFields = (from field in viewElement.Descendants("ViewFields").Descendants("FieldRef") select field.Attribute("Name").Value).ToArray(); } // Default view var viewDefault = viewElement.Attribute("DefaultView") != null && Boolean.Parse(viewElement.Attribute("DefaultView").Value); // Row limit var viewPaged = true; uint viewRowLimit = 30; var rowLimitElement = viewElement.Descendants("RowLimit").FirstOrDefault(); if (rowLimitElement != null) { if (rowLimitElement.Attribute("Paged") != null) { viewPaged = bool.Parse(rowLimitElement.Attribute("Paged").Value); } viewRowLimit = uint.Parse(rowLimitElement.Value); } // Query var viewQuery = new StringBuilder(); foreach (var queryElement in viewElement.Descendants("Query").Elements()) { viewQuery.Append(queryElement.ToString()); } var viewCI = new ViewCreationInformation { ViewFields = viewFields, RowLimit = viewRowLimit, Paged = viewPaged, Title = viewTitle, Query = viewQuery.ToString(), ViewTypeKind = viewType, PersonalView = false, SetAsDefaultView = viewDefault, }; // Allow to specify a custom view url. View url is taken from title, so we first set title to the view url value we need, // create the view and then set title back to the original value var urlAttribute = viewElement.Attribute("Url"); var urlHasValue = urlAttribute != null && !string.IsNullOrEmpty(urlAttribute.Value); if (urlHasValue) { //set Title to be equal to url (in order to generate desired url) viewCI.Title = Path.GetFileNameWithoutExtension(urlAttribute.Value); } var createdView = createdList.Views.Add(viewCI); web.Context.Load(createdView, v => v.Scope, v => v.JSLink, v => v.Title); web.Context.ExecuteQueryRetry(); if (urlHasValue) { //restore original title createdView.Title = viewTitle; createdView.Update(); } // ContentTypeID var contentTypeID = viewElement.Attribute("ContentTypeID") != null ? viewElement.Attribute("ContentTypeID").Value : null; if (!string.IsNullOrEmpty(contentTypeID) && (contentTypeID != BuiltInContentTypeId.System)) { ContentTypeId childContentTypeId = null; if (contentTypeID == BuiltInContentTypeId.RootOfList) { var childContentType = web.GetContentTypeById(contentTypeID); childContentTypeId = childContentType != null ? childContentType.Id : null; } else { childContentTypeId = createdList.ContentTypes.BestMatch(contentTypeID); } if (childContentTypeId != null) { createdView.ContentTypeId = childContentTypeId; createdView.Update(); } } // Default for content type bool parsedDefaultViewForContentType; var defaultViewForContentType = viewElement.Attribute("DefaultViewForContentType") != null ? viewElement.Attribute("DefaultViewForContentType").Value : null; if (!string.IsNullOrEmpty(defaultViewForContentType) && bool.TryParse(defaultViewForContentType, out parsedDefaultViewForContentType)) { createdView.DefaultViewForContentType = parsedDefaultViewForContentType; createdView.Update(); } // Scope var scope = viewElement.Attribute("Scope") != null ? viewElement.Attribute("Scope").Value : null; ViewScope parsedScope = ViewScope.DefaultValue; if (!string.IsNullOrEmpty(scope) && Enum.TryParse<ViewScope>(scope, out parsedScope)) { createdView.Scope = parsedScope; createdView.Update(); } // JSLink var jslinkElement = viewElement.Descendants("JSLink").FirstOrDefault(); if (jslinkElement != null) { var jslink = jslinkElement.Value; if (createdView.JSLink != jslink) { createdView.JSLink = jslink; createdView.Update(); } } createdList.Update(); web.Context.ExecuteQueryRetry(); } catch (Exception ex) { monitoredScope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstances_Creating_view_failed___0_____1_, ex.Message, ex.StackTrace); throw; } }
private static void UpdateContentType(Web web, Microsoft.SharePoint.Client.ContentType existingContentType, ContentType templateContentType, TokenParser parser, PnPMonitoredScope scope, bool isNoScriptSite = false) { var isDirty = false; if (existingContentType.Hidden != templateContentType.Hidden) { scope.LogPropertyUpdate("Hidden"); existingContentType.Hidden = templateContentType.Hidden; isDirty = true; } if (existingContentType.ReadOnly != templateContentType.ReadOnly) { scope.LogPropertyUpdate("ReadOnly"); existingContentType.ReadOnly = templateContentType.ReadOnly; isDirty = true; } if (existingContentType.Sealed != templateContentType.Sealed) { scope.LogPropertyUpdate("Sealed"); existingContentType.Sealed = templateContentType.Sealed; isDirty = true; } if (templateContentType.Description != null && existingContentType.Description != parser.ParseString(templateContentType.Description)) { scope.LogPropertyUpdate("Description"); existingContentType.Description = parser.ParseString(templateContentType.Description); isDirty = true; } if (templateContentType.DocumentTemplate != null && existingContentType.DocumentTemplate != parser.ParseString(templateContentType.DocumentTemplate)) { scope.LogPropertyUpdate("DocumentTemplate"); existingContentType.DocumentTemplate = parser.ParseString(templateContentType.DocumentTemplate); isDirty = true; } if (existingContentType.Name != parser.ParseString(templateContentType.Name)) { scope.LogPropertyUpdate("Name"); existingContentType.Name = parser.ParseString(templateContentType.Name); isDirty = true; // CT is being renamed, add an extra token to the tokenparser parser.AddToken(new ContentTypeIdToken(web, existingContentType.Name, existingContentType.StringId)); } if (templateContentType.Group != null && existingContentType.Group != parser.ParseString(templateContentType.Group)) { scope.LogPropertyUpdate("Group"); existingContentType.Group = parser.ParseString(templateContentType.Group); isDirty = true; } if (!isNoScriptSite) { if (templateContentType.DisplayFormUrl != null && existingContentType.DisplayFormUrl != parser.ParseString(templateContentType.DisplayFormUrl)) { scope.LogPropertyUpdate("DisplayFormUrl"); existingContentType.DisplayFormUrl = parser.ParseString(templateContentType.DisplayFormUrl); isDirty = true; } if (templateContentType.EditFormUrl != null && existingContentType.EditFormUrl != parser.ParseString(templateContentType.EditFormUrl)) { scope.LogPropertyUpdate("EditFormUrl"); existingContentType.EditFormUrl = parser.ParseString(templateContentType.EditFormUrl); isDirty = true; } if (templateContentType.NewFormUrl != null && existingContentType.NewFormUrl != parser.ParseString(templateContentType.NewFormUrl)) { scope.LogPropertyUpdate("NewFormUrl"); existingContentType.NewFormUrl = parser.ParseString(templateContentType.NewFormUrl); isDirty = true; } } else { if (!String.IsNullOrEmpty(parser.ParseString(templateContentType.DisplayFormUrl)) || !String.IsNullOrEmpty(parser.ParseString(templateContentType.EditFormUrl)) || !String.IsNullOrEmpty(parser.ParseString(templateContentType.NewFormUrl))) { // log message scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_ContentTypes_SkipCustomFormUrls, existingContentType.Name); } } #if !SP2013 if (templateContentType.Name.ContainsResourceToken()) { existingContentType.NameResource.SetUserResourceValue(templateContentType.Name, parser); isDirty = true; } if (templateContentType.Description.ContainsResourceToken()) { existingContentType.DescriptionResource.SetUserResourceValue(templateContentType.Description, parser); isDirty = true; } #endif if (isDirty) { existingContentType.Update(true); web.Context.ExecuteQueryRetry(); } // Delta handling existingContentType.EnsureProperty(c => c.FieldLinks); List <Guid> targetIds = existingContentType.FieldLinks.AsEnumerable().Select(c1 => c1.Id).ToList(); List <Guid> sourceIds = templateContentType.FieldRefs.Select(c1 => c1.Id).ToList(); var fieldsNotPresentInTarget = sourceIds.Except(targetIds).ToArray(); if (fieldsNotPresentInTarget.Any()) { foreach (var fieldId in fieldsNotPresentInTarget) { var fieldRef = templateContentType.FieldRefs.Find(fr => fr.Id == fieldId); var field = web.Fields.GetById(fieldId); scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ContentTypes_Adding_field__0__to_content_type, fieldId); web.AddFieldToContentType(existingContentType, field, fieldRef.Required, fieldRef.Hidden); } } isDirty = false; foreach (var fieldId in targetIds.Intersect(sourceIds)) { var fieldLink = existingContentType.FieldLinks.FirstOrDefault(fl => fl.Id == fieldId); var fieldRef = templateContentType.FieldRefs.Find(fr => fr.Id == fieldId); if (fieldRef != null) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ContentTypes_Field__0__exists_in_content_type, fieldId); if (fieldLink.Required != fieldRef.Required) { scope.LogPropertyUpdate("Required"); fieldLink.Required = fieldRef.Required; isDirty = true; } if (fieldLink.Hidden != fieldRef.Hidden) { scope.LogPropertyUpdate("Hidden"); fieldLink.Hidden = fieldRef.Hidden; isDirty = true; } } } // The new CT is a DocumentSet, and the target should be, as well if (templateContentType.DocumentSetTemplate != null) { if (!Microsoft.SharePoint.Client.DocumentSet.DocumentSetTemplate.IsChildOfDocumentSetContentType(web.Context, existingContentType).Value) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_ContentTypes_InvalidDocumentSet_Update_Request, existingContentType.Id, existingContentType.Name); } else { Microsoft.SharePoint.Client.DocumentSet.DocumentSetTemplate templateToUpdate = Microsoft.SharePoint.Client.DocumentSet.DocumentSetTemplate.GetDocumentSetTemplate(web.Context, existingContentType); // TODO: Implement Delta Handling scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_ContentTypes_DocumentSet_DeltaHandling_OnHold, existingContentType.Id, existingContentType.Name); } } if (isDirty) { existingContentType.Update(true); web.Context.ExecuteQueryRetry(); } }
public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { web.EnsureProperties(w => w.ServerRelativeUrl, w => w.Url); var serverRelativeUrl = web.ServerRelativeUrl; // For each list in the site var lists = web.Lists; web.Context.Load(lists, lc => lc.IncludeWithDefaultProperties( l => l.ContentTypes, l => l.Views, l => l.EnableModeration, l => l.ForceCheckout, l => l.BaseTemplate, l => l.OnQuickLaunch, l => l.RootFolder.ServerRelativeUrl, l => l.UserCustomActions, l => l.MajorVersionLimit, l => l.MajorWithMinorVersionsLimit, l => l.DraftVersionVisibility, l => l.DocumentTemplateUrl, l => l.Fields.IncludeWithDefaultProperties( f => f.Id, f => f.Title, f => f.Hidden, f => f.InternalName, f => f.DefaultValue, f => f.Required))); web.Context.ExecuteQueryRetry(); var allLists = new List<List>(); if (web.IsSubSite()) { // If current web is subweb then include the lists in the rootweb for lookup column support var rootWeb = (web.Context as ClientContext).Site.RootWeb; rootWeb.Context.Load(rootWeb.Lists, lsts => lsts.Include(l => l.Id, l => l.Title)); rootWeb.Context.ExecuteQueryRetry(); foreach (var rootList in rootWeb.Lists) { allLists.Add(rootList); } } foreach (var list in lists) { allLists.Add(list); } // Let's see if there are workflow subscriptions Microsoft.SharePoint.Client.WorkflowServices.WorkflowSubscription[] workflowSubscriptions = null; try { workflowSubscriptions = web.GetWorkflowSubscriptions(); } catch (ServerException) { // If there is no workflow service present in the farm this method will throw an error. // Swallow the exception } // Retrieve all not hidden lists and the Workflow History Lists, just in case there are active workflow subscriptions foreach (var siteList in lists.AsEnumerable().Where(l => (l.Hidden == false || ((workflowSubscriptions != null && workflowSubscriptions.Length > 0) && l.BaseTemplate == 140)))) { ListInstance baseTemplateList = null; if (creationInfo.BaseTemplate != null) { // Check if we need to skip this list...if so let's do it before we gather all the other information for this list...improves performance var index = creationInfo.BaseTemplate.Lists.FindIndex(f => f.Url.Equals(siteList.RootFolder.ServerRelativeUrl.Substring(serverRelativeUrl.Length + 1)) && f.TemplateType.Equals(siteList.BaseTemplate)); if (index != -1) { baseTemplateList = creationInfo.BaseTemplate.Lists[index]; } } var contentTypeFields = new List<FieldRef>(); var list = new ListInstance { Description = siteList.Description, EnableVersioning = siteList.EnableVersioning, TemplateType = siteList.BaseTemplate, Title = siteList.Title, Hidden = siteList.Hidden, EnableFolderCreation = siteList.EnableFolderCreation, DocumentTemplate = Tokenize(siteList.DocumentTemplateUrl, web.Url), ContentTypesEnabled = siteList.ContentTypesEnabled, Url = siteList.RootFolder.ServerRelativeUrl.Substring(serverRelativeUrl.Length).TrimStart('/'), TemplateFeatureID = siteList.TemplateFeatureId, EnableAttachments = siteList.EnableAttachments, OnQuickLaunch = siteList.OnQuickLaunch, EnableModeration = siteList.EnableModeration, MaxVersionLimit = siteList.IsPropertyAvailable("MajorVersionLimit") ? siteList.MajorVersionLimit : 0, EnableMinorVersions = siteList.EnableMinorVersions, MinorVersionLimit = siteList.IsPropertyAvailable("MajorWithMinorVersionsLimit") ? siteList.MajorWithMinorVersionsLimit : 0, ForceCheckout = siteList.IsPropertyAvailable("ForceCheckout") ? siteList.ForceCheckout : false, DraftVersionVisibility = siteList.IsPropertyAvailable("DraftVersionVisibility") ? (int)siteList.DraftVersionVisibility : 0, }; if (creationInfo.PersistMultiLanguageResources) { #if !SP2013 if (UserResourceExtensions.PersistResourceValue(siteList.TitleResource, string.Format("List_{0}_Title", siteList.Title.Replace(" ", "_")), template, creationInfo)) { list.Title = string.Format("{{res:List_{0}_Title}}", siteList.Title.Replace(" ", "_")); } if (UserResourceExtensions.PersistResourceValue(siteList.DescriptionResource, string.Format("List_{0}_Description", siteList.Title.Replace(" ", "_")), template, creationInfo)) { list.Description = string.Format("{{res:List_{0}_Description}}", siteList.Title.Replace(" ", "_")); } #endif } list = ExtractContentTypes(web, siteList, contentTypeFields, list); list = ExtractViews(siteList, list); list = ExtractFields(web, siteList, contentTypeFields, list, allLists, creationInfo, template); list = ExtractUserCustomActions(web, siteList, list, creationInfo, template); list.Security = siteList.GetSecurity(); var logCTWarning = false; if (baseTemplateList != null) { if (!baseTemplateList.Equals(list)) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Adding_list___0_____1_, list.Title, list.Url); template.Lists.Add(list); if (list.ContentTypesEnabled && list.ContentTypeBindings.Any() && web.IsSubSite()) { logCTWarning = true; } } } else { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Adding_list___0_____1_, list.Title, list.Url); template.Lists.Add(list); if (list.ContentTypesEnabled && list.ContentTypeBindings.Any() && web.IsSubSite()) { logCTWarning = true; } } if (logCTWarning) { scope.LogWarning("You are extracting a template from a subweb. List '{0}' refers to content types. Content types are not exported when extracting a template from a subweb", siteList.Title); WriteWarning(string.Format("You are extracting a template from a subweb. List '{0}' refers to content types. Content types are not exported when extracting a template from a subweb", siteList.Title), ProvisioningMessageType.Warning); } } } return template; }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { // Changed by Paolo Pialorsi to embrace the new sub-site attributes to break role inheritance and copy role assignments // if this is a sub site then we're not provisioning security as by default security is inherited from the root site //if (web.IsSubSite() && !template.Security.BreakRoleInheritance) //{ // scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_SiteSecurity_Context_web_is_subweb__skipping_site_security_provisioning); // return parser; //} if (web.IsSubSite() && template.Security.BreakRoleInheritance) { web.BreakRoleInheritance(template.Security.CopyRoleAssignments, template.Security.ClearSubscopes); web.Update(); web.Context.Load(web, w => w.HasUniqueRoleAssignments); web.Context.ExecuteQueryRetry(); } var siteSecurity = template.Security; if (web.EnsureProperty(w => w.HasUniqueRoleAssignments)) { string parsedAssociatedOwnerGroupName = parser.ParseString(template.Security.AssociatedOwnerGroup); string parsedAssociatedMemberGroupName = parser.ParseString(template.Security.AssociatedMemberGroup); string parsedAssociatedVisitorGroupName = parser.ParseString(template.Security.AssociatedVisitorGroup); bool webNeedsUpdate = false; if (parsedAssociatedOwnerGroupName != null) { if (string.IsNullOrEmpty(parsedAssociatedOwnerGroupName)) { web.AssociatedOwnerGroup = null; } else { web.AssociatedOwnerGroup = EnsureGroup(web, parsedAssociatedOwnerGroupName); } webNeedsUpdate = true; } if (parsedAssociatedMemberGroupName != null) { if (string.IsNullOrEmpty(parsedAssociatedMemberGroupName)) { web.AssociatedMemberGroup = null; } else { web.AssociatedMemberGroup = EnsureGroup(web, parsedAssociatedMemberGroupName); } webNeedsUpdate = true; } if (parsedAssociatedVisitorGroupName != null) { if (string.IsNullOrEmpty(parsedAssociatedVisitorGroupName)) { web.AssociatedVisitorGroup = null; } else { web.AssociatedVisitorGroup = EnsureGroup(web, parsedAssociatedVisitorGroupName); } webNeedsUpdate = true; } if (webNeedsUpdate) { // Trigger the creation and setting of the associated groups web.Update(); web.Context.ExecuteQueryRetry(); } } var ownerGroup = web.AssociatedOwnerGroup; var memberGroup = web.AssociatedMemberGroup; var visitorGroup = web.AssociatedVisitorGroup; if (!ownerGroup.ServerObjectIsNull()) { web.Context.Load(ownerGroup, o => o.Title, o => o.Users); } if (!memberGroup.ServerObjectIsNull()) { web.Context.Load(memberGroup, o => o.Title, o => o.Users); } if (!visitorGroup.ServerObjectIsNull()) { web.Context.Load(visitorGroup, o => o.Title, o => o.Users); } web.Context.Load(web.SiteUsers); web.Context.ExecuteQueryRetry(); IEnumerable <AssociatedGroupToken> associatedGroupTokens = parser.Tokens.Where(t => t.GetType() == typeof(AssociatedGroupToken)).Cast <AssociatedGroupToken>(); foreach (AssociatedGroupToken associatedGroupToken in associatedGroupTokens) { associatedGroupToken.ClearCache(); } if (!ownerGroup.ServerObjectIsNull()) { AddUserToGroup(web, ownerGroup, siteSecurity.AdditionalOwners, scope, parser); } if (!memberGroup.ServerObjectIsNull()) { AddUserToGroup(web, memberGroup, siteSecurity.AdditionalMembers, scope, parser); } if (!visitorGroup.ServerObjectIsNull()) { AddUserToGroup(web, visitorGroup, siteSecurity.AdditionalVisitors, scope, parser); } foreach (var siteGroup in siteSecurity.SiteGroups .Sort <SiteGroup>( _grp => { string groupOwner = _grp.Owner; if (string.IsNullOrWhiteSpace(groupOwner) || "SHAREPOINT\\system".Equals(groupOwner, StringComparison.OrdinalIgnoreCase) || _grp.Title.Equals(groupOwner, StringComparison.OrdinalIgnoreCase) || (groupOwner.StartsWith("{{associated") && groupOwner.EndsWith("group}}"))) { return(Enumerable.Empty <SiteGroup>()); } return(siteSecurity.SiteGroups.Where(_item => _item.Title.Equals(groupOwner, StringComparison.OrdinalIgnoreCase))); } )) { Group group; var allGroups = web.Context.LoadQuery(web.SiteGroups.Include(gr => gr.LoginName)); web.Context.ExecuteQueryRetry(); string parsedGroupTitle = parser.ParseString(siteGroup.Title); string parsedGroupOwner = parser.ParseString(siteGroup.Owner); string parsedGroupDescription = parser.ParseString(siteGroup.Description); if (!web.GroupExists(parsedGroupTitle)) { scope.LogDebug("Creating group {0}", parsedGroupTitle); group = web.AddGroup( parsedGroupTitle, //If the description is more than 512 characters long a server exception will be thrown. PnPHttpUtility.ConvertSimpleHtmlToText(parsedGroupDescription, int.MaxValue), parsedGroupTitle == parsedGroupOwner); group.AllowMembersEditMembership = siteGroup.AllowMembersEditMembership; group.AllowRequestToJoinLeave = siteGroup.AllowRequestToJoinLeave; group.AutoAcceptRequestToJoinLeave = siteGroup.AutoAcceptRequestToJoinLeave; group.OnlyAllowMembersViewMembership = siteGroup.OnlyAllowMembersViewMembership; group.RequestToJoinLeaveEmailSetting = siteGroup.RequestToJoinLeaveEmailSetting; if (parsedGroupOwner != null && (parsedGroupTitle != parsedGroupOwner)) { Principal ownerPrincipal = allGroups.FirstOrDefault(gr => gr.LoginName.Equals(parsedGroupOwner, StringComparison.OrdinalIgnoreCase)); if (ownerPrincipal == null) { ownerPrincipal = web.EnsureUser(parsedGroupOwner); } group.Owner = ownerPrincipal; } group.Update(); web.Context.Load(group, g => g.Id, g => g.Title); web.Context.ExecuteQueryRetry(); parser.AddToken(new GroupIdToken(web, group.Title, group.Id)); var groupItem = web.SiteUserInfoList.GetItemById(group.Id); groupItem["Notes"] = parsedGroupDescription; groupItem.Update(); web.Context.ExecuteQueryRetry(); } else { group = web.SiteGroups.GetByName(parsedGroupTitle); web.Context.Load(group, g => g.Id, g => g.Title, g => g.Description, g => g.AllowMembersEditMembership, g => g.AllowRequestToJoinLeave, g => g.AutoAcceptRequestToJoinLeave, g => g.OnlyAllowMembersViewMembership, g => g.RequestToJoinLeaveEmailSetting, g => g.Owner.LoginName); web.Context.ExecuteQueryRetry(); var groupNeedsUpdate = false; var executeQuery = false; if (parsedGroupDescription != null) { var groupItem = web.SiteUserInfoList.GetItemById(group.Id); web.Context.Load(groupItem, g => g["Notes"]); web.Context.ExecuteQueryRetry(); var description = groupItem["Notes"]?.ToString(); if (description != parsedGroupDescription) { groupItem["Notes"] = parsedGroupDescription; groupItem.Update(); executeQuery = true; } var plainTextDescription = PnPHttpUtility.ConvertSimpleHtmlToText(parsedGroupDescription, int.MaxValue); if (group.Description != plainTextDescription) { //If the description is more than 512 characters long a server exception will be thrown. group.Description = plainTextDescription; groupNeedsUpdate = true; } } if (group.AllowMembersEditMembership != siteGroup.AllowMembersEditMembership) { group.AllowMembersEditMembership = siteGroup.AllowMembersEditMembership; groupNeedsUpdate = true; } if (group.AllowRequestToJoinLeave != siteGroup.AllowRequestToJoinLeave) { group.AllowRequestToJoinLeave = siteGroup.AllowRequestToJoinLeave; groupNeedsUpdate = true; } if (group.AutoAcceptRequestToJoinLeave != siteGroup.AutoAcceptRequestToJoinLeave) { group.AutoAcceptRequestToJoinLeave = siteGroup.AutoAcceptRequestToJoinLeave; groupNeedsUpdate = true; } if (group.OnlyAllowMembersViewMembership != siteGroup.OnlyAllowMembersViewMembership) { group.OnlyAllowMembersViewMembership = siteGroup.OnlyAllowMembersViewMembership; groupNeedsUpdate = true; } if (!String.IsNullOrEmpty(group.RequestToJoinLeaveEmailSetting) && group.RequestToJoinLeaveEmailSetting != siteGroup.RequestToJoinLeaveEmailSetting) { group.RequestToJoinLeaveEmailSetting = siteGroup.RequestToJoinLeaveEmailSetting; groupNeedsUpdate = true; } if (parsedGroupOwner != null && group.Owner.LoginName != parsedGroupOwner) { if (parsedGroupTitle != parsedGroupOwner) { Principal ownerPrincipal = allGroups.FirstOrDefault(gr => gr.LoginName.Equals(parsedGroupOwner, StringComparison.OrdinalIgnoreCase)); if (ownerPrincipal == null) { ownerPrincipal = web.EnsureUser(parsedGroupOwner); } group.Owner = ownerPrincipal; } else { group.Owner = group; } groupNeedsUpdate = true; } if (groupNeedsUpdate) { scope.LogDebug("Updating existing group {0}", group.Title); group.Update(); executeQuery = true; } if (executeQuery) { web.Context.ExecuteQueryRetry(); } } if (group != null && siteGroup.Members.Any()) { AddUserToGroup(web, group, siteGroup.Members, scope, parser); } } foreach (var admin in siteSecurity.AdditionalAdministrators) { var parsedAdminName = parser.ParseString(admin.Name); try { var user = web.EnsureUser(parsedAdminName); user.IsSiteAdmin = true; user.Update(); web.Context.ExecuteQueryRetry(); } catch (Exception ex) { scope.LogWarning(ex, "Failed to add AdditionalAdministrator {0}", parsedAdminName); } } // With the change from october, manage permission levels on subsites as well if (siteSecurity.SiteSecurityPermissions != null) { var existingRoleDefinitions = web.Context.LoadQuery(web.RoleDefinitions.Include(wr => wr.Name, wr => wr.BasePermissions, wr => wr.Description)); web.Context.ExecuteQueryRetry(); if (siteSecurity.SiteSecurityPermissions.RoleDefinitions.Any()) { foreach (var templateRoleDefinition in siteSecurity.SiteSecurityPermissions.RoleDefinitions) { var roleDefinitions = existingRoleDefinitions as RoleDefinition[] ?? existingRoleDefinitions.ToArray(); var parsedRoleDefinitionName = parser.ParseString(templateRoleDefinition.Name); var parsedTemplateRoleDefinitionDesc = parser.ParseString(templateRoleDefinition.Description); var siteRoleDefinition = roleDefinitions.FirstOrDefault(erd => erd.Name == parsedRoleDefinitionName); if (siteRoleDefinition == null) { scope.LogDebug("Creating role definition {0}", parsedRoleDefinitionName); var roleDefinitionCI = new RoleDefinitionCreationInformation(); roleDefinitionCI.Name = parsedRoleDefinitionName; roleDefinitionCI.Description = parsedTemplateRoleDefinitionDesc; BasePermissions basePermissions = new BasePermissions(); foreach (var permission in templateRoleDefinition.Permissions) { basePermissions.Set(permission); } roleDefinitionCI.BasePermissions = basePermissions; var newRoleDefinition = web.RoleDefinitions.Add(roleDefinitionCI); web.Context.Load(newRoleDefinition, nrd => nrd.Name, nrd => nrd.Id); web.Context.ExecuteQueryRetry(); parser.AddToken(new RoleDefinitionIdToken(web, newRoleDefinition.Name, newRoleDefinition.Id)); } else { var isDirty = false; if (siteRoleDefinition.Description != parsedTemplateRoleDefinitionDesc) { siteRoleDefinition.Description = parsedTemplateRoleDefinitionDesc; isDirty = true; } var templateBasePermissions = new BasePermissions(); // iterate over all possible PermissionKind values and set them on the new object foreach (PermissionKind pk in Enum.GetValues(typeof(PermissionKind))) { if (siteRoleDefinition.BasePermissions.Has(pk)) { templateBasePermissions.Set(pk); } } // add the permissions that were specified in the template templateRoleDefinition.Permissions.ForEach(p => templateBasePermissions.Set(p)); if (siteRoleDefinition.BasePermissions != templateBasePermissions) { isDirty = true; siteRoleDefinition.BasePermissions = templateBasePermissions; } if (isDirty) { scope.LogDebug("Updating role definition {0}", parsedRoleDefinitionName); siteRoleDefinition.Update(); web.Context.ExecuteQueryRetry(); } } } } var webRoleDefinitions = web.Context.LoadQuery(web.RoleDefinitions); var webRoleAssignments = web.Context.LoadQuery(web.RoleAssignments); var groups = web.Context.LoadQuery(web.SiteGroups.Include(g => g.LoginName)); web.Context.ExecuteQueryRetry(); if (siteSecurity.SiteSecurityPermissions.RoleAssignments.Any()) { foreach (var roleAssignment in siteSecurity.SiteSecurityPermissions.RoleAssignments) { var parsedRoleDefinition = parser.ParseString(roleAssignment.RoleDefinition); if (!roleAssignment.Remove) { var roleDefinition = webRoleDefinitions.FirstOrDefault(r => r.Name == parsedRoleDefinition); if (roleDefinition != null) { Principal principal = GetPrincipal(web, parser, scope, groups, roleAssignment); if (principal != null) { var roleDefinitionBindingCollection = new RoleDefinitionBindingCollection(web.Context); roleDefinitionBindingCollection.Add(roleDefinition); web.RoleAssignments.Add(principal, roleDefinitionBindingCollection); web.Context.ExecuteQueryRetry(); } } else { scope.LogWarning("Role assignment {0} not found in web", roleAssignment.RoleDefinition); } } else { var principal = GetPrincipal(web, parser, scope, groups, roleAssignment); if (principal != null) { var assignmentsForPrincipal = webRoleAssignments.Where(t => t.PrincipalId == principal.Id); foreach (var assignmentForPrincipal in assignmentsForPrincipal) { var binding = assignmentForPrincipal.EnsureProperty(r => r.RoleDefinitionBindings).FirstOrDefault(b => b.Name == parsedRoleDefinition); if (binding != null) { assignmentForPrincipal.DeleteObject(); web.Context.ExecuteQueryRetry(); break; } } } } } } } } return(parser); }