protected override void ExecuteCmdlet() { if (!SelectedWeb.IsPropertyAvailable("Url")) { ClientContext.Load(SelectedWeb, w => w.Url); ClientContext.ExecuteQueryRetry(); } if (!System.IO.Path.IsPathRooted(Path)) { Path = System.IO.Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, Path); } FileInfo fileInfo = new FileInfo(Path); XMLTemplateProvider provider = new XMLFileSystemTemplateProvider(fileInfo.DirectoryName, ""); var provisioningTemplate = provider.GetTemplate(fileInfo.Name); if (provisioningTemplate != null) { var fileSystemConnector = new FileSystemConnector(fileInfo.DirectoryName, ""); provisioningTemplate.Connector = fileSystemConnector; var applyingInformation = new ProvisioningTemplateApplyingInformation(); applyingInformation.ProgressDelegate = (message, step, total) => { WriteProgress(new ProgressRecord(0, string.Format("Applying template to {0}", SelectedWeb.Url), message) { PercentComplete = (100 / total) * step }); }; SelectedWeb.ApplyProvisioningTemplate(provisioningTemplate, applyingInformation); } }
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(); if (isNoScriptSite) { return parser; } web.SetPropertyBagValue("_PnP_ProvisioningTemplateId", template.Id != null ? template.Id : ""); web.AddIndexedPropertyBagKey("_PnP_ProvisioningTemplateId"); ProvisioningTemplateInfo info = new ProvisioningTemplateInfo(); info.TemplateId = template.Id != null ? template.Id : ""; info.TemplateVersion = template.Version; info.TemplateSitePolicy = template.SitePolicy; info.Result = true; info.ProvisioningTime = DateTime.Now; string jsonInfo = JsonConvert.SerializeObject(info); web.SetPropertyBagValue("_PnP_ProvisioningTemplateInfo", jsonInfo); } 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; var site = context.Site; // Check if this is not a noscript site as we're not allowed to update some properties bool isNoScriptSite = web.IsNoScriptSite(); // if this is a sub site then we're not enabling the site collection scoped custom actions if (!web.IsSubSite()) { var siteCustomActions = template.CustomActions.SiteCustomActions; ProvisionCustomActionImplementation(site, siteCustomActions, parser, scope, isNoScriptSite); } var webCustomActions = template.CustomActions.WebCustomActions; ProvisionCustomActionImplementation(web, webCustomActions, parser, scope, isNoScriptSite); // Switch parser context back to it's original context parser.Rebase(web); } 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 override void ProvisionObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateApplyingInformation applyingInformation) { Log.Info(Constants.LOGGING_SOURCE_FRAMEWORK_PROVISIONING, CoreResources.Provisioning_ObjectHandlers_Fields); // 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()) { return; } 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(field.SchemaXml.ToParsedString("~sitecollection", "~site")); var fieldId = templateFieldElement.Attribute("ID").Value; if (!existingFieldIds.Contains(Guid.Parse(fieldId))) { CreateField(web, templateFieldElement); } else { UpdateField(web, fieldId, templateFieldElement); } } }
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 (template.ComposedLook != null && !template.ComposedLook.Equals(ComposedLook.Empty)) { bool executeQueryNeeded = false; if (executeQueryNeeded) { web.Context.ExecuteQueryRetry(); } if (String.IsNullOrEmpty(template.ComposedLook.ColorFile) && String.IsNullOrEmpty(template.ComposedLook.FontFile) && String.IsNullOrEmpty(template.ComposedLook.BackgroundFile)) { // Apply OOB theme web.SetComposedLookByUrl(template.ComposedLook.Name); } else { // Apply custom theme string colorFile = null; if (!string.IsNullOrEmpty(template.ComposedLook.ColorFile)) { colorFile = parser.ParseString(template.ComposedLook.ColorFile); } string backgroundFile = null; if (!string.IsNullOrEmpty(template.ComposedLook.BackgroundFile)) { backgroundFile = parser.ParseString(template.ComposedLook.BackgroundFile); } string fontFile = null; if (!string.IsNullOrEmpty(template.ComposedLook.FontFile)) { fontFile = parser.ParseString(template.ComposedLook.FontFile); } string masterUrl = null; if (template.WebSettings != null && !string.IsNullOrEmpty(template.WebSettings.MasterPageUrl)) { masterUrl = parser.ParseString(template.WebSettings.MasterPageUrl); } web.CreateComposedLookByUrl(template.ComposedLook.Name, colorFile, fontFile, backgroundFile, masterUrl); web.SetComposedLookByUrl(template.ComposedLook.Name, colorFile, fontFile, backgroundFile, masterUrl); var composedLookJson = JsonConvert.SerializeObject(template.ComposedLook); web.SetPropertyBagValue("_PnP_ProvisioningTemplateComposedLookInfo", composedLookJson); } // Persist composed look info in property bag } } return parser; }
public void Provision(ClientContext ctx, ProvisioningTemplate template, ProvisioningTemplateApplyingInformation applyingInformation, TokenParser tokenParser, PnPMonitoredScope scope, string configurationData) { bool _urlCheck = ctx.Url.Equals(ExtensibilityTestConstants.MOCK_URL, StringComparison.OrdinalIgnoreCase); if (!_urlCheck) throw new Exception("CTXURLNOTTHESAME"); bool _templateCheck = template.Id.Equals(ExtensibilityTestConstants.PROVISIONINGTEMPLATE_ID, StringComparison.OrdinalIgnoreCase); if (!_templateCheck) throw new Exception("TEMPLATEIDNOTTHESAME"); bool _configDataCheck = configurationData.Equals(ExtensibilityTestConstants.PROVIDER_MOCK_DATA, StringComparison.OrdinalIgnoreCase); if (!_configDataCheck) throw new Exception("CONFIGDATANOTTHESAME"); }
public override void ProvisionObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateApplyingInformation applyingInformation) { Log.Info(Constants.LOGGING_SOURCE_FRAMEWORK_PROVISIONING, CoreResources.Provisioning_ObjectHandlers_SitePolicy); if (template.SitePolicy != null) { if (web.GetSitePolicyByName(template.SitePolicy) != null) // Site Policy Available? { web.ApplySitePolicy(template.SitePolicy); } } }
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; if (!String.IsNullOrEmpty(template.SearchSettings)) { site.SetSearchConfiguration(template.SearchSettings); } } 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 void ApplyCustomTemplateToSite() { var provisioningTemplate = _siteTemplate.PnpTemplate; var applyingInfo = new ProvisioningTemplateApplyingInformation { ProgressDelegate = (message, step, total) => { Updatehelper.UpdateProgressView($"{step}/{total} Provisioning {message}", _actionRequest); } }; _ctx.Web.ApplyProvisioningTemplate(provisioningTemplate, applyingInfo); }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(CoreResources.Provisioning_ObjectHandlers_SitePolicy)) { if (template.SitePolicy != null) { if (web.GetSitePolicyByName(template.SitePolicy) != null) // Site Policy Available? { web.ApplySitePolicy(template.SitePolicy); } } } return parser; }
public void Provision(ClientContext ctx, ProvisioningTemplate template, ProvisioningTemplateApplyingInformation applyingInformation, TokenParser tokenParser, PnPMonitoredScope scope, string configurationData) { Log.Info( logSource, "ProcessRequest. Template: {0}. Config: {1}", template.Id, configurationData); clientContext = ctx; web = ctx.Web; configurationXml = configurationData; AddPublishingPages(); }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { if (template.AuditSettings != null) { // Check if this is not a noscript site as we're not allowed to update some properties bool isNoScriptSite = web.IsNoScriptSite(); var site = (web.Context as ClientContext).Site; site.EnsureProperties(s => s.Audit, s => s.AuditLogTrimmingRetention, s => s.TrimAuditLog); var siteAuditSettings = site.Audit; var isDirty = false; if (template.AuditSettings.AuditFlags != siteAuditSettings.AuditFlags) { site.Audit.AuditFlags = template.AuditSettings.AuditFlags; site.Audit.Update(); isDirty = true; } if (!isNoScriptSite) { if (template.AuditSettings.AuditLogTrimmingRetention != site.AuditLogTrimmingRetention) { site.AuditLogTrimmingRetention = template.AuditSettings.AuditLogTrimmingRetention; isDirty = true; } } else { scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_Audit_SkipAuditLogTrimmingRetention); } if (template.AuditSettings.TrimAuditLog != site.TrimAuditLog) { site.TrimAuditLog = template.AuditSettings.TrimAuditLog; isDirty = true; } if (isDirty) { web.Context.ExecuteQueryRetry(); } } } return parser; }
/// <summary> /// Actual implementation of the apply templates /// </summary> /// <param name="web"></param> /// <param name="provisioningInfo"></param> internal void ApplyRemoteTemplate(Web web, ProvisioningTemplate template, ProvisioningTemplateApplyingInformation provisioningInfo) { ProvisioningProgressDelegate progressDelegate = null; if (provisioningInfo != null) { progressDelegate = provisioningInfo.ProgressDelegate; } Log.Info(Constants.LOGGING_SOURCE_FRAMEWORK_PROVISIONING, CoreResources.Provisioning_ObjectHandlers_StartProvisioning); List<ObjectHandlerBase> objectHandlers = new List<ObjectHandlerBase>(); objectHandlers.Add(new ObjectSitePolicy()); objectHandlers.Add(new ObjectSiteSecurity()); objectHandlers.Add(new ObjectFeatures()); objectHandlers.Add(new ObjectTermGroups()); objectHandlers.Add(new ObjectField()); objectHandlers.Add(new ObjectContentType()); objectHandlers.Add(new ObjectListInstance()); objectHandlers.Add(new ObjectLookupFields()); objectHandlers.Add(new ObjectFiles()); objectHandlers.Add(new ObjectPages()); objectHandlers.Add(new ObjectCustomActions()); objectHandlers.Add(new ObjectComposedLook()); objectHandlers.Add(new ObjectPropertyBagEntry()); objectHandlers.Add(new ObjectExtensibilityProviders()); objectHandlers.Add(new ObjectPersistTemplateInfo()); TokenParser.Initialize(web, template); int step = 1; var count = objectHandlers.Count(o => o.ReportProgress && o.WillProvision(web, template)); foreach (var handler in objectHandlers) { if (handler.WillProvision(web, template)) { if (handler.ReportProgress && progressDelegate != null) { progressDelegate(handler.Name, step, count); step++; } handler.ProvisionObjects(web, template); } } Log.Info(Constants.LOGGING_SOURCE_FRAMEWORK_PROVISIONING, CoreResources.Provisioning_ObjectHandlers_FinishProvisioning); }
public override void ProvisionObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateApplyingInformation applyingInformation) { web.SetPropertyBagValue("_PnP_ProvisioningTemplateId", template.Id != null ? template.Id : ""); web.AddIndexedPropertyBagKey("_PnP_ProvisioningTemplateId"); ProvisioningTemplateInfo info = new ProvisioningTemplateInfo(); info.TemplateId = template.Id != null ? template.Id : ""; info.TemplateVersion = template.Version; info.TemplateSitePolicy = template.SitePolicy; info.Result = true; info.ProvisioningTime = DateTime.Now; string jsonInfo = JsonConvert.SerializeObject(info); web.SetPropertyBagValue("_PnP_ProvisioningTemplateInfo", jsonInfo); }
protected override void ExecuteCmdlet() { var template = new ProvisioningTemplate(); template.Security = null; template.Features = null; template.CustomActions = null; template.ComposedLook = null; template.Id = "TAXONOMYPROVISIONING"; var outputStream = XMLPnPSchemaFormatter.LatestFormatter.ToFormattedTemplate(template); var reader = new StreamReader(outputStream); var fullXml = reader.ReadToEnd(); var document = XDocument.Parse(fullXml); XElement termGroupsElement; if (MyInvocation.BoundParameters.ContainsKey("Xml")) { termGroupsElement = XElement.Parse(Xml); } else { if (!System.IO.Path.IsPathRooted(Path)) { Path = System.IO.Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, Path); } termGroupsElement = XElement.Parse(File.ReadAllText(Path)); } //XNamespace pnp = XMLConstants.PROVISIONING_SCHEMA_NAMESPACE_25_12; var templateElement = document.Root.Descendants(document.Root.GetNamespaceOfPrefix("pnp") + "ProvisioningTemplate").FirstOrDefault(); templateElement?.Add(termGroupsElement); var stream = new MemoryStream(); document.Save(stream); stream.Position = 0; var completeTemplate = XMLPnPSchemaFormatter.LatestFormatter.ToProvisioningTemplate(stream); ProvisioningTemplateApplyingInformation templateAI = new ProvisioningTemplateApplyingInformation(); templateAI.HandlersToProcess = Handlers.TermGroups; ClientContext.Web.ApplyProvisioningTemplate(completeTemplate, templateAI); }
public override void ProvisionObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateApplyingInformation applyingInformation) { Log.Info(Constants.LOGGING_SOURCE_FRAMEWORK_PROVISIONING, CoreResources.Provisioning_ObjectHandlers_ContentTypes); // 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()) { return; } web.Context.Load(web.ContentTypes, ct => ct.IncludeWithDefaultProperties(c => c.StringId, c => c.FieldLinks)); web.Context.ExecuteQueryRetry(); var existingCTs = web.ContentTypes.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) { var newCT = CreateContentType(web, ct); if (newCT != null) { existingCTs.Add(newCT); } } else { if (ct.Overwrite) { existingCT.DeleteObject(); web.Context.ExecuteQueryRetry(); var newCT = CreateContentType(web, ct); if (newCT != null) { existingCTs.Add(newCT); } } else { UpdateContentType(web, existingCT, ct); } } } }
public void SiteCollectionPropertyBagAddingTest() { using (var cc = TestCommon.CreateClientContext(centralSiteCollectionUrl)) { // Ensure we can test clean DeleteWebProperties(cc); // Add web properties var result = TestProvisioningTemplate(cc, "propertybag_add.xml", Handlers.PropertyBagEntries); PropertyBagValidator pv = new PropertyBagValidator(); Assert.IsTrue(pv.Validate(result.SourceTemplate.PropertyBagEntries, result.TargetTemplate.PropertyBagEntries, result.SourceTokenParser)); // Update web properties var result2 = TestProvisioningTemplate(cc, "propertybag_delta_1.xml", Handlers.PropertyBagEntries); PropertyBagValidator pv2 = new PropertyBagValidator(); pv2.ValidateEvent += Pv2_ValidateEvent; Assert.IsTrue(pv2.Validate(result2.SourceTemplate.PropertyBagEntries, result2.TargetTemplate.PropertyBagEntries, result2.SourceTokenParser)); // Update system properties: run 1 is without specifying the override flag...no updates should happen ProvisioningTemplateApplyingInformation ptai3 = new ProvisioningTemplateApplyingInformation(); ptai3.OverwriteSystemPropertyBagValues = false; //=default ptai3.HandlersToProcess = Handlers.PropertyBagEntries; // Set base template to null to ensure all properties are fetched by the engine ProvisioningTemplateCreationInformation ptci3 = new ProvisioningTemplateCreationInformation(cc.Web); ptci3.BaseTemplate = null; ptci3.HandlersToProcess = Handlers.PropertyBagEntries; var result3 = TestProvisioningTemplate(cc, "propertybag_delta_2.xml", Handlers.PropertyBagEntries, ptai3, ptci3); PropertyBagValidator pv3 = new PropertyBagValidator(); pv3.ValidateEvent += Pv3_ValidateEvent; Assert.IsTrue(pv3.Validate(result3.SourceTemplate.PropertyBagEntries, result3.TargetTemplate.PropertyBagEntries, result3.SourceTokenParser)); // Update system properties: run 2 is with specifying the override flag...updates should happen if the overwrite flag was set to true ProvisioningTemplateApplyingInformation ptai4 = new ProvisioningTemplateApplyingInformation(); // Set system overwrite flag ptai4.OverwriteSystemPropertyBagValues = true; ptai4.HandlersToProcess = Handlers.PropertyBagEntries; // Set base template to null to ensure all properties are fetched by the engine ProvisioningTemplateCreationInformation ptci4 = new ProvisioningTemplateCreationInformation(cc.Web); ptci4.BaseTemplate = null; ptci4.HandlersToProcess = Handlers.PropertyBagEntries; var result4 = TestProvisioningTemplate(cc, "propertybag_delta_2.xml", Handlers.PropertyBagEntries, ptai4, ptci4); PropertyBagValidator pv4 = new PropertyBagValidator(); pv4.ValidateEvent += Pv2_ValidateEvent; Assert.IsTrue(pv4.Validate(result4.SourceTemplate.PropertyBagEntries, result4.TargetTemplate.PropertyBagEntries, result4.SourceTokenParser)); } }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { try { parser = ProcessLookupFields(web, template, parser, scope); } catch (Exception ex) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_LookupFields_Processing_lookup_fields_failed___0_____1_, ex.Message, ex.StackTrace); //throw; } } return parser; }
public override void ProvisionObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateApplyingInformation applyingInformation) { Log.Info(Constants.LOGGING_SOURCE_FRAMEWORK_PROVISIONING, CoreResources.Provisioning_ObjectHandlers_SiteSecurity); // 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()) { return; } var siteSecurity = template.Security; var ownerGroup = web.AssociatedOwnerGroup; var memberGroup = web.AssociatedMemberGroup; var visitorGroup = web.AssociatedVisitorGroup; web.Context.Load(ownerGroup, o => o.Users); web.Context.Load(memberGroup, o => o.Users); web.Context.Load(visitorGroup, o => o.Users); web.Context.ExecuteQueryRetry(); if (!ownerGroup.ServerObjectIsNull.Value) { AddUserToGroup(web, ownerGroup, siteSecurity.AdditionalOwners); } if (!memberGroup.ServerObjectIsNull.Value) { AddUserToGroup(web, memberGroup, siteSecurity.AdditionalMembers); } if (!visitorGroup.ServerObjectIsNull.Value) { AddUserToGroup(web, visitorGroup, siteSecurity.AdditionalVisitors); } foreach (var admin in siteSecurity.AdditionalAdministrators) { var user = web.EnsureUser(admin.Name); user.IsSiteAdmin = true; user.Update(); web.Context.ExecuteQueryRetry(); } }
public override void ProvisionObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateApplyingInformation applyingInformation) { Log.Info(Constants.LOGGING_SOURCE_FRAMEWORK_PROVISIONING, CoreResources.Provisioning_ObjectHandlers_CustomActions); var context = web.Context as ClientContext; var site = context.Site; // if this is a sub site then we're not enabling the site collection scoped custom actions if (!web.IsSubSite()) { var siteCustomActions = template.CustomActions.SiteCustomActions; ProvisionCustomActionImplementation(site, siteCustomActions); } var webCustomActions = template.CustomActions.WebCustomActions; ProvisionCustomActionImplementation(web, webCustomActions); // Switch parser context back to it's original context TokenParser.Rebase(web); }
public override void ProvisionObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateApplyingInformation applyingInformation) { Log.Info(Constants.LOGGING_SOURCE_FRAMEWORK_PROVISIONING, CoreResources.Provisioning_ObjectHandlers_ExtensibilityProviders); var _ctx = web.Context as ClientContext; foreach(var _provider in template.Providers) { if (_provider.Enabled) { try { _extManager.ExecuteExtensibilityCallOut(_ctx, _provider, template); } catch (Exception ex) { Log.Error(Constants.LOGGING_SOURCE, ex.Message); } } } }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { web.SetPropertyBagValue("_PnP_ProvisioningTemplateId", template.Id != null ? template.Id : ""); web.AddIndexedPropertyBagKey("_PnP_ProvisioningTemplateId"); ProvisioningTemplateInfo info = new ProvisioningTemplateInfo(); info.TemplateId = template.Id != null ? template.Id : ""; info.TemplateVersion = template.Version; info.TemplateSitePolicy = template.SitePolicy; info.Result = true; info.ProvisioningTime = DateTime.Now; string jsonInfo = JsonConvert.SerializeObject(info); web.SetPropertyBagValue("_PnP_ProvisioningTemplateInfo", jsonInfo); } return parser; }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(CoreResources.Provisioning_ObjectHandlers_CustomActions)) { var context = web.Context as ClientContext; var site = context.Site; // if this is a sub site then we're not enabling the site collection scoped custom actions if (!web.IsSubSite()) { var siteCustomActions = template.CustomActions.SiteCustomActions; ProvisionCustomActionImplementation(site, siteCustomActions, parser, scope); } var webCustomActions = template.CustomActions.WebCustomActions; ProvisionCustomActionImplementation(web, webCustomActions, parser, scope); // Switch parser context back to it's original context parser.Rebase(web); } return parser; }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { if (template.AuditSettings != null) { var site = (web.Context as ClientContext).Site; site.EnsureProperties(s => s.Audit, s => s.AuditLogTrimmingRetention, s => s.TrimAuditLog); var siteAuditSettings = site.Audit; var isDirty = false; if (template.AuditSettings.AuditFlags != siteAuditSettings.AuditFlags) { site.Audit.AuditFlags = template.AuditSettings.AuditFlags; site.Audit.Update(); isDirty = true; } if (template.AuditSettings.AuditLogTrimmingRetention != site.AuditLogTrimmingRetention) { site.AuditLogTrimmingRetention = template.AuditSettings.AuditLogTrimmingRetention; isDirty = true; } if (template.AuditSettings.TrimAuditLog != site.TrimAuditLog) { site.TrimAuditLog = template.AuditSettings.TrimAuditLog; isDirty = true; } if (isDirty) { web.Context.ExecuteQueryRetry(); } } } return parser; }
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 void Provision(ClientContext ctx, ProvisioningTemplate template, ProvisioningTemplateApplyingInformation applyingInformation, TokenParser tokenParser, PnPMonitoredScope scope, string configurationData) { logger.Info("Entering the SiteFields provider"); try { // ---------------------------------------------- // Deserializes the configuration data // ---------------------------------------------- SiteFieldsConfigurationData configData = XmlUtility.DeserializeXml<SiteFieldsConfigurationData>(configurationData); // ---------------------------------------------- // Loads the site collection and root web // ---------------------------------------------- using (SPSite site = new SPSite(ctx.Url)) { using (SPWeb web = site.OpenWeb()) { // ---------------------------------------------- // Loops through the <Fields> nodes // ---------------------------------------------- foreach (Field configField in configData.Fields) { SPField field = web.Fields.GetFieldByInternalName(configField.Name); // ---------------------------------------------- // Configures the field's title resource // ---------------------------------------------- ConfigureFieldTitleResource(field, configField); } } } } catch(Exception e) { throw new Exception(String.Format(ERROR_GENERAL, e.Message), e.InnerException); } }
public override TokenParser ProvisionObjects(Web web, Model.ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { TaxonomySession taxSession = TaxonomySession.GetTaxonomySession(web.Context); var termStore = taxSession.GetDefaultKeywordsTermStore(); web.Context.Load(termStore, ts => ts.DefaultLanguage, ts => ts.Groups.Include( tg => tg.Name, tg => tg.Id, tg => tg.TermSets.Include( tset => tset.Name, tset => tset.Id))); web.Context.ExecuteQueryRetry(); foreach (var modelTermGroup in template.TermGroups) { #region Group var newGroup = false; TermGroup group = termStore.Groups.FirstOrDefault( g => g.Id == modelTermGroup.Id || g.Name == modelTermGroup.Name); if (group == null) { if (modelTermGroup.Name == "Site Collection") { var site = (web.Context as ClientContext).Site; group = termStore.GetSiteCollectionGroup(site, true); web.Context.Load(group, g => g.Name, g => g.Id, g => g.TermSets.Include( tset => tset.Name, tset => tset.Id)); web.Context.ExecuteQueryRetry(); } else { var parsedGroupName = parser.ParseString(modelTermGroup.Name); group = termStore.Groups.FirstOrDefault(g => g.Name == parsedGroupName); if (group == null) { if (modelTermGroup.Id == Guid.Empty) { modelTermGroup.Id = Guid.NewGuid(); } group = termStore.CreateGroup(parsedGroupName, modelTermGroup.Id); group.Description = modelTermGroup.Description; termStore.CommitAll(); web.Context.Load(group); web.Context.ExecuteQueryRetry(); newGroup = true; } } } #endregion #region TermSets foreach (var modelTermSet in modelTermGroup.TermSets) { TermSet set = null; var newTermSet = false; if (!newGroup) { set = group.TermSets.FirstOrDefault(ts => ts.Id == modelTermSet.Id || ts.Name == modelTermSet.Name); } if (set == null) { if (modelTermSet.Id == Guid.Empty) { modelTermSet.Id = Guid.NewGuid(); } set = group.CreateTermSet(parser.ParseString(modelTermSet.Name), modelTermSet.Id, modelTermSet.Language ?? termStore.DefaultLanguage); parser.AddToken(new TermSetIdToken(web, modelTermGroup.Name, modelTermSet.Name, modelTermSet.Id)); newTermSet = true; set.IsOpenForTermCreation = modelTermSet.IsOpenForTermCreation; set.IsAvailableForTagging = modelTermSet.IsAvailableForTagging; foreach (var property in modelTermSet.Properties) { set.SetCustomProperty(property.Key, property.Value); } if (modelTermSet.Owner != null) { set.Owner = modelTermSet.Owner; } termStore.CommitAll(); web.Context.Load(set); web.Context.ExecuteQueryRetry(); } web.Context.Load(set, s => s.Terms.Include(t => t.Id, t => t.Name)); web.Context.ExecuteQueryRetry(); var terms = set.Terms; foreach (var modelTerm in modelTermSet.Terms) { if (!newTermSet) { if (terms.Any()) { var term = terms.FirstOrDefault(t => t.Id == modelTerm.Id); if (term == null) { term = terms.FirstOrDefault(t => t.Name == modelTerm.Name); if (term == null) { var returnTuple = CreateTerm <TermSet>(web, modelTerm, set, termStore, parser, scope); modelTerm.Id = returnTuple.Item1; parser = returnTuple.Item2; } else { modelTerm.Id = term.Id; } } else { modelTerm.Id = term.Id; } } else { var returnTuple = CreateTerm <TermSet>(web, modelTerm, set, termStore, parser, scope); modelTerm.Id = returnTuple.Item1; parser = returnTuple.Item2; } } else { var returnTuple = CreateTerm <TermSet>(web, modelTerm, set, termStore, parser, scope); modelTerm.Id = returnTuple.Item1; parser = returnTuple.Item2; } } // do we need custom sorting? if (modelTermSet.Terms.Any(t => t.CustomSortOrder > -1)) { var sortedTerms = modelTermSet.Terms.OrderBy(t => t.CustomSortOrder); var customSortString = sortedTerms.Aggregate(string.Empty, (a, i) => a + i.Id.ToString() + ":"); customSortString = customSortString.TrimEnd(new[] { ':' }); set.CustomSortOrder = customSortString; termStore.CommitAll(); web.Context.ExecuteQueryRetry(); } } #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) { currentFileIndex++; WriteMessage($"File|{file.Src}|{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, file.Src, folderName)) { // add log message scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_Files_SkipFileUpload, file.Src, folderName); continue; } var folder = web.EnsureFolderPath(folderName); var checkedOut = false; var 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 !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.ParseString(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)) { // 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.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.Load(web.SiteUsers); web.Context.ExecuteQueryRetry(); 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); } //sorting groups with respect to possible dependency through Owner property. Groups that are owners of other groups must be processed prior owned groups. for (int i = 0; i < siteSecurity.SiteGroups.Count; i++) { var currentGroup = siteSecurity.SiteGroups[i]; string currentGroupOwner = currentGroup.Owner; string currentGroupTitle = parser.ParseString(currentGroup.Title); if (currentGroupOwner != "SHAREPOINT\\system" && currentGroupOwner != currentGroupTitle && !(currentGroupOwner.StartsWith("{{associated") && currentGroupOwner.EndsWith("group}}"))) { for (int j = i + 1; j < siteSecurity.SiteGroups.Count; j++) { if (siteSecurity.SiteGroups[j].Title == currentGroupOwner) { siteSecurity.SiteGroups.Insert(i, siteSecurity.SiteGroups[j]); siteSecurity.SiteGroups.RemoveAt(j); i--; break; } } } } 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); bool descriptionHasHtml = HttpUtility.HtmlEncode(parsedGroupDescription) != parsedGroupDescription; 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; group.OnlyAllowMembersViewMembership = siteGroup.OnlyAllowMembersViewMembership; group.RequestToJoinLeaveEmailSetting = siteGroup.RequestToJoinLeaveEmailSetting; 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)); if (descriptionHasHtml) { 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 isDirty = false; if (descriptionHasHtml) { 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(); isDirty = true; } } else { 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.OnlyAllowMembersViewMembership != siteGroup.OnlyAllowMembersViewMembership) { group.OnlyAllowMembersViewMembership = siteGroup.OnlyAllowMembersViewMembership; isDirty = true; } if (!String.IsNullOrEmpty(group.RequestToJoinLeaveEmailSetting) && group.RequestToJoinLeaveEmailSetting != siteGroup.RequestToJoinLeaveEmailSetting) { group.RequestToJoinLeaveEmailSetting = siteGroup.RequestToJoinLeaveEmailSetting; 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); 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 siteRoleDefinition = roleDefinitions.FirstOrDefault(erd => erd.Name == parser.ParseString(templateRoleDefinition.Name)); if (siteRoleDefinition == null) { scope.LogDebug("Creating 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; 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 != 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 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) { if (!roleAssignment.Remove) { var roleDefinition = webRoleDefinitions.FirstOrDefault(r => r.Name == parser.ParseString(roleAssignment.RoleDefinition)); 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); 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 == roleAssignment.RoleDefinition); if (binding != null) { assignmentForPrincipal.DeleteObject(); web.Context.ExecuteQueryRetry(); break; } } } } } } } return(parser); }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { web.Context.Load(web.RegionalSettings); web.Context.Load(web.RegionalSettings.TimeZone, tz => tz.Id); web.Context.ExecuteQueryRetry(); var isDirty = false; if (web.RegionalSettings.AdjustHijriDays != template.RegionalSettings.AdjustHijriDays) { web.RegionalSettings.AdjustHijriDays = Convert.ToInt16(template.RegionalSettings.AdjustHijriDays); isDirty = true; } if (web.RegionalSettings.AlternateCalendarType != (short)template.RegionalSettings.AlternateCalendarType) { web.RegionalSettings.AlternateCalendarType = (short)template.RegionalSettings.AlternateCalendarType; isDirty = true; } if (web.RegionalSettings.CalendarType != (short)template.RegionalSettings.CalendarType) { web.RegionalSettings.CalendarType = (short)template.RegionalSettings.CalendarType; isDirty = true; } if (web.RegionalSettings.Collation != Convert.ToInt16(template.RegionalSettings.Collation)) { web.RegionalSettings.Collation = Convert.ToInt16(template.RegionalSettings.Collation); isDirty = true; } if (web.RegionalSettings.FirstDayOfWeek != (uint)template.RegionalSettings.FirstDayOfWeek) { web.RegionalSettings.FirstDayOfWeek = (uint)template.RegionalSettings.FirstDayOfWeek; isDirty = true; } if (web.RegionalSettings.FirstWeekOfYear != Convert.ToInt16(template.RegionalSettings.FirstWeekOfYear)) { web.RegionalSettings.FirstWeekOfYear = Convert.ToInt16(template.RegionalSettings.FirstWeekOfYear); isDirty = true; } if (template.RegionalSettings.LocaleId > 0 && (web.RegionalSettings.LocaleId != Convert.ToUInt32(template.RegionalSettings.LocaleId))) { web.RegionalSettings.LocaleId = Convert.ToUInt32(template.RegionalSettings.LocaleId); isDirty = true; } if (web.RegionalSettings.ShowWeeks != template.RegionalSettings.ShowWeeks) { web.RegionalSettings.ShowWeeks = template.RegionalSettings.ShowWeeks; isDirty = true; } if (web.RegionalSettings.Time24 != template.RegionalSettings.Time24) { web.RegionalSettings.Time24 = template.RegionalSettings.Time24; isDirty = true; } if (template.RegionalSettings.TimeZone != 0 && (web.RegionalSettings.TimeZone.Id != template.RegionalSettings.TimeZone)) { web.RegionalSettings.TimeZone = web.RegionalSettings.TimeZones.GetById(template.RegionalSettings.TimeZone); isDirty = true; } if (web.RegionalSettings.WorkDayEndHour != (short)template.RegionalSettings.WorkDayEndHour) { web.RegionalSettings.WorkDayEndHour = (short)template.RegionalSettings.WorkDayEndHour; isDirty = true; } if (template.RegionalSettings.WorkDays > 0 && (web.RegionalSettings.WorkDays != Convert.ToInt16(template.RegionalSettings.WorkDays))) { web.RegionalSettings.WorkDays = Convert.ToInt16(template.RegionalSettings.WorkDays); isDirty = true; } if (web.RegionalSettings.WorkDayStartHour != (short)template.RegionalSettings.WorkDayStartHour) { web.RegionalSettings.WorkDayStartHour = (short)template.RegionalSettings.WorkDayStartHour; isDirty = true; } if (isDirty) { web.RegionalSettings.Update(); web.Context.ExecuteQueryRetry(); } } return(parser); }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { if (template.Footer != null) { web.EnsureProperty(w => w.ServerRelativeUrl); web.FooterEnabled = template.Footer.Enabled; web.Update(); web.Context.ExecuteQueryRetry(); if (web.FooterEnabled) { var structureString = web.ExecuteGet($"/_api/navigation/MenuState?menuNodeKey='{Constants.SITEFOOTER_NODEKEY}'").GetAwaiter().GetResult(); var menuState = JsonConvert.DeserializeObject <MenuState>(structureString); if (menuState.StartingNodeKey == null) { var now = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss:Z"); web.ExecutePost($"/_api/navigation/SaveMenuState", $@"{{ ""menuState"":{{ ""Version"":""{now}"",""StartingNodeTitle"":""3a94b35f-030b-468e-80e3-b75ee84ae0ad"",""SPSitePrefix"":""/"",""SPWebPrefix"":""{web.ServerRelativeUrl}"",""FriendlyUrlPrefix"":"""",""SimpleUrl"":"""",""Nodes"":[]}}}}").GetAwaiter().GetResult(); structureString = web.ExecuteGet($"/_api/navigation/MenuState?menuNodeKey='{Constants.SITEFOOTER_NODEKEY}'").GetAwaiter().GetResult(); menuState = JsonConvert.DeserializeObject <MenuState>(structureString); } var n1 = web.Navigation.GetNodeById(Convert.ToInt32(menuState.StartingNodeKey)); web.Context.Load(n1); web.Context.ExecuteQueryRetry(); web.Context.Load(n1, n => n.Children.IncludeWithDefaultProperties()); web.Context.ExecuteQueryRetry(); var menuNode = n1.Children.FirstOrDefault(n => n.Title == Constants.SITEFOOTER_MENUNODEKEY); if (menuNode != null) { if (template.Footer.RemoveExistingNodes == true) { menuNode.DeleteObject(); web.Context.ExecuteQueryRetry(); menuNode = n1.Children.Add(new NavigationNodeCreationInformation() { Title = Constants.SITEFOOTER_MENUNODEKEY }); } } else { menuNode = n1.Children.Add(new NavigationNodeCreationInformation() { Title = Constants.SITEFOOTER_MENUNODEKEY }); } foreach (var footerLink in template.Footer.FooterLinks) { menuNode.Children.Add(new NavigationNodeCreationInformation() { Url = parser.ParseString(footerLink.Url), Title = parser.ParseString(footerLink.DisplayName) }); } if (web.Context.PendingRequestCount() > 0) { web.Context.ExecuteQueryRetry(); } var logoNode = n1.Children.FirstOrDefault(n => n.Title == Constants.SITEFOOTER_LOGONODEKEY); if (logoNode != null) { if (string.IsNullOrEmpty(template.Footer.Logo)) { // remove the logo logoNode.DeleteObject(); } else { logoNode.Url = parser.ParseString(template.Footer.Logo); } } else { if (!string.IsNullOrEmpty(template.Footer.Logo)) { logoNode = n1.Children.Add(new NavigationNodeCreationInformation() { Title = Constants.SITEFOOTER_LOGONODEKEY, Url = parser.ParseString(template.Footer.Logo) }); } } if (web.Context.PendingRequestCount() > 0) { web.Context.ExecuteQueryRetry(); } var titleNode = n1.Children.FirstOrDefault(n => n.Title == Constants.SITEFOOTER_TITLENODEKEY); if (titleNode != null) { titleNode.EnsureProperty(n => n.Children); if (string.IsNullOrEmpty(template.Footer.Name)) { // remove the title titleNode.DeleteObject(); } else { titleNode.Children[0].Title = template.Footer.Name; titleNode.Update(); } } else { if (!string.IsNullOrEmpty(template.Footer.Name)) { titleNode = n1.Children.Add(new NavigationNodeCreationInformation() { Title = Constants.SITEFOOTER_TITLENODEKEY }); titleNode.Children.Add(new NavigationNodeCreationInformation() { Title = template.Footer.Name }); } } if (web.Context.PendingRequestCount() > 0) { web.Context.ExecuteQueryRetry(); } } } } return(parser); }
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); }
private TokenParser ApplySubSiteTemplates(ProvisioningHierarchy hierarchy, TokenParser tokenParser, Model.SiteCollection sitecollection, ClientContext siteContext, Web web, TeamNoGroupSubSite subSiteObject, ProvisioningTemplateApplyingInformation provisioningTemplateApplyingInformation) { var url = tokenParser.ParseString(subSiteObject.Url); var subweb = web.Webs.FirstOrDefault(t => t.ServerRelativeUrl.Equals(UrlUtility.Combine(web.ServerRelativeUrl, "/", url.Trim(new char[] { '/' })))); foreach (var templateRef in subSiteObject.Templates) { var provisioningTemplate = hierarchy.Templates.FirstOrDefault(t => t.Id == templateRef); if (provisioningTemplate != null) { provisioningTemplate.Connector = hierarchy.Connector; if (tokenParser == null) { tokenParser = new TokenParser(subweb, provisioningTemplate); } else { tokenParser.Rebase(subweb, provisioningTemplate, provisioningTemplateApplyingInformation); } new SiteToTemplateConversion().ApplyRemoteTemplate(subweb, provisioningTemplate, provisioningTemplateApplyingInformation, true, tokenParser); } else { WriteMessage($"Referenced template ID {templateRef} not found", ProvisioningMessageType.Error); } } if (subSiteObject.Sites.Any()) { foreach (var subsubSite in subSiteObject.Sites) { var subsubSiteObject = (TeamNoGroupSubSite)subsubSite; tokenParser = ApplySubSiteTemplates(hierarchy, tokenParser, sitecollection, siteContext, subweb, subsubSiteObject, provisioningTemplateApplyingInformation); } } return(tokenParser); }
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, 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); // 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) { 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) { // skip read only fields continue; } if (dataField != null) { if (dataValue.Value == null) { if (dataField.FieldTypeKind == FieldType.Invalid) { updateValues.Add(new FieldUpdateValue(dataValue.Key, null, dataField.TypeAsString)); } else { updateValues.Add(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; } } 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(); var itemId = listitem.Id; 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) { // This handler only extracts contents and adds them to the Files and Pages collection. return(parser); }
public abstract TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation);
public override bool WillProvision(Web web, ProvisioningTemplate template, ProvisioningTemplateApplyingInformation applyingInformation) { return(template.WebSettings != null); }
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; if (!String.IsNullOrEmpty(template.SearchSettings)) { site.SetSearchConfiguration(template.SearchSettings); } } 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 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"); } var availableWebTemplates = template.Publishing.AvailableWebTemplates.Select(t => new WebTemplateEntity() { LanguageCode = t.LanguageCode.ToString(), TemplateName = t.TemplateName }).ToList(); if (availableWebTemplates.Any()) { web.SetAvailableWebTemplates(availableWebTemplates); } var availablePageLayouts = template.Publishing.PageLayouts.Select(p => p.Path); if (availablePageLayouts.Any()) { web.SetAvailablePageLayouts(site.RootWeb, availablePageLayouts); } 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(CoreResources.Provisioning_ObjectHandlers_RetrieveTemplateInfo)) //{ } 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)) { // 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() && !applyingInformation.ProvisionFieldsToSubWebs) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Fields_Context_web_is_subweb__skipping_site_columns); WriteMessage("This template contains fields and you are provisioning to a subweb. If you still want to provision these fields, set the ProvisionFieldsToSubWebs property to true.", ProvisioningMessageType.Warning); 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 .Select(fld => new { Field = fld, FieldRef = (string)XElement.Parse(parser.ParseString(fld.SchemaXml, "~sitecollection", "~site")).Attribute("FieldRef"), Step = fld.GetFieldProvisioningStep(parser) }) .Where(fldData => fldData.Step == _step) // Only include fields related to the current step .OrderBy(fldData => fldData.FieldRef) // Ensure fields having fieldRef are handled after. This ensure lookups are created before dependent lookups .Select(fldData => fldData.Field) .ToArray(); var currentFieldIndex = 0; foreach (var field in fields) { currentFieldIndex++; var fieldSchemaElement = XElement.Parse(parser.ParseString(field.SchemaXml, "~sitecollection", "~site")); var fieldId = fieldSchemaElement.Attribute("ID").Value; var fieldInternalName = (string)fieldSchemaElement.Attribute("InternalName") != null ? (string)fieldSchemaElement.Attribute("InternalName") : ""; WriteMessage($"Field|{(!string.IsNullOrWhiteSpace(fieldInternalName) ? fieldInternalName : fieldId)}|{currentFieldIndex}|{fields.Length}", ProvisioningMessageType.Progress); if (!existingFieldIds.Contains(Guid.Parse(fieldId))) { try { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Fields_Adding_field__0__to_site, fieldId); CreateField(web, fieldSchemaElement, 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, fieldSchemaElement, 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; } } } } WriteMessage($"Done processing fields", ProvisioningMessageType.Completed); return(parser); }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { web.EnsureProperty(w => w.Url); using (var scope = new PnPMonitoredScope(this.Name)) { if (template.Tenant != null) { using (var tenantContext = web.Context.Clone(web.GetTenantAdministrationUrl())) { var tenant = new Tenant(tenantContext); TenantHelper.ProcessCdns(tenant, template.Tenant, parser, scope, MessagesDelegate); parser = TenantHelper.ProcessApps(tenant, template.Tenant, template.Connector, parser, scope, ApplyConfiguration.FromApplyingInformation(applyingInformation), MessagesDelegate); try { parser = TenantHelper.ProcessWebApiPermissions(tenant, template.Tenant, parser, scope, MessagesDelegate); } catch (ServerUnauthorizedAccessException ex) { scope.LogError(ex.Message); } parser = TenantHelper.ProcessSiteScripts(tenant, template.Tenant, template.Connector, parser, scope, MessagesDelegate); parser = TenantHelper.ProcessSiteDesigns(tenant, template.Tenant, parser, scope, MessagesDelegate); parser = TenantHelper.ProcessStorageEntities(tenant, template.Tenant, parser, scope, ApplyConfiguration.FromApplyingInformation(applyingInformation), MessagesDelegate); parser = TenantHelper.ProcessThemes(tenant, template.Tenant, parser, scope, MessagesDelegate); parser = TenantHelper.ProcessUserProfiles(tenant, template.Tenant, parser, scope, MessagesDelegate); parser = TenantHelper.ProcessSharingSettings(tenant, template.Tenant, parser, scope, MessagesDelegate); parser = TenantHelper.ProcessO365GroupSettings(tenant, template.Tenant, parser, scope, MessagesDelegate); } } } return(parser); }
/// <summary> /// Constructor /// </summary> /// <param name="web">A SharePoint site or subsite</param> /// <param name="template">a provisioning template</param> /// <param name="applyingInformation">The provisioning template applying information</param> public TokenParser(Web web, ProvisioningTemplate template, ProvisioningTemplateApplyingInformation applyingInformation) { web.EnsureProperties(w => w.ServerRelativeUrl, w => w.Url, w => w.Language); _web = web; _tokens = new List <TokenDefinition>(); _tokens.Add(new SiteCollectionToken(web)); _tokens.Add(new SiteCollectionIdToken(web)); _tokens.Add(new SiteCollectionIdEncodedToken(web)); _tokens.Add(new SiteToken(web)); _tokens.Add(new MasterPageCatalogToken(web)); _tokens.Add(new SiteCollectionTermStoreIdToken(web)); _tokens.Add(new KeywordsTermStoreIdToken(web)); _tokens.Add(new ThemeCatalogToken(web)); _tokens.Add(new WebNameToken(web)); _tokens.Add(new SiteIdToken(web)); _tokens.Add(new SiteIdEncodedToken(web)); _tokens.Add(new SiteOwnerToken(web)); _tokens.Add(new SiteTitleToken(web)); _tokens.Add(new AssociatedGroupToken(web, AssociatedGroupToken.AssociatedGroupType.owners)); _tokens.Add(new AssociatedGroupToken(web, AssociatedGroupToken.AssociatedGroupType.members)); _tokens.Add(new AssociatedGroupToken(web, AssociatedGroupToken.AssociatedGroupType.visitors)); _tokens.Add(new GuidToken(web)); _tokens.Add(new DateNowToken(web)); _tokens.Add(new CurrentUserIdToken(web)); _tokens.Add(new CurrentUserLoginNameToken(web)); _tokens.Add(new CurrentUserFullNameToken(web)); _tokens.Add(new AuthenticationRealmToken(web)); _tokens.Add(new HostUrlToken(web)); #if !ONPREMISES _tokens.Add(new SiteCollectionConnectedOffice365GroupId(web)); _tokens.Add(new EveryoneToken(web)); _tokens.Add(new EveryoneButExternalUsersToken(web)); #endif AddListTokens(web); AddContentTypeTokens(web); if (!_initializedFromHierarchy) { // Add parameters foreach (var parameter in template.Parameters) { _tokens.Add(new ParameterToken(web, parameter.Key, parameter.Value ?? string.Empty)); } } AddTermStoreTokens(web); #if !ONPREMISES AddSiteDesignTokens(web, applyingInformation); AddSiteScriptTokens(web, applyingInformation); AddStorageEntityTokens(web); #endif // Fields AddFieldTokens(web); // Handle resources AddResourceTokens(web, template.Localizations, template.Connector); // OOTB Roledefs AddRoleDefinitionTokens(web); // Groups AddGroupTokens(web); // AppPackages tokens #if !ONPREMISES AddAppPackagesTokens(web); #endif var sortedTokens = from t in _tokens orderby t.GetTokenLength() descending select t; _tokens = sortedTokens.ToList(); }
public override bool WillProvision(Web web, Model.ProvisioningTemplate template, ProvisioningTemplateApplyingInformation applyingInformation) { if (!_willProvision.HasValue) { _willProvision = template.TermGroups.Any(); } return(_willProvision.Value); }
public override void ProvisionObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateApplyingInformation applyingInformation) { Log.Info(Constants.LOGGING_SOURCE_FRAMEWORK_PROVISIONING, CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows); if (template.Lists.Any()) { var rootWeb = (web.Context as ClientContext).Site.RootWeb; if (!web.IsPropertyAvailable("ServerRelativeUrl")) { web.Context.Load(web, w => w.ServerRelativeUrl); web.Context.ExecuteQueryRetry(); } 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()) { // 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) { var listitemCI = new ListItemCreationInformation(); var listitem = list.AddItem(listitemCI); foreach (var dataValue in dataRow.Values) { Field dataField = fields.FirstOrDefault( f => f.InternalName == dataValue.Key.ToParsedString()); if (dataField != null) { String fieldValue = dataValue.Value.ToParsedString(); 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[dataValue.Key.ToParsedString()] = geolocationValue; } else { listitem[dataValue.Key.ToParsedString()] = fieldValue; } break; case FieldType.Lookup: // FieldLookupValue - Expected format: LookupID var lookupValue = new FieldLookupValue { LookupId = Int32.Parse(fieldValue), }; listitem[dataValue.Key.ToParsedString()] = 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[dataValue.Key.ToParsedString()] = 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[dataValue.Key.ToParsedString()] = userValue; } else { listitem[dataValue.Key.ToParsedString()] = fieldValue; } break; default: listitem[dataValue.Key.ToParsedString()] = fieldValue; break; } } listitem.Update(); } web.Context.ExecuteQueryRetry(); // TODO: Run in batches? } } } #endregion } }
public abstract bool WillProvision(Web web, ProvisioningTemplate template, ProvisioningTemplateApplyingInformation applyingInformation);
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { // Get a reference to infrastructural services WorkflowServicesManager servicesManager = null; try { servicesManager = new WorkflowServicesManager(web.Context, web); } catch (ServerException) { // If there is no workflow service present in the farm this method will throw an error. // Swallow the exception } if (servicesManager != null) { var deploymentService = servicesManager.GetWorkflowDeploymentService(); var subscriptionService = servicesManager.GetWorkflowSubscriptionService(); // Pre-load useful properties web.EnsureProperty(w => w.Id); // Provision Workflow Definitions foreach (var templateDefinition in template.Workflows.WorkflowDefinitions) { // Load the Workflow Definition XAML Stream xamlStream = template.Connector.GetFileStream(templateDefinition.XamlPath); XElement xaml = XElement.Load(xamlStream); int retryCount = 5; int retryAttempts = 1; int delay = 2000; while (retryAttempts <= retryCount) { try { var workflowDefinition = deploymentService.GetDefinition(templateDefinition.Id); web.Context.Load(workflowDefinition); web.Context.ExecuteQueryRetry(); // If Definition does not exist, create it // Prevent an exception if already exists if (workflowDefinition.ServerObjectIsNull()) { // Create the WorkflowDefinition instance workflowDefinition = new Microsoft.SharePoint.Client.WorkflowServices.WorkflowDefinition(web.Context) { AssociationUrl = templateDefinition.AssociationUrl, Description = templateDefinition.Description, DisplayName = templateDefinition.DisplayName, FormField = templateDefinition.FormField, DraftVersion = templateDefinition.DraftVersion, Id = templateDefinition.Id, InitiationUrl = templateDefinition.InitiationUrl, RequiresAssociationForm = templateDefinition.RequiresAssociationForm, RequiresInitiationForm = templateDefinition.RequiresInitiationForm, RestrictToScope = parser.ParseString(templateDefinition.RestrictToScope), RestrictToType = templateDefinition.RestrictToType != "Universal" ? templateDefinition.RestrictToType : null, Xaml = parser.ParseXmlString(xaml.ToString()), }; // Save the Workflow Definition var newDefinition = deploymentService.SaveDefinition(workflowDefinition); web.Context.ExecuteQueryRetry(); // Let's publish the Workflow Definition, if needed if (templateDefinition.Published) { deploymentService.PublishDefinition(newDefinition.Value); web.Context.ExecuteQueryRetry(); } } else { // Otherwise update the XAML definition workflowDefinition.AssociationUrl = templateDefinition.AssociationUrl; workflowDefinition.Description = templateDefinition.Description; workflowDefinition.DisplayName = templateDefinition.DisplayName; workflowDefinition.FormField = templateDefinition.FormField; workflowDefinition.DraftVersion = templateDefinition.DraftVersion; workflowDefinition.InitiationUrl = templateDefinition.InitiationUrl; workflowDefinition.RequiresAssociationForm = templateDefinition.RequiresAssociationForm; workflowDefinition.RequiresInitiationForm = templateDefinition.RequiresInitiationForm; workflowDefinition.RestrictToScope = parser.ParseString(templateDefinition.RestrictToScope); workflowDefinition.RestrictToType = templateDefinition.RestrictToType != "Universal" ? templateDefinition.RestrictToType : null; workflowDefinition.Xaml = parser.ParseXmlString(xaml.ToString()); var updatedDefinition = deploymentService.SaveDefinition(workflowDefinition); web.Context.ExecuteQueryRetry(); // Let's publish the Workflow Definition, if needed if (templateDefinition.Published) { deploymentService.PublishDefinition(updatedDefinition.Value); web.Context.ExecuteQueryRetry(); } } // If we are here, we have the workflow definition // and we did not have any exception. // Thus, we can exit from the loop break; } catch (Exception ex) { // check exception is due to connection closed issue if (ex is ServerException && ((ServerException)ex).ServerErrorCode == -2130575223 && ((ServerException)ex).ServerErrorTypeName.Equals("Microsoft.SharePoint.SPException", StringComparison.InvariantCultureIgnoreCase) && ((ServerException)ex).Message.Contains("A connection that was expected to be kept alive was closed by the server.") ) { WriteMessage($"Connection closed whilst adding Workflow Definition, trying again in {delay}ms", ProvisioningMessageType.Warning); Thread.Sleep(delay); retryAttempts++; delay = delay * 2; // double delay for next retry } else { throw; } } } } // get existing subscriptions var existingWorkflowSubscriptions = web.GetWorkflowSubscriptions(); foreach (var subscription in template.Workflows.WorkflowSubscriptions) { Microsoft.SharePoint.Client.WorkflowServices.WorkflowSubscription workflowSubscription = null; // Check if the subscription already exists before adding it, and // if already exists a subscription with the same name and with the same DefinitionId, // it is a duplicate and we just need to update it string subscriptionName; if (subscription.PropertyDefinitions.TryGetValue("SharePointWorkflowContext.Subscription.Name", out subscriptionName) && existingWorkflowSubscriptions.Any(s => s.PropertyDefinitions["SharePointWorkflowContext.Subscription.Name"] == subscriptionName && s.DefinitionId == subscription.DefinitionId)) { // Thus, delete it before adding it again! WriteMessage($"Workflow Subscription '{subscription.Name}' already exists. It will be updated.", ProvisioningMessageType.Warning); workflowSubscription = existingWorkflowSubscriptions.FirstOrDefault((s => s.PropertyDefinitions["SharePointWorkflowContext.Subscription.Name"] == subscriptionName && s.DefinitionId == subscription.DefinitionId)); } if (workflowSubscription != null) { // Update The existing subscription instead of delete the existing one. // Only update the following properties workflowSubscription.Enabled = subscription.Enabled; workflowSubscription.EventTypes = subscription.EventTypes; workflowSubscription.ManualStartBypassesActivationLimit = subscription.ManualStartBypassesActivationLimit; workflowSubscription.StatusFieldName = subscription.StatusFieldName; } else { // Create the WorkflowDefinition instance workflowSubscription = new Microsoft.SharePoint.Client.WorkflowServices.WorkflowSubscription(web.Context) { DefinitionId = subscription.DefinitionId, Enabled = subscription.Enabled, EventSourceId = (!String.IsNullOrEmpty(subscription.EventSourceId)) ? Guid.Parse(parser.ParseString(subscription.EventSourceId)) : web.Id, EventTypes = subscription.EventTypes, #if !ONPREMISES ParentContentTypeId = subscription.ParentContentTypeId, #endif ManualStartBypassesActivationLimit = subscription.ManualStartBypassesActivationLimit, Name = subscription.Name, StatusFieldName = subscription.StatusFieldName, }; foreach (var propertyDefinition in subscription.PropertyDefinitions .Where(d => d.Key == "TaskListId" || d.Key == "HistoryListId" || d.Key == "SharePointWorkflowContext.Subscription.Id" || d.Key == "SharePointWorkflowContext.Subscription.Name" || d.Key == "CreatedBySPD" || d.Key == "StatusColumnCreated")) // If set to "0" the status column will be created automatically. { workflowSubscription.SetProperty(propertyDefinition.Key, parser.ParseString(propertyDefinition.Value)); } } if (!String.IsNullOrEmpty(subscription.ListId)) { // It is a List Workflow Guid targetListId = Guid.Parse(parser.ParseString(subscription.ListId)); subscriptionService.PublishSubscriptionForList(workflowSubscription, targetListId); } else { // It is a Site Workflow subscriptionService.PublishSubscription(workflowSubscription); } web.Context.ExecuteQueryRetry(); } } } return(parser); }
public override bool WillProvision(Tenant tenant, Model.ProvisioningHierarchy hierarchy, string sequenceId, ProvisioningTemplateApplyingInformation applyingInformation) { return(hierarchy.Sequences.Count > 0); }
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.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.Load(web.SiteUsers); web.Context.ExecuteQueryRetry(); 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) { 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); 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 siteRoleDefinition = roleDefinitions.FirstOrDefault(erd => erd.Name == parser.ParseString(templateRoleDefinition.Name)); if (siteRoleDefinition == null) { scope.LogDebug("Creating 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) { var roleDefinition = webRoleDefinitions.FirstOrDefault(r => r.Name == parser.ParseString(roleAssignment.RoleDefinition)); if (roleDefinition != null) { Principal principal = groups.FirstOrDefault(g => g.LoginName == parser.ParseString(roleAssignment.Principal)); if (principal == null) { var parsedUser = parser.ParseString(roleAssignment.Principal); if (parsedUser.Contains("#ext#")) { principal = web.SiteUsers.FirstOrDefault(u => u.LoginName.Equals(parsedUser)); if (principal == null) { scope.LogInfo($"Skipping external user {parsedUser}"); } } else { try { principal = web.EnsureUser(parsedUser); web.Context.ExecuteQueryRetry(); } catch (Exception ex) { scope.LogWarning(ex, "Failed to EnsureUser {0}", parsedUser); } } } 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); } } } } } return(parser); }
public override TokenParser ProvisionObjects(Tenant tenant, Model.ProvisioningHierarchy hierarchy, string sequenceId, TokenParser tokenParser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(CoreResources.Provisioning_ObjectHandlers_Provisioning)) { var sequence = hierarchy.Sequences.FirstOrDefault(s => s.ID == sequenceId); if (sequence != null) { var siteUrls = new Dictionary <Guid, string>(); TokenParser siteTokenParser = null; foreach (var sitecollection in sequence.SiteCollections) { ClientContext siteContext = null; switch (sitecollection) { case TeamSiteCollection t: { TeamSiteCollectionCreationInformation siteInfo = new TeamSiteCollectionCreationInformation() { Alias = tokenParser.ParseString(t.Alias), DisplayName = tokenParser.ParseString(t.Title), Description = tokenParser.ParseString(t.Description), Classification = tokenParser.ParseString(t.Classification), IsPublic = t.IsPublic }; var groupSiteInfo = Sites.SiteCollection.GetGroupInfoAsync(tenant.Context as ClientContext, siteInfo.Alias).GetAwaiter().GetResult(); if (groupSiteInfo == null) { WriteMessage($"Creating Team Site {siteInfo.Alias}", ProvisioningMessageType.Progress); siteContext = Sites.SiteCollection.Create(tenant.Context as ClientContext, siteInfo, applyingInformation.DelayAfterModernSiteCreation); } else { if (groupSiteInfo.ContainsKey("siteUrl")) { WriteMessage($"Using existing Team Site {siteInfo.Alias}", ProvisioningMessageType.Progress); siteContext = (tenant.Context as ClientContext).Clone(groupSiteInfo["siteUrl"], applyingInformation.AccessTokens); } } if (t.IsHubSite) { siteContext.Load(siteContext.Site, s => s.Id); siteContext.ExecuteQueryRetry(); RegisterAsHubSite(tenant, siteContext.Url, siteContext.Site.Id, t.HubSiteLogoUrl, t.HubSiteTitle, tokenParser); } if (!string.IsNullOrEmpty(t.Theme)) { var parsedTheme = tokenParser.ParseString(t.Theme); tenant.SetWebTheme(parsedTheme, siteContext.Url); tenant.Context.ExecuteQueryRetry(); } if (t.Teamify) { try { WriteMessage($"Teamifying the O365 group connected site at URL - {siteContext.Url}", ProvisioningMessageType.Progress); siteContext.TeamifyAsync().GetAwaiter().GetResult(); } catch (Exception ex) { WriteMessage($"Teamifying site at URL - {siteContext.Url} failed due to an exception:- {ex.Message}", ProvisioningMessageType.Warning); } } if (t.HideTeamify) { try { WriteMessage($"Teamify prompt is now hidden for site at URL - {siteContext.Url}", ProvisioningMessageType.Progress); siteContext.HideTeamifyPrompt().GetAwaiter().GetResult(); } catch (Exception ex) { WriteMessage($"Teamify prompt couldn't be hidden for site at URL - {siteContext.Url} due to an exception:- {ex.Message}", ProvisioningMessageType.Warning); } } siteUrls.Add(t.Id, siteContext.Url); if (!string.IsNullOrEmpty(t.ProvisioningId)) { _additionalTokens.Add(new SequenceSiteUrlUrlToken(null, t.ProvisioningId, siteContext.Url)); siteContext.Web.EnsureProperty(w => w.Id); _additionalTokens.Add(new SequenceSiteIdToken(null, t.ProvisioningId, siteContext.Web.Id)); siteContext.Site.EnsureProperties(s => s.Id, s => s.GroupId); _additionalTokens.Add(new SequenceSiteCollectionIdToken(null, t.ProvisioningId, siteContext.Site.Id)); _additionalTokens.Add(new SequenceSiteGroupIdToken(null, t.ProvisioningId, siteContext.Site.GroupId)); } break; } case CommunicationSiteCollection c: { var siteUrl = tokenParser.ParseString(c.Url); if (!siteUrl.StartsWith("https://", StringComparison.InvariantCultureIgnoreCase)) { var rootSiteUrl = tenant.GetRootSiteUrl(); tenant.Context.ExecuteQueryRetry(); siteUrl = UrlUtility.Combine(rootSiteUrl.Value, siteUrl); } CommunicationSiteCollectionCreationInformation siteInfo = new CommunicationSiteCollectionCreationInformation() { ShareByEmailEnabled = c.AllowFileSharingForGuestUsers, Classification = tokenParser.ParseString(c.Classification), Description = tokenParser.ParseString(c.Description), Lcid = (uint)c.Language, Owner = tokenParser.ParseString(c.Owner), Title = tokenParser.ParseString(c.Title), Url = siteUrl }; if (Guid.TryParse(c.SiteDesign, out Guid siteDesignId)) { siteInfo.SiteDesignId = siteDesignId; } else { if (!string.IsNullOrEmpty(c.SiteDesign)) { siteInfo.SiteDesign = (CommunicationSiteDesign)Enum.Parse(typeof(CommunicationSiteDesign), c.SiteDesign); } else { siteInfo.SiteDesign = CommunicationSiteDesign.Showcase; } } // check if site exists if (tenant.SiteExists(siteInfo.Url)) { WriteMessage($"Using existing Communications Site at {siteInfo.Url}", ProvisioningMessageType.Progress); siteContext = (tenant.Context as ClientContext).Clone(siteInfo.Url, applyingInformation.AccessTokens); } else { WriteMessage($"Creating Communications Site at {siteInfo.Url}", ProvisioningMessageType.Progress); siteContext = Sites.SiteCollection.Create(tenant.Context as ClientContext, siteInfo, applyingInformation.DelayAfterModernSiteCreation); } if (c.IsHubSite) { siteContext.Load(siteContext.Site, s => s.Id); siteContext.ExecuteQueryRetry(); RegisterAsHubSite(tenant, siteInfo.Url, siteContext.Site.Id, c.HubSiteLogoUrl, c.HubSiteTitle, tokenParser); } if (!string.IsNullOrEmpty(c.Theme)) { var parsedTheme = tokenParser.ParseString(c.Theme); tenant.SetWebTheme(parsedTheme, siteInfo.Url); tenant.Context.ExecuteQueryRetry(); } siteUrls.Add(c.Id, siteInfo.Url); if (!string.IsNullOrEmpty(c.ProvisioningId)) { _additionalTokens.Add(new SequenceSiteUrlUrlToken(null, c.ProvisioningId, siteInfo.Url)); siteContext.Web.EnsureProperty(w => w.Id); _additionalTokens.Add(new SequenceSiteIdToken(null, c.ProvisioningId, siteContext.Web.Id)); siteContext.Site.EnsureProperties(s => s.Id, s => s.GroupId); _additionalTokens.Add(new SequenceSiteCollectionIdToken(null, c.ProvisioningId, siteContext.Site.Id)); _additionalTokens.Add(new SequenceSiteGroupIdToken(null, c.ProvisioningId, siteContext.Site.GroupId)); } break; } case TeamNoGroupSiteCollection t: { var siteUrl = tokenParser.ParseString(t.Url); TeamNoGroupSiteCollectionCreationInformation siteInfo = new TeamNoGroupSiteCollectionCreationInformation() { Lcid = (uint)t.Language, Url = siteUrl, Title = tokenParser.ParseString(t.Title), Description = tokenParser.ParseString(t.Description), Owner = tokenParser.ParseString(t.Owner) }; if (tenant.SiteExists(siteUrl)) { WriteMessage($"Using existing Team Site at {siteUrl}", ProvisioningMessageType.Progress); siteContext = (tenant.Context as ClientContext).Clone(siteUrl, applyingInformation.AccessTokens); } else { WriteMessage($"Creating Team Site with no Office 365 group at {siteUrl}", ProvisioningMessageType.Progress); siteContext = Sites.SiteCollection.Create(tenant.Context as ClientContext, siteInfo, applyingInformation.DelayAfterModernSiteCreation); } if (t.IsHubSite) { siteContext.Load(siteContext.Site, s => s.Id); siteContext.ExecuteQueryRetry(); RegisterAsHubSite(tenant, siteContext.Url, siteContext.Site.Id, t.HubSiteLogoUrl, t.HubSiteTitle, tokenParser); } if (!string.IsNullOrEmpty(t.Theme)) { var parsedTheme = tokenParser.ParseString(t.Theme); tenant.SetWebTheme(parsedTheme, siteContext.Url); tenant.Context.ExecuteQueryRetry(); } siteUrls.Add(t.Id, siteContext.Url); if (!string.IsNullOrEmpty(t.ProvisioningId)) { _additionalTokens.Add(new SequenceSiteUrlUrlToken(null, t.ProvisioningId, siteContext.Url)); siteContext.Web.EnsureProperty(w => w.Id); _additionalTokens.Add(new SequenceSiteIdToken(null, t.ProvisioningId, siteContext.Web.Id)); siteContext.Site.EnsureProperties(s => s.Id, s => s.GroupId); _additionalTokens.Add(new SequenceSiteCollectionIdToken(null, t.ProvisioningId, siteContext.Site.Id)); _additionalTokens.Add(new SequenceSiteGroupIdToken(null, t.ProvisioningId, siteContext.Site.GroupId)); } break; } } var web = siteContext.Web; if (siteTokenParser == null) { siteTokenParser = new TokenParser(tenant, hierarchy, applyingInformation); foreach (var token in _additionalTokens) { siteTokenParser.AddToken(token); } } foreach (var subsite in sitecollection.Sites) { var subSiteObject = (TeamNoGroupSubSite)subsite; web.EnsureProperties(w => w.Webs.IncludeWithDefaultProperties(), w => w.ServerRelativeUrl); siteTokenParser = CreateSubSites(hierarchy, siteTokenParser, sitecollection, siteContext, web, subSiteObject); } siteTokenParser = null; } // System.Threading.Thread.Sleep(TimeSpan.FromMinutes(10)); WriteMessage("Applying templates", ProvisioningMessageType.Progress); var currentSite = ""; var provisioningTemplateApplyingInformation = new ProvisioningTemplateApplyingInformation(); provisioningTemplateApplyingInformation.AccessTokens = applyingInformation.AccessTokens; provisioningTemplateApplyingInformation.MessagesDelegate = applyingInformation.MessagesDelegate; provisioningTemplateApplyingInformation.ProgressDelegate = (string message, int step, int total) => { applyingInformation.ProgressDelegate?.Invoke($"{currentSite} : {message}", step, total); }; provisioningTemplateApplyingInformation.SiteProvisionedDelegate = applyingInformation.SiteProvisionedDelegate; foreach (var sitecollection in sequence.SiteCollections) { currentSite = sitecollection.ProvisioningId != null ? sitecollection.ProvisioningId : sitecollection.Title; siteUrls.TryGetValue(sitecollection.Id, out string siteUrl); if (siteUrl != null) { using (var clonedContext = tenant.Context.Clone(siteUrl, applyingInformation.AccessTokens)) { var web = clonedContext.Web; foreach (var templateRef in sitecollection.Templates) { var provisioningTemplate = hierarchy.Templates.FirstOrDefault(t => t.Id == templateRef); if (provisioningTemplate != null) { provisioningTemplate.Connector = hierarchy.Connector; //if (siteTokenParser == null) //{ siteTokenParser = new TokenParser(web, provisioningTemplate, applyingInformation); foreach (var token in _additionalTokens) { siteTokenParser.AddToken(token); } //} //else //{ // siteTokenParser.Rebase(web, provisioningTemplate); //} WriteMessage($"Applying Template", ProvisioningMessageType.Progress); new SiteToTemplateConversion().ApplyRemoteTemplate(web, provisioningTemplate, provisioningTemplateApplyingInformation, true, siteTokenParser); } else { WriteMessage($"Referenced template ID {templateRef} not found", ProvisioningMessageType.Error); } } if (siteTokenParser == null) { siteTokenParser = new TokenParser(tenant, hierarchy, applyingInformation); foreach (var token in _additionalTokens) { siteTokenParser.AddToken(token); } } foreach (var subsite in sitecollection.Sites) { var subSiteObject = (TeamNoGroupSubSite)subsite; web.EnsureProperties(w => w.Webs.IncludeWithDefaultProperties(), w => w.ServerRelativeUrl); siteTokenParser = ApplySubSiteTemplates(hierarchy, siteTokenParser, sitecollection, clonedContext, web, subSiteObject, provisioningTemplateApplyingInformation); } if (sitecollection.IsHubSite) { RESTUtilities.ExecuteGet(web, "/_api/web/hubsitedata(true)").GetAwaiter().GetResult(); } } } } } return(tokenParser); } }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { if (template.ComposedLook != null && !template.ComposedLook.Equals(ComposedLook.Empty)) { bool executeQueryNeeded = false; // Apply alternate CSS if (!string.IsNullOrEmpty(template.ComposedLook.AlternateCSS)) { var alternateCssUrl = parser.ParseString(template.ComposedLook.AlternateCSS); web.AlternateCssUrl = alternateCssUrl; web.Update(); executeQueryNeeded = true; } // Apply Site logo if (!string.IsNullOrEmpty(template.ComposedLook.SiteLogo)) { var siteLogoUrl = parser.ParseString(template.ComposedLook.SiteLogo); web.SiteLogoUrl = siteLogoUrl; web.Update(); executeQueryNeeded = true; } if (executeQueryNeeded) { web.Context.ExecuteQueryRetry(); } if (String.IsNullOrEmpty(template.ComposedLook.ColorFile) && String.IsNullOrEmpty(template.ComposedLook.FontFile) && String.IsNullOrEmpty(template.ComposedLook.BackgroundFile)) { // Apply OOB theme web.SetComposedLookByUrl(template.ComposedLook.Name); } else { // Apply custom theme string colorFile = null; if (!string.IsNullOrEmpty(template.ComposedLook.ColorFile)) { colorFile = parser.ParseString(template.ComposedLook.ColorFile); } string backgroundFile = null; if (!string.IsNullOrEmpty(template.ComposedLook.BackgroundFile)) { backgroundFile = parser.ParseString(template.ComposedLook.BackgroundFile); } string fontFile = null; if (!string.IsNullOrEmpty(template.ComposedLook.FontFile)) { fontFile = parser.ParseString(template.ComposedLook.FontFile); } string masterUrl = null; if (!string.IsNullOrEmpty(template.ComposedLook.MasterPage)) { masterUrl = parser.ParseString(template.ComposedLook.MasterPage); } web.CreateComposedLookByUrl(template.ComposedLook.Name, colorFile, fontFile, backgroundFile, masterUrl); web.SetComposedLookByUrl(template.ComposedLook.Name, colorFile, fontFile, backgroundFile, masterUrl); } } } return(parser); }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { if (template.WebSettings != null) { // Check if this is not a noscript site as we're not allowed to update some properties bool isNoScriptSite = web.IsNoScriptSite(); web.EnsureProperties( #if !SP2013 && !SP2016 w => w.NoCrawl, w => w.CommentsOnSitePagesDisabled, w => w.ExcludeFromOfflineClient, w => w.MembersCanShare, w => w.DisableFlows, w => w.DisableAppViews, w => w.HorizontalQuickLaunch, #if !SP2019 w => w.SearchScope, w => w.SearchBoxInNavBar, #endif #endif w => w.WebTemplate, w => w.HasUniqueRoleAssignments); var webSettings = template.WebSettings; // Since the IsSubSite function can trigger an executequery ensure it's called before any updates to the web object are done. if (!web.IsSubSite() || (web.IsSubSite() && web.HasUniqueRoleAssignments)) { String requestAccessEmailValue = parser.ParseString(webSettings.RequestAccessEmail); if (!String.IsNullOrEmpty(requestAccessEmailValue) && requestAccessEmailValue.Length >= 255) { requestAccessEmailValue = requestAccessEmailValue.Substring(0, 255); } if (!String.IsNullOrEmpty(requestAccessEmailValue)) { web.RequestAccessEmail = requestAccessEmailValue; web.Update(); web.Context.ExecuteQueryRetry(); } } #if !SP2013 && !SP2016 if (!isNoScriptSite) { web.NoCrawl = webSettings.NoCrawl; } else { scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_WebSettings_SkipNoCrawlUpdate); } if (web.CommentsOnSitePagesDisabled != webSettings.CommentsOnSitePagesDisabled) { web.CommentsOnSitePagesDisabled = webSettings.CommentsOnSitePagesDisabled; } if (web.ExcludeFromOfflineClient != webSettings.ExcludeFromOfflineClient) { web.ExcludeFromOfflineClient = webSettings.ExcludeFromOfflineClient; } if (web.MembersCanShare != webSettings.MembersCanShare) { web.MembersCanShare = webSettings.MembersCanShare; } if (web.DisableFlows != webSettings.DisableFlows) { web.DisableFlows = webSettings.DisableFlows; } if (web.DisableAppViews != webSettings.DisableAppViews) { web.DisableAppViews = webSettings.DisableAppViews; } if (web.HorizontalQuickLaunch != webSettings.HorizontalQuickLaunch) { web.HorizontalQuickLaunch = webSettings.HorizontalQuickLaunch; } #if !SP2019 if (web.SearchScope.ToString() != webSettings.SearchScope.ToString()) { web.SearchScope = (SearchScopeType)Enum.Parse(typeof(SearchScopeType), webSettings.SearchScope.ToString(), true); } if (web.SearchBoxInNavBar.ToString() != webSettings.SearchBoxInNavBar.ToString()) { web.SearchBoxInNavBar = (SearchBoxInNavBarType)Enum.Parse(typeof(SearchBoxInNavBarType), webSettings.SearchBoxInNavBar.ToString(), true); } if (!string.IsNullOrEmpty(webSettings.SearchCenterUrl) && web.GetWebSearchCenterUrl(true) != webSettings.SearchCenterUrl) { web.SetWebSearchCenterUrl(webSettings.SearchCenterUrl); } #endif #endif var masterUrl = parser.ParseString(webSettings.MasterPageUrl); if (!string.IsNullOrEmpty(masterUrl)) { if (!isNoScriptSite) { web.MasterUrl = masterUrl; } else { scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_WebSettings_SkipMasterPageUpdate); } } var customMasterUrl = parser.ParseString(webSettings.CustomMasterPageUrl); if (!string.IsNullOrEmpty(customMasterUrl)) { if (!isNoScriptSite) { web.CustomMasterUrl = customMasterUrl; } else { scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_WebSettings_SkipCustomMasterPageUpdate); } } if (webSettings.Title != null) { web.Title = parser.ParseString(webSettings.Title); } if (webSettings.Description != null) { web.Description = parser.ParseString(webSettings.Description); } if (webSettings.SiteLogo != null) { var logoUrl = parser.ParseString(webSettings.SiteLogo); if (template.BaseSiteTemplate == "SITEPAGEPUBLISHING#0" && web.WebTemplate == "GROUP") { // logo provisioning throws when applying across base template IDs; provisioning fails in this case // this is the error that is already (rightly so) shown beforehand in the console: WARNING: The source site from which the template was generated had a base template ID value of SITEPAGEPUBLISHING#0, while the current target site has a base template ID value of GROUP#0. This could cause potential issues while applying the template. WriteMessage("Applying site logo across base template IDs is not possible. Skipping site logo provisioning.", ProvisioningMessageType.Warning); } else // Modern site? Then we assume the SiteLogo is actually a filepath if (web.WebTemplate == "GROUP") { #if !ONPREMISES if (!string.IsNullOrEmpty(logoUrl) && !logoUrl.ToLower().Contains("_api/groupservice/getgroupimage")) { var fileBytes = ConnectorFileHelper.GetFileBytes(template.Connector, logoUrl); if (fileBytes != null && fileBytes.Length > 0) { #if !NETSTANDARD2_0 var mimeType = MimeMapping.GetMimeMapping(logoUrl); #else var mimeType = ""; var imgUrl = logoUrl; if (imgUrl.Contains("?")) { imgUrl = imgUrl.Split(new[] { '?' })[0]; } if (imgUrl.EndsWith(".gif", StringComparison.InvariantCultureIgnoreCase)) { mimeType = "image/gif"; } if (imgUrl.EndsWith(".png", StringComparison.InvariantCultureIgnoreCase)) { mimeType = "image/png"; } if (imgUrl.EndsWith(".jpg", StringComparison.InvariantCultureIgnoreCase)) { mimeType = "image/jpeg"; } #endif Sites.SiteCollection.SetGroupImageAsync((ClientContext)web.Context, fileBytes, mimeType).GetAwaiter().GetResult(); } } #endif } else { web.SiteLogoUrl = logoUrl; } } var welcomePage = parser.ParseString(webSettings.WelcomePage); if (!string.IsNullOrEmpty(welcomePage)) { web.RootFolder.WelcomePage = welcomePage; web.RootFolder.Update(); } if (webSettings.AlternateCSS != null) { web.AlternateCssUrl = parser.ParseString(webSettings.AlternateCSS); } // Tempory disabled as this change is a breaking change for folks that have not set this property in their provisioning templates //web.QuickLaunchEnabled = webSettings.QuickLaunchEnabled; web.Update(); web.Context.ExecuteQueryRetry(); #if !ONPREMISES if (webSettings.HubSiteUrl != null) { var hubsiteUrl = parser.ParseString(webSettings.HubSiteUrl); try { using (var tenantContext = web.Context.Clone(web.GetTenantAdministrationUrl(), applyingInformation.AccessTokens)) { var tenant = new Tenant(tenantContext); tenant.ConnectSiteToHubSite(web.Url, hubsiteUrl); tenantContext.ExecuteQueryRetry(); } } catch (Exception ex) { WriteMessage($"Hub site association failed: {ex.Message}", ProvisioningMessageType.Warning); } } #endif } } 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 = context.Site; // if this is a sub site then we're not enabling the site collection scoped custom actions if (!web.IsSubSite()) { var siteCustomActions = template.CustomActions.SiteCustomActions; ProvisionCustomActionImplementation(site, siteCustomActions, parser, scope); } var webCustomActions = template.CustomActions.WebCustomActions; ProvisionCustomActionImplementation(web, webCustomActions, parser, scope); // Switch parser context back to it's original context parser.Rebase(web); } return(parser); }