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 ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { var site = (web.Context as ClientContext).Site; try { var siteSearchSettings = site.GetSearchConfiguration(); if (!String.IsNullOrEmpty(siteSearchSettings)) { template.SiteSearchSettings = siteSearchSettings; } var webSearchSettings = web.GetSearchConfiguration(); if (!String.IsNullOrEmpty(webSearchSettings)) { template.WebSearchSettings = webSearchSettings; } } catch (ServerException) { // The search service is not necessarily configured // Swallow the exception } } return template; }
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 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 ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { web.Context.Load(web.RegionalSettings); web.Context.Load(web.RegionalSettings.TimeZone, tz => tz.Id); web.Context.ExecuteQueryRetry(); Model.RegionalSettings settings = new Model.RegionalSettings(); settings.AdjustHijriDays = web.RegionalSettings.AdjustHijriDays; settings.AlternateCalendarType = (CalendarType)web.RegionalSettings.AlternateCalendarType; settings.Collation = web.RegionalSettings.Collation; settings.FirstDayOfWeek = (DayOfWeek)web.RegionalSettings.FirstDayOfWeek; settings.FirstWeekOfYear = web.RegionalSettings.FirstWeekOfYear; settings.LocaleId = (int)web.RegionalSettings.LocaleId; settings.ShowWeeks = web.RegionalSettings.ShowWeeks; settings.Time24 = web.RegionalSettings.Time24; settings.TimeZone = web.RegionalSettings.TimeZone.Id; settings.WorkDayEndHour = (WorkHour)web.RegionalSettings.WorkDayEndHour; settings.WorkDays = web.RegionalSettings.WorkDays; settings.WorkDayStartHour = (WorkHour)web.RegionalSettings.WorkDayStartHour; template.RegionalSettings = settings; // If a base template is specified then use that one to "cleanup" the generated template model if (creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate); } } return template; }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { var 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; }
private static void LocalizeParts(Web web, TokenParser parser, string url, WebPartCollection webParts, PnPMonitoredScope scope) { if (CanUseAcceptLanguageHeaderForLocalization(web)) { var context = web.Context; var allParts = web.GetWebParts(parser.ParseString(url)).ToList(); foreach (var webPart in webParts) { #if !SP2016 var partOnPage = allParts.FirstOrDefault(w => w.ZoneId == webPart.Zone && w.WebPart.ZoneIndex == webPart.Order); #else var partOnPage = allParts.FirstOrDefault(w => w.WebPart.ZoneIndex == webPart.Order); #endif if (webPart.Title.ContainsResourceToken() && partOnPage != null) { var resourceValues = parser.GetResourceTokenResourceValues(webPart.Title); foreach (var resourceValue in resourceValues) { // Save property with correct locale on the request to make it stick // http://sadomovalex.blogspot.no/2015/09/localize-web-part-titles-via-client.html context.PendingRequest.RequestExecutor.WebRequest.Headers["Accept-Language"] = resourceValue.Item1; partOnPage.WebPart.Properties["Title"] = resourceValue.Item2; partOnPage.SaveWebPartChanges(); context.ExecuteQueryRetry(); } } } context.PendingRequest.RequestExecutor.WebRequest.Headers.Remove("Accept-Language"); } else { // warning scope.LogWarning(CoreResources.Provisioning_Extensions_WebPartLocalization_Skip); } }
internal void PersistFile(Web web, ProvisioningTemplateCreationInformation creationInfo, PnPMonitoredScope scope, string folderPath, string fileName, Boolean decodeFileName = false) { if (creationInfo.FileConnector != null) { SharePointConnector connector = new SharePointConnector(web.Context, web.Url, "dummy"); Uri u = new Uri(web.Url); if (folderPath.IndexOf(u.PathAndQuery, StringComparison.InvariantCultureIgnoreCase) > -1) { folderPath = folderPath.Replace(u.PathAndQuery, ""); } using (Stream s = connector.GetFileStream(fileName, folderPath)) { if (s != null) { creationInfo.FileConnector.SaveFileStream(decodeFileName ? HttpUtility.UrlDecode(fileName) : fileName, s); } } } else { WriteWarning("No connector present to persist homepage.", ProvisioningMessageType.Error); scope.LogError("No connector present to persist homepage"); } }
public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { web.Context.Load(web.RegionalSettings); web.Context.Load(web.RegionalSettings.TimeZone, tz => tz.Id); web.Context.ExecuteQueryRetry(); Model.RegionalSettings settings = new Model.RegionalSettings(); settings.AdjustHijriDays = web.RegionalSettings.AdjustHijriDays; settings.AlternateCalendarType = (CalendarType)web.RegionalSettings.AlternateCalendarType; settings.CalendarType = (CalendarType)web.RegionalSettings.CalendarType; settings.Collation = web.RegionalSettings.Collation; settings.FirstDayOfWeek = (DayOfWeek)web.RegionalSettings.FirstDayOfWeek; settings.FirstWeekOfYear = web.RegionalSettings.FirstWeekOfYear; settings.LocaleId = (int)web.RegionalSettings.LocaleId; settings.ShowWeeks = web.RegionalSettings.ShowWeeks; settings.Time24 = web.RegionalSettings.Time24; settings.TimeZone = web.RegionalSettings.TimeZone.Id; settings.WorkDayEndHour = (WorkHour)web.RegionalSettings.WorkDayEndHour; settings.WorkDays = web.RegionalSettings.WorkDays; settings.WorkDayStartHour = (WorkHour)web.RegionalSettings.WorkDayStartHour; template.RegionalSettings = settings; // We're not comparing regional settings with the value stored in the base template as base templates are always for the US locale (1033) } return template; }
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 override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { var lists = this.GetListsWithPages(template); template.Pages = new PageCollection(template); var homePageUrl = web.GetHomePageRelativeUrl(); foreach (var list in lists) { try { List splist = web.Lists.GetById(list.ID); web.Context.Load(splist); web.Context.ExecuteQueryRetry(); if (!creationInfo.ExecutePreProvisionEvent<ListInstance, List>(Handlers.Pages, template, list, null)) { continue; } var listItems = GetListPages(web, splist); var fileItems = listItems.AsEnumerable().Where(x => x.IsFile()); foreach (ListItem item in fileItems) { try { IPageModelProvider provider = GetProvider(item, homePageUrl, web, parser); if (null != provider) { provider.AddPage(item, template); } } catch (Exception ex) { var message = string.Format("Error in export page for list: {0}", list.ServerRelativeUrl); scope.LogError(ex, message); } } creationInfo.ExecutePostProvisionEvent<ListInstance, List>(Handlers.Pages, template, list, splist); } catch (Exception exception) { var message = string.Format("Error in export publishing page for list: {0}", list.ServerRelativeUrl); scope.LogError(exception, message); } } // Impossible to return all files in the site currently // If a base template is specified then use that one to "cleanup" the generated template model if (creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate); } } return template; }
public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { // Set default values for Template ID and Version template.Id = String.Format("TEMPLATE-{0:N}", Guid.NewGuid()).ToUpper(); template.Version = 1; template.BaseSiteTemplate = web.GetBaseTemplateId(); // Retrieve original Template ID and remove it from Property Bag Entries int provisioningTemplateIdIndex = template.PropertyBagEntries.FindIndex(f => f.Key.Equals("_PnP_ProvisioningTemplateId")); if (provisioningTemplateIdIndex > -1) { var templateId = template.PropertyBagEntries[provisioningTemplateIdIndex].Value; if (!String.IsNullOrEmpty(templateId)) { template.Id = templateId; } template.PropertyBagEntries.RemoveAt(provisioningTemplateIdIndex); } // Retrieve original Template Info and remove it from Property Bag Entries int provisioningTemplateInfoIndex = template.PropertyBagEntries.FindIndex(f => f.Key.Equals("_PnP_ProvisioningTemplateInfo")); if (provisioningTemplateInfoIndex > -1) { var jsonInfo = template.PropertyBagEntries[provisioningTemplateInfoIndex].Value; if (jsonInfo != null) { ProvisioningTemplateInfo info = JsonConvert.DeserializeObject<ProvisioningTemplateInfo>(jsonInfo); // Override any previously defined Template ID, Version, and SitePolicy // with the one stored in the Template Info, if any if (info != null) { if (!String.IsNullOrEmpty(info.TemplateId)) { template.Id = info.TemplateId; } if (!String.IsNullOrEmpty(info.TemplateSitePolicy)) { template.SitePolicy = info.TemplateSitePolicy; } if (info.TemplateVersion > 0) { template.Version = info.TemplateVersion; } } } template.PropertyBagEntries.RemoveAt(provisioningTemplateInfoIndex); } } return template; }
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 ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { // If a base template is specified then use that one to "cleanup" the generated template model if (creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate); } } return template; }
// This function will be triggered based on the schedule you have set for this WebJob public static void VerifyDocLib() { var url = ConfigurationManager.AppSettings["SpUrl"].ToString(); var user = ConfigurationManager.AppSettings["SpUserName"].ToString(); var pw = ConfigurationManager.AppSettings["SpPassword"].ToString(); using (PnPMonitoredScope p = new PnPMonitoredScope()) { p.LogInfo("Gathering connect info from web.config"); p.LogInfo("SharePoint url is " + url); p.LogInfo("SharePoint user is " + user); try { ClientContext cc = new ClientContext(url); cc.AuthenticationMode = ClientAuthenticationMode.Default; cc.Credentials = new SharePointOnlineCredentials(user, GetPassword(pw)); using (cc) { if (cc != null) { string listName = "Site Pages"; p.LogInfo("This is what a Monitored Scope log entry looks like in PNP, more to come as we try to validate a lists existence."); p.LogInfo("Connect to Sharepoint"); ListCollection lists = cc.Web.Lists; IEnumerable<List> results = cc.LoadQuery<List>(lists.Where(lst => lst.Title == listName)); p.LogInfo("Executing query to find the Site Pages library"); cc.ExecuteQuery(); p.LogInfo("Query Executed successfully."); List list = results.FirstOrDefault(); if (list == null) { p.LogError("Site Pages library not found."); } else { p.LogInfo("Site Pages library found."); ListItemCollection items = list.GetItems(new CamlQuery()); cc.Load(items, itms => itms.Include(item => item.DisplayName)); cc.ExecuteQueryRetry(); string pgs = "These pages were found, " + string.Join(", ", items.Select(x => x.DisplayName)); p.LogInfo(pgs); } } } } catch (System.Exception ex) { p.LogInfo("We had a problem: " + ex.Message); } } }
/// <summary> /// Method to Invoke Custom Extraction Handlers. /// </summary> /// <remarks> /// Ensure the ClientContext is not disposed in the custom provider. /// </remarks> /// <param name="ctx">Authenticated ClientContext that is passed to the custom provider.</param> /// <param name="handler">A custom Extensibility Provisioning Provider</param> /// <param name="template">ProvisioningTemplate that is passed to the custom provider</param> /// <param name="creationInformation">The Provisioning Template creation information object</param> /// <param name="scope">The PnPMonitoredScope of the current step in the pipeline</param> /// <exception cref="ExtensiblityPipelineException"></exception> /// <exception cref="ArgumentException">Provider.Assembly or Provider.Type is NullOrWhiteSpace></exception> /// <exception cref="ArgumentNullException">ClientContext is Null></exception> public ProvisioningTemplate ExecuteExtensibilityExtractionCallOut(ClientContext ctx, ExtensibilityHandler handler, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInformation, PnPMonitoredScope scope) { var _loggingSource = "OfficeDevPnP.Core.Framework.Provisioning.Extensibility.ExtensibilityManager.ExecuteCallout"; if (ctx == null) throw new ArgumentNullException(CoreResources.Provisioning_Extensibility_Pipeline_ClientCtxNull); if (string.IsNullOrWhiteSpace(handler.Assembly)) throw new ArgumentException(CoreResources.Provisioning_Extensibility_Pipeline_Missing_AssemblyName); if (string.IsNullOrWhiteSpace(handler.Type)) throw new ArgumentException(CoreResources.Provisioning_Extensibility_Pipeline_Missing_TypeName); ProvisioningTemplate parsedTemplate = null; try { var _instance = GetProviderInstance(handler); if (_instance is IProvisioningExtensibilityHandler) { Log.Info(_loggingSource, CoreResources.Provisioning_Extensibility_Pipeline_BeforeInvocation, handler.Assembly, handler.Type); parsedTemplate = (_instance as IProvisioningExtensibilityHandler).Extract(ctx, template, creationInformation, scope, handler.Configuration); Log.Info(_loggingSource, CoreResources.Provisioning_Extensibility_Pipeline_Success, handler.Assembly, handler.Type); } else { parsedTemplate = template; } } catch (Exception ex) { string _message = string.Format( CoreResources.Provisioning_Extensibility_Pipeline_Exception, handler.Assembly, handler.Type, ex); Log.Error(_loggingSource, _message); throw new ExtensiblityPipelineException(_message, ex); } return parsedTemplate; }
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 ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { var sitePolicyEntity = web.GetAppliedSitePolicy(); if (sitePolicyEntity != null) { template.SitePolicy = sitePolicyEntity.Name; } } return template; }
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 ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(CoreResources.Provisioning_ObjectHandlers_Pages)) { // Impossible to return all files in the site currently // If a base template is specified then use that one to "cleanup" the generated template model if (creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate); } } return template; }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(CoreResources.Provisioning_ObjectHandlers_SitePolicy)) { if (template.SitePolicy != null) { if (web.GetSitePolicyByName(template.SitePolicy) != null) // Site Policy Available? { web.ApplySitePolicy(template.SitePolicy); } } } return parser; }
private void MonitoredScope() { Log.LogLevel = LogLevel.Debug; var scope = new PnPMonitoredScope("PnP Sleeping Monitored Scope"); for (int i = 0; i < 3; i++) { //do a little looping and sleeping to show of the timer Task task = Task.Run(() => { SleepAndWake(i); }); } ViewBag.MonitoredScopeMessage = "Ok, I'm adding some entries to the Trace Log output."; }
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(); }
private void SleepAndWake(int taskNumber) { using (PnPMonitoredScope p = new PnPMonitoredScope(string.Format("PnP Sleeping Monitored Scope {0}", taskNumber))) { for (int i = 0; i < 10; i++) { p.LogInfo(string.Format("Starting sleep for 2 seconds, iteration {0}", i)); System.Threading.Thread.Sleep(2000); p.LogInfo("Ending sleep"); } } }
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; }
public void PnPMonitoredScopeNestingTest() { using (var ctx = TestCommon.CreateClientContext()) { using (var scope1 = new PnPMonitoredScope("1.0")) { Assert.IsTrue(scope1.CorrelationId != Guid.Empty); Assert.IsTrue(scope1.Parent == null); scope1.LogInfo("Logging from scope 1"); using (var scope1_1 = new PnPMonitoredScope("1.1")) { Assert.IsTrue(scope1_1.Parent != null); scope1_1.LogInfo("Logging from scope 1.1"); using (var scope1_1_1 = new PnPMonitoredScope("1.1.1")) { Assert.IsTrue(scope1_1_1.Parent != null && scope1_1_1.Parent != scope1); scope1_1_1.LogInfo("Logging from scope 1.1.1"); } using (var scope1_1_2 = new PnPMonitoredScope("1.1.2")) { Assert.IsTrue(scope1_1_2.Parent != null && scope1_1_2.Parent == scope1_1); using (var scope1_1_2_1 = new PnPMonitoredScope("1.1.2.1")) { Assert.IsTrue(scope1_1_2_1.Parent != null && scope1_1_2_1.Parent == scope1_1_2); } scope1_1_2.LogInfo("Logging from scope 1.1.2"); } } } using (var topScope2 = new PnPMonitoredScope("1.0")) { topScope2.LogInfo("Test"); } } }
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 ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { web.Context.Load(web, w => w.SupportedUILanguageIds); web.Context.ExecuteQuery(); foreach (var id in web.SupportedUILanguageIds) { template.SupportedUILanguages.Add(new SupportedUILanguage() { LCID = id }); } } return template; }
public static ObjectSecurity GetSecurity(this SecurableObject securable) { ObjectSecurity security = null; using (var scope = new PnPMonitoredScope("Get Security")) { var context = securable.Context as ClientContext; context.Load(securable, sec => sec.HasUniqueRoleAssignments); context.Load(context.Web, w => w.AssociatedMemberGroup.Title, w => w.AssociatedOwnerGroup.Title, w => w.AssociatedVisitorGroup.Title); var roleAssignments = context.LoadQuery(securable.RoleAssignments.Include( r => r.Member.LoginName, r => r.RoleDefinitionBindings.Include( rdb => rdb.Name, rdb => rdb.RoleTypeKind ))); context.ExecuteQueryRetry(); if (securable.HasUniqueRoleAssignments) { security = new ObjectSecurity(); foreach (var roleAssignment in roleAssignments) { if (roleAssignment.Member.LoginName != "Excel Services Viewers") { foreach (var roleDefinition in roleAssignment.RoleDefinitionBindings) { if (roleDefinition.RoleTypeKind != RoleType.Guest) { security.RoleAssignments.Add(new Model.RoleAssignment() { Principal = ReplaceGroupTokens(context.Web, roleAssignment.Member.LoginName), RoleDefinition = roleDefinition.Name }); } } } } } } return security; }
private ProvisioningTemplate GetFileContents(Web web, ProvisioningTemplate template, string welcomePageUrl, ProvisioningTemplateCreationInformation creationInfo, PnPMonitoredScope scope) { var homepageUrl = web.RootFolder.WelcomePage; if (string.IsNullOrEmpty(homepageUrl)) { homepageUrl = "Default.aspx"; } var fullUri = new Uri(UrlUtility.Combine(web.Url, homepageUrl)); var folderPath = fullUri.Segments.Take(fullUri.Segments.Count() - 1).ToArray().Aggregate((i, x) => i + x).TrimEnd('/'); var fileName = fullUri.Segments[fullUri.Segments.Count() - 1]; var webParts = web.GetWebParts(welcomePageUrl); var file = web.GetFileByServerRelativeUrl(welcomePageUrl); file.EnsureProperty(f => f.Level); var containerPath = folderPath.StartsWith(web.ServerRelativeUrl) && web.ServerRelativeUrl != "/" ? folderPath.Substring(web.ServerRelativeUrl.Length) : folderPath; var container = containerPath.Trim('/').Replace("%20", " ").Replace("/", "\\"); var homeFile = new Model.File() { Folder = Tokenize(folderPath, web.Url), Src = !string.IsNullOrEmpty(container) ? $"{container}\\{fileName}" : fileName, Overwrite = true, Level = (Model.FileLevel)Enum.Parse(typeof(Model.FileLevel), file.Level.ToString()) }; // Add field values to file RetrieveFieldValues(web, file, homeFile); // Add WebParts to file foreach (var webPart in webParts) { var webPartxml = TokenizeWebPartXml(web, web.GetWebPartXml(webPart.Id, welcomePageUrl)); Model.WebPart newWp = new Model.WebPart() { Title = webPart.WebPart.Title, Row = (uint)webPart.WebPart.ZoneIndex, Order = (uint)webPart.WebPart.ZoneIndex, Contents = webPartxml }; // As long as we've no CSOM library that has the ZoneID we can't use the version check as things don't compile... if (web.Context.HasMinimalServerLibraryVersion(Constants.MINIMUMZONEIDREQUIREDSERVERVERSION)) { newWp.Zone = webPart.ZoneId; } homeFile.WebParts.Add(newWp); } template.Files.Add(homeFile); // Persist file using connector if (creationInfo.PersistBrandingFiles) { PersistFile(web, creationInfo, scope, folderPath, fileName); } return(template); }
private Tuple <Guid, TokenParser> CreateTerm <T>(Web web, Model.Term modelTerm, TaxonomyItem parent, TermStore termStore, TokenParser parser, PnPMonitoredScope scope) where T : TaxonomyItem { Term term; if (modelTerm.Id == Guid.Empty) { modelTerm.Id = Guid.NewGuid(); } if (parent is Term) { var languages = termStore.DefaultLanguage; term = ((Term)parent).CreateTerm(parser.ParseString(modelTerm.Name), modelTerm.Language ?? termStore.DefaultLanguage, modelTerm.Id); } else { term = ((TermSet)parent).CreateTerm(parser.ParseString(modelTerm.Name), modelTerm.Language ?? termStore.DefaultLanguage, modelTerm.Id); } if (!String.IsNullOrEmpty(modelTerm.Description)) { term.SetDescription(modelTerm.Description, modelTerm.Language ?? termStore.DefaultLanguage); } if (!String.IsNullOrEmpty(modelTerm.Owner)) { term.Owner = modelTerm.Owner; } term.IsAvailableForTagging = modelTerm.IsAvailableForTagging; if (modelTerm.Properties.Any() || modelTerm.Labels.Any() || modelTerm.LocalProperties.Any()) { if (modelTerm.Labels.Any()) { foreach (var label in modelTerm.Labels) { if ((label.IsDefaultForLanguage && label.Language != termStore.DefaultLanguage) || label.IsDefaultForLanguage == false) { var l = term.CreateLabel(parser.ParseString(label.Value), label.Language, label.IsDefaultForLanguage); } else { scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_TermGroups_Skipping_label__0___label_is_to_set_to_default_for_language__1__while_the_default_termstore_language_is_also__1_, label.Value, label.Language); WriteWarning(string.Format(CoreResources.Provisioning_ObjectHandlers_TermGroups_Skipping_label__0___label_is_to_set_to_default_for_language__1__while_the_default_termstore_language_is_also__1_, label.Value, label.Language), ProvisioningMessageType.Warning); } } } if (modelTerm.Properties.Any()) { foreach (var property in modelTerm.Properties) { term.SetCustomProperty(parser.ParseString(property.Key), parser.ParseString(property.Value)); } } if (modelTerm.LocalProperties.Any()) { foreach (var property in modelTerm.LocalProperties) { term.SetLocalCustomProperty(parser.ParseString(property.Key), parser.ParseString(property.Value)); } } } termStore.CommitAll(); web.Context.Load(term); web.Context.ExecuteQueryRetry(); if (modelTerm.Terms.Any()) { foreach (var modelTermTerm in modelTerm.Terms) { web.Context.Load(term.Terms); web.Context.ExecuteQueryRetry(); var termTerms = term.Terms; if (termTerms.Any()) { var termTerm = termTerms.FirstOrDefault(t => t.Id == modelTermTerm.Id); if (termTerm == null) { termTerm = termTerms.FirstOrDefault(t => t.Name == modelTermTerm.Name); if (termTerm == null) { var returnTuple = CreateTerm <Term>(web, modelTermTerm, term, termStore, parser, scope); modelTermTerm.Id = returnTuple.Item1; parser = returnTuple.Item2; } else { modelTermTerm.Id = termTerm.Id; } } else { modelTermTerm.Id = termTerm.Id; } } else { var returnTuple = CreateTerm <Term>(web, modelTermTerm, term, termStore, parser, scope); modelTermTerm.Id = returnTuple.Item1; parser = returnTuple.Item2; } } if (modelTerm.Terms.Any(t => t.CustomSortOrder > -1)) { var sortedTerms = modelTerm.Terms.OrderBy(t => t.CustomSortOrder); var customSortString = sortedTerms.Aggregate(string.Empty, (a, i) => a + i.Id.ToString() + ":"); customSortString = customSortString.TrimEnd(new[] { ':' }); term.CustomSortOrder = customSortString; termStore.CommitAll(); } } return(Tuple.Create(modelTerm.Id, 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); }
private void DownLoadFile(SharePointConnector reader, SharePointConnector readerRoot, FileConnectorBase writer, string webUrl, string asset, PnPMonitoredScope scope) { // No file passed...leave if (String.IsNullOrEmpty(asset)) { return; } scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_DownLoadFile_Downloading_asset___0_, asset); ; SharePointConnector readerToUse; Model.File f = GetComposedLookFile(asset); // Strip the /sites/root part from /sites/root/lib/folder structure Uri u = new Uri(webUrl); if (f.Folder.IndexOf(u.PathAndQuery, StringComparison.InvariantCultureIgnoreCase) > -1) { f.Folder = f.Folder.Replace(u.PathAndQuery, ""); } // in case of a theme catalog we need to use the root site reader as that list only exists on root site level if (f.Folder.IndexOf("/_catalogs/theme", StringComparison.InvariantCultureIgnoreCase) > -1) { readerToUse = readerRoot; } else { readerToUse = reader; } using (Stream s = readerToUse.GetFileStream(f.Src, f.Folder)) { if (s != null) { writer.SaveFileStream(f.Src, s); } } }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { // 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); }
internal static void LocalizeNavigationNode(this Microsoft.SharePoint.Client.NavigationNode navigationNode, Web web, string token, TokenParser parser, PnPMonitoredScope scope) { if (CanUseAcceptLanguageHeaderForLocalization(web)) { web.EnsureProperties(w => w.Language, w => w.IsMultilingual, w => w.SupportedUILanguageIds); if (web.IsMultilingual) { var context = web.Context; var resourceValues = parser.GetResourceTokenResourceValues(token); foreach (var resourceValue in resourceValues) { var translationculture = new CultureInfo(resourceValue.Item1); if (web.SupportedUILanguageIds.Contains(translationculture.LCID)) { // Save property with correct locale on the request to make it stick // http://sadomovalex.blogspot.no/2015/09/localize-web-part-titles-via-client.html context.PendingRequest.RequestExecutor.WebRequest.Headers["Accept-Language"] = resourceValue.Item1; navigationNode.Title = resourceValue.Item2; navigationNode.Update(); context.ExecuteQueryRetry(); } } } else { scope.LogWarning(CoreResources.Provisioning_Extensions_NavigationLocalization_NoMUI_Skip); } } else { // warning scope.LogWarning(CoreResources.Provisioning_Extensions_NavigationLocalization_Skip); } }
internal static void LocalizeWebParts(this Page page, Web web, TokenParser parser, PnPMonitoredScope scope) { var url = page.Url; var webParts = page.WebParts; LocalizeParts(web, parser, url, webParts, scope); }
internal static void LocalizeWebParts(this File file, Web web, TokenParser parser, Microsoft.SharePoint.Client.File targetFile, PnPMonitoredScope scope) { var url = targetFile.ServerRelativeUrl; var webParts = file.WebParts; LocalizeParts(web, parser, url, webParts, scope); }
private bool PersistFile(Web web, ProvisioningTemplateCreationInformation creationInfo, PnPMonitoredScope scope, string serverRelativeUrl) { var success = false; if (creationInfo.PersistBrandingFiles) { if (creationInfo.FileConnector != null) { if (UrlUtility.IsIisVirtualDirectory(serverRelativeUrl)) { scope.LogWarning("File is not located in the content database. Not retrieving {0}", serverRelativeUrl); return(success); } try { var file = web.GetFileByServerRelativeUrl(serverRelativeUrl); string fileName = string.Empty; if (serverRelativeUrl.IndexOf("/") > -1) { fileName = serverRelativeUrl.Substring(serverRelativeUrl.LastIndexOf("/") + 1); } else { fileName = serverRelativeUrl; } web.Context.Load(file); web.Context.ExecuteQueryRetry(); ClientResult <Stream> stream = file.OpenBinaryStream(); web.Context.ExecuteQueryRetry(); var baseUri = new Uri(web.Url); var fullUri = new Uri(baseUri, file.ServerRelativeUrl); var folderPath = HttpUtility.UrlDecode(fullUri.Segments.Take(fullUri.Segments.Count() - 1).ToArray().Aggregate((i, x) => i + x).TrimEnd('/')); // Configure the filename to use fileName = HttpUtility.UrlDecode(fullUri.Segments[fullUri.Segments.Count() - 1]); // Build up a site relative container URL...might end up empty as well String container = HttpUtility.UrlDecode(folderPath.Replace(web.ServerRelativeUrl, "")).Trim('/').Replace("/", "\\"); using (Stream memStream = new MemoryStream()) { CopyStream(stream.Value, memStream); memStream.Position = 0; if (!string.IsNullOrEmpty(container)) { creationInfo.FileConnector.SaveFileStream(fileName, container, memStream); } else { creationInfo.FileConnector.SaveFileStream(fileName, memStream); } } success = true; } catch (ServerException ex1) { // If we are referring a file from a location outside of the current web or at a location where we cannot retrieve the file an exception is thrown. We swallow this exception. if (ex1.ServerErrorCode != -2147024809) { throw; } else { scope.LogWarning("File is not necessarily located in the current web. Not retrieving {0}", serverRelativeUrl); } } } else { WriteMessage("No connector present to persist site logo.", ProvisioningMessageType.Error); scope.LogError("No connector present to persist site logo"); } } else { success = true; } return(success); }
private static void AddUserToGroup(Web web, Group group, IEnumerable <User> members, PnPMonitoredScope scope, TokenParser parser) { if (members.Any()) { scope.LogDebug("Adding users to group {0}", group.Title); try { foreach (var user in members) { var parsedUserName = parser.ParseString(user.Name); scope.LogDebug("Adding user {0}", parsedUserName); if (parsedUserName.Contains("#ext#")) { var externalUser = web.SiteUsers.FirstOrDefault(u => u.LoginName.Equals(parsedUserName)); if (externalUser == null) { scope.LogInfo($"Skipping external user {parsedUserName}"); } else { group.Users.AddUser(externalUser); } } else { try { var existingUser = web.EnsureUser(parsedUserName); web.Context.ExecuteQueryRetry(); group.Users.AddUser(existingUser); } catch (Exception ex) { scope.LogWarning(ex, "Failed to EnsureUser {0}", parsedUserName); } } } web.Context.ExecuteQueryRetry(); } catch (Exception ex) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_SiteSecurity_Add_users_failed_for_group___0_____1_____2_, group.Title, ex.Message, ex.StackTrace); throw; } } }
private void ExtractMasterPagesAndPageLayouts(Web web, ProvisioningTemplate template, PnPMonitoredScope scope, ProvisioningTemplateCreationInformation creationInfo) { web.EnsureProperty(w => w.Url); String webApplicationUrl = GetWebApplicationUrl(web.Url); if (!String.IsNullOrEmpty(webApplicationUrl)) { // Get the Publishing Feature reference template ProvisioningTemplate publishingFeatureTemplate = GetPublishingFeatureBaseTemplate(); // Get a reference to the root folder of the master page gallery var gallery = web.GetCatalog(116); web.Context.Load(gallery, g => g.RootFolder); web.Context.ExecuteQueryRetry(); var masterPageGalleryFolder = gallery.RootFolder; // Load the files in the master page gallery web.Context.Load(masterPageGalleryFolder.Files); web.Context.ExecuteQueryRetry(); var sourceFiles = GetFiles(masterPageGalleryFolder).Where( f => f.Name.EndsWith(".aspx", StringComparison.InvariantCultureIgnoreCase) || f.Name.EndsWith(".html", StringComparison.InvariantCultureIgnoreCase) || f.Name.EndsWith(".master", StringComparison.InvariantCultureIgnoreCase)); /*var sourceFiles = masterPageGalleryFolder.Files.AsEnumerable().Where( * f => f.Name.EndsWith(".aspx", StringComparison.InvariantCultureIgnoreCase) || * f.Name.EndsWith(".html", StringComparison.InvariantCultureIgnoreCase) || * f.Name.EndsWith(".master", StringComparison.InvariantCultureIgnoreCase)); */ foreach (var file in sourceFiles) { if (file.ListItemAllFields.ServerObjectIsNull != null && !file.ListItemAllFields.ServerObjectIsNull.Value) { var listItem = file.EnsureProperty(f => f.ListItemAllFields); listItem.ContentType.EnsureProperties(ct => ct.Id, ct => ct.StringId); // Check if the content type is of type Master Page or Page Layout if (listItem.ContentType.StringId.StartsWith(MASTER_PAGE_CONTENT_TYPE_ID) || listItem.ContentType.StringId.StartsWith(PAGE_LAYOUT_CONTENT_TYPE_ID) || listItem.ContentType.StringId.StartsWith(ASP_NET_MASTER_PAGE_CONTENT_TYPE_ID) || listItem.ContentType.StringId.StartsWith(HTML_PAGE_LAYOUT_CONTENT_TYPE_ID)) { // Skip any .ASPX or .MASTER file related to an .HTML designer file if ((file.Name.EndsWith(".aspx", StringComparison.InvariantCultureIgnoreCase) && sourceFiles.Any(f => f.Name.Equals(file.Name.ToLower().Replace(".aspx", ".html"), StringComparison.InvariantCultureIgnoreCase))) || (file.Name.EndsWith(".master", StringComparison.InvariantCultureIgnoreCase) && sourceFiles.Any(f => f.Name.Equals(file.Name.ToLower().Replace(".master", ".html"), StringComparison.InvariantCultureIgnoreCase)))) { continue; } // If the file is a custom one, and not one native // and coming out from the publishing feature if (creationInfo.IncludeNativePublishingFiles || !IsPublishingFeatureNativeFile(publishingFeatureTemplate, file.Name)) { var fullUri = new Uri(UrlUtility.Combine(webApplicationUrl, file.ServerRelativeUrl)); var folderPath = fullUri.Segments.Take(fullUri.Segments.Count() - 1).ToArray().Aggregate((i, x) => i + x).TrimEnd('/'); var fileName = fullUri.Segments[fullUri.Segments.Count() - 1]; var publishingFile = new Model.File() { Folder = Tokenize(folderPath, web.Url), Src = HttpUtility.UrlDecode(fileName), Overwrite = true, }; // Add field values to file RetrieveFieldValues(web, file, publishingFile); // Add the file to the template template.Files.Add(publishingFile); // Persist file using connector, if needed if (creationInfo.PersistPublishingFiles) { PersistFile(web, creationInfo, scope, folderPath, fileName, true); } if (listItem.ContentType.StringId.StartsWith(MASTER_PAGE_CONTENT_TYPE_ID)) { scope.LogWarning(String.Format("The file \"{0}\" is a custom MasterPage. Accordingly to the PnP Guidance (http://aka.ms/o365pnpguidancemasterpages) you should try to avoid using custom MasterPages.", file.Name)); } } else { scope.LogWarning(String.Format("Skipping file \"{0}\" because it is native in the publishing feature.", file.Name)); } } } } } }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { var site = (web.Context as ClientContext).Site; var webFeatureActive = web.IsFeatureActive(PUBLISHING_FEATURE_WEB); var siteFeatureActive = site.IsFeatureActive(PUBLISHING_FEATURE_SITE); if (template.Publishing.AutoCheckRequirements == AutoCheckRequirementsOptions.SkipIfNotCompliant && !webFeatureActive) { scope.LogDebug("Publishing Feature (Web Scoped) not active. Skipping provisioning of Publishing settings"); return(parser); } else if (template.Publishing.AutoCheckRequirements == AutoCheckRequirementsOptions.MakeCompliant) { if (!siteFeatureActive) { scope.LogDebug("Making site compliant for publishing"); site.ActivateFeature(PUBLISHING_FEATURE_SITE); web.ActivateFeature(PUBLISHING_FEATURE_WEB); } else { if (!web.IsFeatureActive(PUBLISHING_FEATURE_WEB)) { scope.LogDebug("Making site compliant for publishing"); web.ActivateFeature(PUBLISHING_FEATURE_WEB); } } } else { throw new Exception("Publishing Feature not active. Provisioning failed"); } // Set allowed web templates var availableWebTemplates = template.Publishing.AvailableWebTemplates.Select(t => new WebTemplateEntity() { LanguageCode = t.LanguageCode.ToString(), TemplateName = t.TemplateName }).ToList(); if (availableWebTemplates.Any()) { web.SetAvailableWebTemplates(availableWebTemplates); } // Set allowed page layouts var availablePageLayouts = template.Publishing.PageLayouts.Select(p => p.Path); if (availablePageLayouts.Any()) { web.SetAvailablePageLayouts(site.RootWeb, availablePageLayouts); } // Set default page layout, if any var defaultPageLayout = template.Publishing.PageLayouts.FirstOrDefault(p => p.IsDefault); if (defaultPageLayout != null) { web.SetDefaultPageLayoutForSite(site.RootWeb, defaultPageLayout.Path); } if (template.Publishing.DesignPackage != null) { var package = template.Publishing.DesignPackage; var tempFileName = Path.Combine(Path.GetTempPath(), template.Connector.GetFilenamePart(package.DesignPackagePath)); scope.LogDebug("Saving {0} to temporary file: {1}", package.DesignPackagePath, tempFileName); using (var stream = template.Connector.GetFileStream(package.DesignPackagePath)) { using (var outstream = System.IO.File.Create(tempFileName)) { stream.CopyTo(outstream); } } scope.LogDebug("Installing design package"); site.InstallSolution(package.PackageGuid, tempFileName, package.MajorVersion, package.MinorVersion); System.IO.File.Delete(tempFileName); } return(parser); } }
internal static void LocalizeView(this Microsoft.SharePoint.Client.View view, Web web, string token, TokenParser parser, PnPMonitoredScope scope) { if (CanUseAcceptLanguageHeaderForLocalization(web)) { var context = web.Context; //preserve Default Language to set last since otherwise Entries in QuickLaunch can show wrong language web.EnsureProperties(w => w.Language, w => w.IsMultilingual, w => w.SupportedUILanguageIds); if (web.IsMultilingual) { //just update if web is multilingual var culture = new CultureInfo((int)web.Language); var resourceValues = parser.GetResourceTokenResourceValues(token); var defaultLanguageResource = resourceValues.FirstOrDefault(r => r.Item1.Equals(culture.Name, StringComparison.InvariantCultureIgnoreCase)); if (defaultLanguageResource != null) { foreach (var resourceValue in resourceValues.Where(r => !r.Item1.Equals(culture.Name, StringComparison.InvariantCultureIgnoreCase))) { var translationculture = new CultureInfo(resourceValue.Item1); if (web.SupportedUILanguageIds.Contains(translationculture.LCID)) { // Save property with correct locale on the request to make it stick // http://sadomovalex.blogspot.no/2015/09/localize-web-part-titles-via-client.html context.PendingRequest.RequestExecutor.WebRequest.Headers["Accept-Language"] = resourceValue.Item1; view.Title = resourceValue.Item2; view.Update(); context.ExecuteQueryRetry(); } } //Set for default Language of Web context.PendingRequest.RequestExecutor.WebRequest.Headers["Accept-Language"] = defaultLanguageResource.Item1; view.Title = defaultLanguageResource.Item2; view.Update(); context.ExecuteQueryRetry(); } else { //skip since default language of web is not contained in resource file scope.LogWarning(CoreResources.Provisioning_Extensions_ViewLocalization_DefaultLngMissing_Skip); } } else { //skip since web is not multilingual scope.LogWarning(CoreResources.Provisioning_Extensions_ViewLocalization_NoMUI_Skip); } } else { // warning scope.LogWarning(CoreResources.Provisioning_Extensions_ViewLocalization_Skip); } }
public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { // Load object if not there #if !CLIENTSDKV15 web.EnsureProperties(w => w.Url, w => w.MasterUrl, w => w.AlternateCssUrl, w => w.SiteLogoUrl); #else web.EnsureProperties(w => w.Url, w => w.MasterUrl); #endif // Information coming from the site template.ComposedLook.MasterPage = Tokenize(web.MasterUrl, web.Url); #if !CLIENTSDKV15 template.ComposedLook.AlternateCSS = Tokenize(web.AlternateCssUrl, web.Url); template.ComposedLook.SiteLogo = Tokenize(web.SiteLogoUrl, web.Url); #else template.ComposedLook.AlternateCSS = null; template.ComposedLook.SiteLogo = null; #endif scope.LogInfo(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Retrieving_current_composed_look); var theme = web.GetCurrentComposedLook(); if (theme != null) { if (creationInfo != null) { // Don't exclude the DesignPreviewThemedCssFolderUrl property bag, if any creationInfo.PropertyBagPropertiesToPreserve.Add("DesignPreviewThemedCssFolderUrl"); } template.ComposedLook.Name = theme.Name; if (theme.IsCustomComposedLook) { if (creationInfo != null && creationInfo.PersistComposedLookFiles && creationInfo.FileConnector != null) { Site site = (web.Context as ClientContext).Site; if (!site.IsObjectPropertyInstantiated("Url")) { web.Context.Load(site); web.Context.ExecuteQueryRetry(); } scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Creating_SharePointConnector); // Let's create a SharePoint connector since our files anyhow are in SharePoint at this moment SharePointConnector spConnector = new SharePointConnector(web.Context, web.Url, "dummy"); // to get files from theme catalog we need a connector linked to the root site SharePointConnector spConnectorRoot; if (!site.Url.Equals(web.Url, StringComparison.InvariantCultureIgnoreCase)) { spConnectorRoot = new SharePointConnector(web.Context.Clone(site.Url), site.Url, "dummy"); } else { spConnectorRoot = spConnector; } // Download the theme/branding specific files DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, web.AlternateCssUrl, scope); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, web.SiteLogoUrl, scope); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.BackgroundImage, scope); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.Theme, scope); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.Font, scope); } template.ComposedLook.BackgroundFile = FixFileUrl(Tokenize(theme.BackgroundImage, web.Url)); template.ComposedLook.ColorFile = FixFileUrl(Tokenize(theme.Theme, web.Url)); template.ComposedLook.FontFile = FixFileUrl(Tokenize(theme.Font, web.Url)); // Create file entries for the custom theme files if (!string.IsNullOrEmpty(template.ComposedLook.BackgroundFile)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.BackgroundFile)); } if (!string.IsNullOrEmpty(template.ComposedLook.ColorFile)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.ColorFile)); } if (!string.IsNullOrEmpty(template.ComposedLook.FontFile)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.FontFile)); } if (!string.IsNullOrEmpty(template.ComposedLook.SiteLogo)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.SiteLogo)); } // If a base template is specified then use that one to "cleanup" the generated template model if (creationInfo != null && creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate); } } else { template.ComposedLook.BackgroundFile = ""; template.ComposedLook.ColorFile = ""; template.ComposedLook.FontFile = ""; } } else { template.ComposedLook = null; } if (creationInfo != null && creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate); } } return(template); }
public override Model.ProvisioningTemplate ExtractObjects(Web web, Model.ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { if (creationInfo.IncludeSiteCollectionTermGroup || creationInfo.IncludeAllTermGroups) { // Find the site collection termgroup, if any TaxonomySession session = TaxonomySession.GetTaxonomySession(web.Context); var termStore = session.GetDefaultSiteCollectionTermStore(); web.Context.Load(termStore, t => t.Id, t => t.DefaultLanguage, t => t.OrphanedTermsTermSet); web.Context.ExecuteQueryRetry(); var orphanedTermsTermSetId = termStore.OrphanedTermsTermSet.Id; if (termStore.ServerObjectIsNull.Value) { termStore = session.GetDefaultKeywordsTermStore(); web.Context.Load(termStore, t => t.Id, t => t.DefaultLanguage); web.Context.ExecuteQueryRetry(); } var propertyBagKey = string.Format("SiteCollectionGroupId{0}", termStore.Id); var siteCollectionTermGroupId = web.GetPropertyBagValueString(propertyBagKey, ""); Guid termGroupGuid = Guid.Empty; Guid.TryParse(siteCollectionTermGroupId, out termGroupGuid); List <TermGroup> termGroups = new List <TermGroup>(); if (creationInfo.IncludeAllTermGroups) { web.Context.Load(termStore.Groups, groups => groups.Include(tg => tg.Name, tg => tg.Id, tg => tg.Description, tg => tg.TermSets.IncludeWithDefaultProperties(ts => ts.CustomSortOrder))); web.Context.ExecuteQueryRetry(); termGroups = termStore.Groups.ToList(); } else { if (termGroupGuid != Guid.Empty) { var termGroup = termStore.GetGroup(termGroupGuid); web.Context.Load(termGroup, tg => tg.Name, tg => tg.Id, tg => tg.Description, tg => tg.TermSets.IncludeWithDefaultProperties(ts => ts.CustomSortOrder)); web.Context.ExecuteQueryRetry(); termGroups = new List <TermGroup>() { termGroup }; } } foreach (var termGroup in termGroups) { Boolean isSiteCollectionTermGroup = termGroupGuid != Guid.Empty && termGroup.Id == termGroupGuid; var modelTermGroup = new Model.TermGroup { Name = isSiteCollectionTermGroup ? "{sitecollectiontermgroupname}" : termGroup.Name, Id = isSiteCollectionTermGroup ? Guid.Empty : termGroup.Id, Description = termGroup.Description }; foreach (var termSet in termGroup.TermSets) { // Do not include the orphan term set if (termSet.Id == orphanedTermsTermSetId) { continue; } // Extract all other term sets var modelTermSet = new Model.TermSet(); modelTermSet.Name = termSet.Name; if (!isSiteCollectionTermGroup) { modelTermSet.Id = termSet.Id; } modelTermSet.IsAvailableForTagging = termSet.IsAvailableForTagging; modelTermSet.IsOpenForTermCreation = termSet.IsOpenForTermCreation; modelTermSet.Description = termSet.Description; modelTermSet.Terms.AddRange(GetTerms <TermSet>(web.Context, termSet, termStore.DefaultLanguage, isSiteCollectionTermGroup)); foreach (var property in termSet.CustomProperties) { modelTermSet.Properties.Add(property.Key, property.Value); } modelTermGroup.TermSets.Add(modelTermSet); } template.TermGroups.Add(modelTermGroup); } } } return(template); }
private void ProvisionCustomActionImplementation(object parent, CustomActionCollection customActions, TokenParser parser, PnPMonitoredScope scope, bool isNoScriptSite = false) { Web web = null; Site site = null; if (parent is Site) { site = parent as Site; // Switch parser context; parser.Rebase(site.RootWeb); } else { web = parent as Web; // Switch parser context parser.Rebase(web); } foreach (var customAction in customActions) { if (isNoScriptSite && Guid.Empty == customAction.ClientSideComponentId) { scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_CustomActions_SkippingAddUpdateDueToNoScript, customAction.Name); continue; } var caExists = false; if (site != null) { caExists = site.CustomActionExists(customAction.Name); } else { caExists = web.CustomActionExists(customAction.Name); } // If the CustomAction does not exist, we don't have to remove it, and it is enabled if (!caExists && !customAction.Remove && customAction.Enabled) { // Then we add it to the target var customActionEntity = new CustomActionEntity() { #if !ONPREMISES ClientSideComponentId = customAction.ClientSideComponentId, ClientSideComponentProperties = customAction.ClientSideComponentProperties != null?parser.ParseString(customAction.ClientSideComponentProperties) : customAction.ClientSideComponentProperties, #endif CommandUIExtension = customAction.CommandUIExtension != null?parser.ParseString(customAction.CommandUIExtension.ToString()) : string.Empty, Description = parser.ParseString(customAction.Description), Group = customAction.Group, ImageUrl = parser.ParseString(customAction.ImageUrl), Location = customAction.Location, Name = customAction.Name, RegistrationId = parser.ParseString(customAction.RegistrationId), RegistrationType = customAction.RegistrationType, Remove = customAction.Remove, Rights = customAction.Rights, ScriptBlock = parser.ParseString(customAction.ScriptBlock), ScriptSrc = parser.ParseString(customAction.ScriptSrc), Sequence = customAction.Sequence, Title = parser.ParseString(customAction.Title), Url = parser.ParseString(customAction.Url) }; if (site != null) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Adding_custom_action___0___to_scope_Site, customActionEntity.Name); site.AddCustomAction(customActionEntity); #if !ONPREMISES if ((!string.IsNullOrEmpty(customAction.Title) && customAction.Title.ContainsResourceToken()) || (!string.IsNullOrEmpty(customAction.Description) && customAction.Description.ContainsResourceToken())) { var uca = site.GetCustomActions().FirstOrDefault(uc => uc.Name == customAction.Name); SetCustomActionResourceValues(parser, customAction, uca); } #endif } else { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Adding_custom_action___0___to_scope_Web, customActionEntity.Name); web.AddCustomAction(customActionEntity); #if !ONPREMISES if (customAction.Title.ContainsResourceToken() || customAction.Description.ContainsResourceToken()) { var uca = web.GetCustomActions().FirstOrDefault(uc => uc.Name == customAction.Name); SetCustomActionResourceValues(parser, customAction, uca); } #endif } } else { UserCustomAction existingCustomAction; if (site != null) { existingCustomAction = site.GetCustomActions().FirstOrDefault(c => c.Name == customAction.Name); } else { existingCustomAction = web.GetCustomActions().FirstOrDefault(c => c.Name == customAction.Name); } if (existingCustomAction != null) { // If we have to remove the existing CustomAction if (customAction.Remove) { // We simply remove it existingCustomAction.DeleteObject(); existingCustomAction.Context.ExecuteQueryRetry(); } else { UpdateCustomAction(parser, scope, customAction, existingCustomAction, isNoScriptSite); } } } } }
/// <summary> /// Method to Invoke Custom Extraction Handlers. /// </summary> /// <remarks> /// Ensure the ClientContext is not disposed in the custom provider. /// </remarks> /// <param name="ctx">Authenticated ClientContext that is passed to the custom provider.</param> /// <param name="handler">A custom Extensibility Provisioning Provider</param> /// <param name="template">ProvisioningTemplate that is passed to the custom provider</param> /// <param name="creationInformation">The Provisioning Template creation information object</param> /// <param name="scope">The PnPMonitoredScope of the current step in the pipeline</param> /// <exception cref="ExtensiblityPipelineException"></exception> /// <exception cref="ArgumentException">Provider.Assembly or Provider.Type is NullOrWhiteSpace></exception> /// <exception cref="ArgumentNullException">ClientContext is Null></exception> public ProvisioningTemplate ExecuteExtensibilityExtractionCallOut(ClientContext ctx, ExtensibilityHandler handler, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInformation, PnPMonitoredScope scope) { var _loggingSource = "OfficeDevPnP.Core.Framework.Provisioning.Extensibility.ExtensibilityManager.ExecuteCallout"; if (ctx == null) { throw new ArgumentNullException(nameof(ctx), CoreResources.Provisioning_Extensibility_Pipeline_ClientCtxNull); } if (string.IsNullOrWhiteSpace(handler.Assembly)) { throw new ArgumentException(String.Format("{0}.{1}", nameof(handler), nameof(handler.Assembly)), CoreResources.Provisioning_Extensibility_Pipeline_Missing_AssemblyName); } if (string.IsNullOrWhiteSpace(handler.Type)) { throw new ArgumentException(String.Format("{0}.{1}", nameof(handler), nameof(handler.Type)), CoreResources.Provisioning_Extensibility_Pipeline_Missing_TypeName); } ProvisioningTemplate parsedTemplate = null; try { var _instance = GetProviderInstance(handler); if (_instance is IProvisioningExtensibilityHandler) { Log.Info(_loggingSource, CoreResources.Provisioning_Extensibility_Pipeline_BeforeInvocation, handler.Assembly, handler.Type); parsedTemplate = (_instance as IProvisioningExtensibilityHandler).Extract(ctx, template, creationInformation, scope, handler.Configuration); Log.Info(_loggingSource, CoreResources.Provisioning_Extensibility_Pipeline_Success, handler.Assembly, handler.Type); } else if (_instance != null && !(_instance is IProvisioningExtensibilityTokenProvider)) { throw new ArgumentOutOfRangeException(nameof(handler), string.Format(CoreResources.Provisioning_Extensibility_Invalid_Handler_Implementation, this.GetType().Assembly.GetName().Version.ToString(), handler.Assembly, handler.Type)); } else { parsedTemplate = template; } } catch (Exception ex) { Log.Error(_loggingSource, CoreResources.Provisioning_Extensibility_Pipeline_Exception, handler.Assembly, handler.Type, ex); string _message = string.Format( CoreResources.Provisioning_Extensibility_Pipeline_Exception, handler.Assembly, handler.Type, ex); throw new ExtensiblityPipelineException(_message, ex); } return(parsedTemplate); }
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); }
private ProvisioningTemplate CleanupEntities(ProvisioningTemplate template, ProvisioningTemplate baseTemplate, bool isSubSite, PnPMonitoredScope scope) { if (!isSubSite) { foreach (var customAction in baseTemplate.CustomActions.SiteCustomActions) { int index = template.CustomActions.SiteCustomActions.FindIndex(f => f.Name.Equals(customAction.Name)); if (index > -1) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Removing_site_scoped_custom_action___0___from_template_because_already_available_in_base_template, customAction.Name); template.CustomActions.SiteCustomActions.RemoveAt(index); } } } foreach (var customAction in baseTemplate.CustomActions.WebCustomActions) { int index = template.CustomActions.WebCustomActions.FindIndex(f => f.Name.Equals(customAction.Name)); if (index > -1) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Removing_web_scoped_custom_action___0___from_template_because_already_available_in_base_template, customAction.Name); template.CustomActions.WebCustomActions.RemoveAt(index); } } return(template); }
/// <summary> /// Method to Invoke Custom Provisioning Handlers. /// </summary> /// <remarks> /// Ensure the ClientContext is not disposed in the custom provider. /// </remarks> /// <param name="ctx">Authenticated ClientContext that is passed to the custom provider.</param> /// <param name="handler">A custom Extensibility Provisioning Provider</param> /// <param name="template">ProvisioningTemplate that is passed to the custom provider</param> /// <param name="applyingInformation">The Provisioning Template application information object</param> /// <param name="tokenParser">The Token Parser used by the engine during template provisioning</param> /// <param name="scope">The PnPMonitoredScope of the current step in the pipeline</param> /// <exception cref="ExtensiblityPipelineException"></exception> /// <exception cref="ArgumentException">Provider.Assembly or Provider.Type is NullOrWhiteSpace></exception> /// <exception cref="ArgumentNullException">ClientContext is Null></exception> public void ExecuteExtensibilityProvisionCallOut(ClientContext ctx, ExtensibilityHandler handler, ProvisioningTemplate template, ProvisioningTemplateApplyingInformation applyingInformation, TokenParser tokenParser, PnPMonitoredScope scope) { var _loggingSource = "OfficeDevPnP.Core.Framework.Provisioning.Extensibility.ExtensibilityManager.ExecuteCallout"; if (ctx == null) { throw new ArgumentNullException(nameof(ctx), CoreResources.Provisioning_Extensibility_Pipeline_ClientCtxNull); } if (string.IsNullOrWhiteSpace(handler.Assembly)) { throw new ArgumentException(String.Format("{0}.{1}", nameof(handler), nameof(handler.Type)), CoreResources.Provisioning_Extensibility_Pipeline_Missing_AssemblyName); } if (string.IsNullOrWhiteSpace(handler.Type)) { throw new ArgumentException(String.Format("{0}.{1}", nameof(handler), nameof(handler.Type)), CoreResources.Provisioning_Extensibility_Pipeline_Missing_TypeName); } try { var _instance = GetProviderInstance(handler); #pragma warning disable 618 if (_instance is IProvisioningExtensibilityProvider) #pragma warning restore 618 { Log.Info(_loggingSource, CoreResources.Provisioning_Extensibility_Pipeline_BeforeInvocation, handler.Assembly, handler.Type); #pragma warning disable 618 (_instance as IProvisioningExtensibilityProvider).ProcessRequest(ctx, template, handler.Configuration); #pragma warning restore 618 Log.Info(_loggingSource, CoreResources.Provisioning_Extensibility_Pipeline_Success, handler.Assembly, handler.Type); } else if (_instance is IProvisioningExtensibilityHandler) { Log.Info(_loggingSource, CoreResources.Provisioning_Extensibility_Pipeline_BeforeInvocation, handler.Assembly, handler.Type); (_instance as IProvisioningExtensibilityHandler).Provision(ctx, template, applyingInformation, tokenParser, scope, handler.Configuration); Log.Info(_loggingSource, CoreResources.Provisioning_Extensibility_Pipeline_Success, handler.Assembly, handler.Type); } else if (_instance != null && !(_instance is IProvisioningExtensibilityTokenProvider)) { throw new ArgumentOutOfRangeException(nameof(handler), string.Format(CoreResources.Provisioning_Extensibility_Invalid_Handler_Implementation, this.GetType().Assembly.GetName().Version.ToString(), handler.Assembly, handler.Type)); } } catch (Exception ex) { Log.Error(_loggingSource, CoreResources.Provisioning_Extensibility_Pipeline_Exception, handler.Assembly, handler.Type, ex); string _message = string.Format( CoreResources.Provisioning_Extensibility_Pipeline_Exception, handler.Assembly, handler.Type, ex); throw new ExtensiblityPipelineException(_message, ex); } }
internal static void UpdateCustomAction(TokenParser parser, PnPMonitoredScope scope, CustomAction customAction, UserCustomAction existingCustomAction, bool isNoScriptSite = false) { var isDirty = false; if (isNoScriptSite) { scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_CustomActions_SkippingAddUpdateDueToNoScript, customAction.Name); return; } // Otherwise we update it if (customAction.CommandUIExtension != null) { if (existingCustomAction.CommandUIExtension != parser.ParseString(customAction.CommandUIExtension.ToString())) { scope.LogPropertyUpdate("CommandUIExtension"); existingCustomAction.CommandUIExtension = parser.ParseString(customAction.CommandUIExtension.ToString()); isDirty = true; } } else { // Required to allow for a delta action to blank out the CommandUIExtension attribute if (existingCustomAction.CommandUIExtension != null) { scope.LogPropertyUpdate("CommandUIExtension"); existingCustomAction.CommandUIExtension = null; isDirty = true; } } #if !ONPREMISES if (customAction.ClientSideComponentId != null && customAction.ClientSideComponentId != Guid.Empty) { if (existingCustomAction.ClientSideComponentId != customAction.ClientSideComponentId) { existingCustomAction.ClientSideComponentId = customAction.ClientSideComponentId; isDirty = true; } } if (!String.IsNullOrEmpty(customAction.ClientSideComponentProperties)) { if (existingCustomAction.ClientSideComponentProperties != parser.ParseString(customAction.ClientSideComponentProperties)) { existingCustomAction.ClientSideComponentProperties = parser.ParseString(customAction.ClientSideComponentProperties); isDirty = true; } } #endif if (existingCustomAction.Description != customAction.Description) { scope.LogPropertyUpdate("Description"); existingCustomAction.Description = customAction.Description; isDirty = true; } #if !ONPREMISES if (customAction.Description.ContainsResourceToken()) { if (existingCustomAction.DescriptionResource.SetUserResourceValue(customAction.Description, parser)) { isDirty = true; } } #endif if (existingCustomAction.Group != customAction.Group) { scope.LogPropertyUpdate("Group"); existingCustomAction.Group = customAction.Group; isDirty = true; } if (existingCustomAction.ImageUrl != parser.ParseString(customAction.ImageUrl)) { scope.LogPropertyUpdate("ImageUrl"); existingCustomAction.ImageUrl = parser.ParseString(customAction.ImageUrl); isDirty = true; } if (existingCustomAction.Location != customAction.Location) { scope.LogPropertyUpdate("Location"); existingCustomAction.Location = customAction.Location; isDirty = true; } if (existingCustomAction.RegistrationId != parser.ParseString(customAction.RegistrationId)) { scope.LogPropertyUpdate("RegistrationId"); existingCustomAction.RegistrationId = parser.ParseString(customAction.RegistrationId); isDirty = true; } if (existingCustomAction.RegistrationType != customAction.RegistrationType) { scope.LogPropertyUpdate("RegistrationType"); existingCustomAction.RegistrationType = customAction.RegistrationType; isDirty = true; } if (existingCustomAction.ScriptBlock != parser.ParseString(customAction.ScriptBlock)) { scope.LogPropertyUpdate("ScriptBlock"); existingCustomAction.ScriptBlock = parser.ParseString(customAction.ScriptBlock); isDirty = true; } if (existingCustomAction.ScriptSrc != parser.ParseString(customAction.ScriptSrc)) { scope.LogPropertyUpdate("ScriptSrc"); existingCustomAction.ScriptSrc = parser.ParseString(customAction.ScriptSrc); isDirty = true; } if (existingCustomAction.Sequence != customAction.Sequence) { scope.LogPropertyUpdate("Sequence"); existingCustomAction.Sequence = customAction.Sequence; isDirty = true; } if (existingCustomAction.Title != parser.ParseString(customAction.Title)) { scope.LogPropertyUpdate("Title"); existingCustomAction.Title = parser.ParseString(customAction.Title); isDirty = true; } #if !ONPREMISES if (customAction.Title.ContainsResourceToken()) { if (existingCustomAction.TitleResource.SetUserResourceValue(customAction.Title, parser)) { isDirty = true; } } #endif if (existingCustomAction.Url != parser.ParseString(customAction.Url)) { scope.LogPropertyUpdate("Url"); existingCustomAction.Url = parser.ParseString(customAction.Url); isDirty = true; } if (isDirty) { existingCustomAction.Update(); existingCustomAction.Context.ExecuteQueryRetry(); } }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { 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); } #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); } 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); }
private static void LocalizeParts(Web web, TokenParser parser, string url, WebPartCollection webParts, PnPMonitoredScope scope) { if (CanUseAcceptLanguageHeaderForLocalization(web)) { var context = web.Context; web.EnsureProperties(w => w.Language, w => w.IsMultilingual, w => w.SupportedUILanguageIds); if (web.IsMultilingual) { //just update if web is multilingual var allParts = web.GetWebParts(parser.ParseString(url)).ToList(); foreach (var webPart in webParts) { var partOnPage = allParts.FirstOrDefault(w => w.ZoneId == webPart.Zone && w.WebPart.ZoneIndex == webPart.Order); if (webPart.Title.ContainsResourceToken() && partOnPage != null) { var resourceValues = parser.GetResourceTokenResourceValues(webPart.Title); foreach (var resourceValue in resourceValues) { var translationculture = new CultureInfo(resourceValue.Item1); if (web.SupportedUILanguageIds.Contains(translationculture.LCID)) { // Save property with correct locale on the request to make it stick // http://sadomovalex.blogspot.no/2015/09/localize-web-part-titles-via-client.html context.PendingRequest.RequestExecutor.WebRequest.Headers["Accept-Language"] = resourceValue.Item1; partOnPage.WebPart.Properties["Title"] = resourceValue.Item2; partOnPage.SaveWebPartChanges(); context.ExecuteQueryRetry(); } } } } context.PendingRequest.RequestExecutor.WebRequest.Headers.Remove("Accept-Language"); } else { //skip since web is not multilingual scope.LogWarning(CoreResources.Provisioning_Extensions_WebPartLocalization_NoMUI_Skip); } } else { // warning scope.LogWarning(CoreResources.Provisioning_Extensions_WebPartLocalization_Skip); } }
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 CanProvisionResult CanProvision(Web web, ProvisioningTemplate template, ProvisioningTemplateApplyingInformation applyingInformation) { // Prepare the default output var result = new CanProvisionResult(); Model.ProvisioningTemplate targetTemplate = null; if (template.ParentHierarchy != null) { // If we have a hierarchy, search for a template with Taxonomy settings, if any targetTemplate = template.ParentHierarchy.Templates.FirstOrDefault(t => t.TermGroups.Count > 0); if (targetTemplate == null) { // or use the first in the hierarchy targetTemplate = template.ParentHierarchy.Templates[0]; } } else { // Otherwise, use the provided template targetTemplate = template; } // Verify if we need the Term Store permissions (i.e. the template contains term groups to provision, or sequences with TermStore settings) if ((targetTemplate.TermGroups != null && targetTemplate.TermGroups?.Count > 0) || targetTemplate.ParentHierarchy.Sequences.Any( s => s.TermStore?.TermGroups != null && s.TermStore?.TermGroups?.Count > 0)) { using (var scope = new PnPMonitoredScope(this.Name)) { try { // Try to access the Term Store TaxonomySession taxSession = TaxonomySession.GetTaxonomySession(web.Context); TermStore termStore = taxSession.GetDefaultKeywordsTermStore(); web.Context.Load(termStore, ts => ts.Languages, ts => ts.DefaultLanguage, ts => ts.Groups.Include( tg => tg.Name, tg => tg.Id, tg => tg.TermSets.Include( tset => tset.Name, tset => tset.Id))); var siteCollectionTermGroup = termStore.GetSiteCollectionGroup((web.Context as ClientContext).Site, false); web.Context.Load(siteCollectionTermGroup); web.Context.ExecuteQueryRetry(); var termGroupId = Guid.NewGuid(); var group = termStore.CreateGroup($"Temp-{termGroupId.ToString()}", termGroupId); termStore.CommitAll(); web.Context.Load(group); web.Context.ExecuteQueryRetry(); // Now delete the just created termGroup, to cleanup the Term Store group.DeleteObject(); web.Context.ExecuteQueryRetry(); } catch (Exception ex) { // And if we fail, raise a CanProvisionIssue result.CanProvision = false; result.Issues.Add(new CanProvisionIssue() { Source = this.Name, Tag = CanProvisionIssueTags.MISSING_TERMSTORE_PERMISSIONS, Message = CanProvisionIssuesMessages.Term_Store_Not_Admin, ExceptionMessage = ex.Message, // Here we have a specific exception ExceptionStackTrace = ex.StackTrace, // Here we have a specific exception }); } } } return(result); }
public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { // Extract the Home Page web.EnsureProperties(w => w.RootFolder.WelcomePage, w => w.ServerRelativeUrl, w => w.Url); var homepageUrl = web.RootFolder.WelcomePage; if (string.IsNullOrEmpty(homepageUrl)) { homepageUrl = "Default.aspx"; } var welcomePageUrl = UrlUtility.Combine(web.ServerRelativeUrl, homepageUrl); var file = web.GetFileByServerRelativeUrl(welcomePageUrl); try { var listItem = file.EnsureProperty(f => f.ListItemAllFields); if (listItem != null) { if (listItem.FieldValues.ContainsKey("WikiField")) { // Wiki page var fullUri = new Uri(UrlUtility.Combine(web.Url, web.RootFolder.WelcomePage)); var folderPath = fullUri.Segments.Take(fullUri.Segments.Count() - 1).ToArray().Aggregate((i, x) => i + x).TrimEnd('/'); var fileName = fullUri.Segments[fullUri.Segments.Count() - 1]; var homeFile = web.GetFileByServerRelativeUrl(welcomePageUrl); LimitedWebPartManager limitedWPManager = homeFile.GetLimitedWebPartManager(PersonalizationScope.Shared); web.Context.Load(limitedWPManager); var webParts = web.GetWebParts(welcomePageUrl); var page = new Page() { Layout = WikiPageLayout.Custom, Overwrite = true, Url = Tokenize(fullUri.PathAndQuery, web.Url), }; var pageContents = listItem.FieldValues["WikiField"].ToString(); Regex regexClientIds = new Regex(@"id=\""div_(?<ControlId>(\w|\-)+)"); if (regexClientIds.IsMatch(pageContents)) { foreach (Match webPartMatch in regexClientIds.Matches(pageContents)) { String serverSideControlId = webPartMatch.Groups["ControlId"].Value; try { String serverSideControlIdToSearchFor = String.Format("g_{0}", serverSideControlId.Replace("-", "_")); WebPartDefinition webPart = limitedWPManager.WebParts.GetByControlId(serverSideControlIdToSearchFor); web.Context.Load(webPart, wp => wp.Id, wp => wp.WebPart.Title, wp => wp.WebPart.ZoneIndex ); web.Context.ExecuteQueryRetry(); var webPartxml = TokenizeWebPartXml(web, web.GetWebPartXml(webPart.Id, welcomePageUrl)); page.WebParts.Add(new Model.WebPart() { Title = webPart.WebPart.Title, Contents = webPartxml, Order = (uint)webPart.WebPart.ZoneIndex, Row = 1, // By default we will create a onecolumn layout, add the webpart to it, and later replace the wikifield on the page to position the webparts correctly. Column = 1 // By default we will create a onecolumn layout, add the webpart to it, and later replace the wikifield on the page to position the webparts correctly. }); pageContents = Regex.Replace(pageContents, serverSideControlId, string.Format("{{webpartid:{0}}}", webPart.WebPart.Title), RegexOptions.IgnoreCase); } catch (ServerException) { scope.LogWarning("Found a WebPart ID which is not available on the server-side. ID: {0}", serverSideControlId); } } } page.Fields.Add("WikiField", pageContents); template.Pages.Add(page); // Set the homepage if (template.WebSettings == null) { template.WebSettings = new WebSettings(); } template.WebSettings.WelcomePage = homepageUrl; } else { if (web.Context.HasMinimalServerLibraryVersion(Constants.MINIMUMZONEIDREQUIREDSERVERVERSION)) { // Not a wikipage template = GetFileContents(web, template, welcomePageUrl, creationInfo, scope); if (template.WebSettings == null) { template.WebSettings = new WebSettings(); } template.WebSettings.WelcomePage = homepageUrl; } else { WriteWarning(string.Format("Page content export requires a server version that is newer than the current server. Server version is {0}, minimal required is {1}", web.Context.ServerLibraryVersion, Constants.MINIMUMZONEIDREQUIREDSERVERVERSION), ProvisioningMessageType.Warning); scope.LogWarning("Page content export requires a server version that is newer than the current server. Server version is {0}, minimal required is {1}", web.Context.ServerLibraryVersion, Constants.MINIMUMZONEIDREQUIREDSERVERVERSION); } } } } catch (ServerException ex) { if (ex.ServerErrorCode != -2146232832) { throw; } else { if (web.Context.HasMinimalServerLibraryVersion(Constants.MINIMUMZONEIDREQUIREDSERVERVERSION)) { // Page does not belong to a list, extract the file as is template = GetFileContents(web, template, welcomePageUrl, creationInfo, scope); if (template.WebSettings == null) { template.WebSettings = new WebSettings(); } template.WebSettings.WelcomePage = homepageUrl; } else { WriteWarning(string.Format("Page content export requires a server version that is newer than the current server. Server version is {0}, minimal required is {1}", web.Context.ServerLibraryVersion, Constants.MINIMUMZONEIDREQUIREDSERVERVERSION), ProvisioningMessageType.Warning); scope.LogWarning("Page content export requires a server version that is newer than the current server. Server version is {0}, minimal required is {1}", web.Context.ServerLibraryVersion, Constants.MINIMUMZONEIDREQUIREDSERVERVERSION); } } } // If a base template is specified then use that one to "cleanup" the generated template model if (creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate); } } return(template); }
public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { 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, w => w.QuickLaunchEnabled, #if !SP2019 w => w.SearchScope, w => w.SearchBoxInNavBar, #endif #endif //w => w.Title, //w => w.Description, w => w.MasterUrl, w => w.CustomMasterUrl, w => w.SiteLogoUrl, w => w.RequestAccessEmail, w => w.RootFolder, w => w.AlternateCssUrl, w => w.ServerRelativeUrl, w => w.Url ); var webSettings = new WebSettings(); #if !SP2013 && !SP2016 webSettings.NoCrawl = web.NoCrawl; webSettings.CommentsOnSitePagesDisabled = web.CommentsOnSitePagesDisabled; webSettings.ExcludeFromOfflineClient = web.ExcludeFromOfflineClient; webSettings.MembersCanShare = web.MembersCanShare; webSettings.DisableFlows = web.DisableFlows; webSettings.DisableAppViews = web.DisableAppViews; webSettings.HorizontalQuickLaunch = web.HorizontalQuickLaunch; webSettings.QuickLaunchEnabled = web.QuickLaunchEnabled; #if !SP2019 webSettings.SearchScope = (SearchScopes)Enum.Parse(typeof(SearchScopes), web.SearchScope.ToString(), true); webSettings.SearchBoxInNavBar = (SearchBoxInNavBar)Enum.Parse(typeof(SearchBoxInNavBar), web.SearchBoxInNavBar.ToString(), true); #endif #endif // We're not extracting Title and Description //webSettings.Title = Tokenize(web.Title, web.Url); //webSettings.Description = Tokenize(web.Description, web.Url); webSettings.MasterPageUrl = Tokenize(web.MasterUrl, web.Url); webSettings.CustomMasterPageUrl = Tokenize(web.CustomMasterUrl, web.Url); webSettings.SiteLogo = TokenizeHost(web, Tokenize(web.SiteLogoUrl, web.Url)); // Notice. No tokenization needed for the welcome page, it's always relative for the site webSettings.WelcomePage = web.RootFolder.WelcomePage; webSettings.AlternateCSS = Tokenize(web.AlternateCssUrl, web.Url); webSettings.RequestAccessEmail = web.RequestAccessEmail; #if !ONPREMISES // Can we get the hubsite url? This requires Tenant Admin rights try { var site = ((ClientContext)web.Context).Site; site.EnsureProperties(s => s.HubSiteId, s => s.Id); if (site.HubSiteId != Guid.Empty && site.HubSiteId != site.Id) { using (var tenantContext = web.Context.Clone((web.Context as ClientContext).Web.GetTenantAdministrationUrl())) { var tenant = new Tenant(tenantContext); var hubsiteProperties = tenant.GetHubSitePropertiesById(site.HubSiteId); tenantContext.Load(hubsiteProperties); tenantContext.ExecuteQueryRetry(); webSettings.HubSiteUrl = hubsiteProperties.SiteUrl; } } } catch { } #endif if (creationInfo.PersistBrandingFiles) { if (!string.IsNullOrEmpty(web.MasterUrl)) { var masterUrl = web.MasterUrl.ToLower(); if (!masterUrl.EndsWith("default.master") && !masterUrl.EndsWith("custom.master") && !masterUrl.EndsWith("v4.master") && !masterUrl.EndsWith("seattle.master") && !masterUrl.EndsWith("oslo.master")) { if (PersistFile(web, creationInfo, scope, web.MasterUrl)) { template.Files.Add(GetTemplateFile(web, web.MasterUrl)); } } } if (!string.IsNullOrEmpty(web.CustomMasterUrl)) { var customMasterUrl = web.CustomMasterUrl.ToLower(); if (!customMasterUrl.EndsWith("default.master") && !customMasterUrl.EndsWith("custom.master") && !customMasterUrl.EndsWith("v4.master") && !customMasterUrl.EndsWith("seattle.master") && !customMasterUrl.EndsWith("oslo.master")) { if (PersistFile(web, creationInfo, scope, web.CustomMasterUrl)) { template.Files.Add(GetTemplateFile(web, web.CustomMasterUrl)); } } } // Extract site logo if property has been set and it's not dynamic image from _api URL if (!string.IsNullOrEmpty(web.SiteLogoUrl) && (!web.SiteLogoUrl.ToLowerInvariant().Contains("_api/"))) { // Convert to server relative URL if needed (web.SiteLogoUrl can be set to FQDN URL of a file hosted in the site (e.g. for communication sites)) Uri webUri = new Uri(web.Url); string webUrl = $"{webUri.Scheme}://{webUri.DnsSafeHost}"; string siteLogoServerRelativeUrl = web.SiteLogoUrl.Replace(webUrl, ""); if (PersistFile(web, creationInfo, scope, siteLogoServerRelativeUrl)) { template.Files.Add(GetTemplateFile(web, siteLogoServerRelativeUrl)); } } if (!string.IsNullOrEmpty(web.AlternateCssUrl)) { if (PersistFile(web, creationInfo, scope, web.AlternateCssUrl)) { template.Files.Add(GetTemplateFile(web, web.AlternateCssUrl)); } } var files = template.Files.Distinct().ToList(); template.Files.Clear(); template.Files.AddRange(files); } if (!creationInfo.PersistBrandingFiles) { if (creationInfo.BaseTemplate != null) { if (!webSettings.Equals(creationInfo.BaseTemplate.WebSettings)) { template.WebSettings = webSettings; } } else { template.WebSettings = webSettings; } } else { template.WebSettings = webSettings; } } return(template); }
private ProvisioningTemplate GetFileContents(Web web, ProvisioningTemplate template, string welcomePageUrl, ProvisioningTemplateCreationInformation creationInfo, PnPMonitoredScope scope) { var fullUri = new Uri(UrlUtility.Combine(web.Url, web.RootFolder.WelcomePage)); var folderPath = fullUri.Segments.Take(fullUri.Segments.Count() - 1).ToArray().Aggregate((i, x) => i + x).TrimEnd('/'); var fileName = fullUri.Segments[fullUri.Segments.Count() - 1]; var webParts = web.GetWebParts(welcomePageUrl); var file = web.GetFileByServerRelativeUrl(welcomePageUrl); var homeFile = new Model.File() { Folder = Tokenize(folderPath, web.Url), Src = fileName, Overwrite = true, }; // Add field values to file RetrieveFieldValues(web, file, homeFile); // Add WebParts to file foreach (var webPart in webParts) { var webPartxml = TokenizeWebPartXml(web, web.GetWebPartXml(webPart.Id, welcomePageUrl)); Model.WebPart newWp = new Model.WebPart() { Title = webPart.WebPart.Title, Row = (uint)webPart.WebPart.ZoneIndex, Contents = webPartxml }; #if !CLIENTSDKV15 // As long as we've no CSOM library that has the ZoneID we can't use the version check as things don't compile... if (web.Context.HasMinimalServerLibraryVersion(Constants.MINIMUMZONEIDREQUIREDSERVERVERSION)) { newWp.Zone = webPart.ZoneId; } #endif homeFile.WebParts.Add(newWp); } template.Files.Add(homeFile); // Persist file using connector if (creationInfo.PersistBrandingFiles) { PersistFile(web, creationInfo, scope, folderPath, fileName); } return(template); }
public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { web.EnsureProperties(w => w.HasUniqueRoleAssignments, w => w.Title); // Changed by Paolo Pialorsi to embrace the new sub-site attributes for break role inheritance and copy role assignments // if this is a sub site then we're not creating security entities as by default security is inherited from the root site if (web.IsSubSite() && !web.HasUniqueRoleAssignments) { return(template); } var ownerGroup = web.AssociatedOwnerGroup; var memberGroup = web.AssociatedMemberGroup; var visitorGroup = web.AssociatedVisitorGroup; web.Context.ExecuteQueryRetry(); if (!ownerGroup.ServerObjectIsNull.Value) { web.Context.Load(ownerGroup, o => o.Id, o => o.Users, o => o.Title); } if (!memberGroup.ServerObjectIsNull.Value) { web.Context.Load(memberGroup, o => o.Id, o => o.Users, o => o.Title); } if (!visitorGroup.ServerObjectIsNull.Value) { web.Context.Load(visitorGroup, o => o.Id, o => o.Users, o => o.Title); } web.Context.ExecuteQueryRetry(); List <int> associatedGroupIds = new List <int>(); var owners = new List <User>(); var members = new List <User>(); var visitors = new List <User>(); if (!ownerGroup.ServerObjectIsNull.Value) { associatedGroupIds.Add(ownerGroup.Id); foreach (var member in ownerGroup.Users) { owners.Add(new User() { Name = member.LoginName }); } } if (!memberGroup.ServerObjectIsNull.Value) { associatedGroupIds.Add(memberGroup.Id); foreach (var member in memberGroup.Users) { members.Add(new User() { Name = member.LoginName }); } } if (!visitorGroup.ServerObjectIsNull.Value) { associatedGroupIds.Add(visitorGroup.Id); foreach (var member in visitorGroup.Users) { visitors.Add(new User() { Name = member.LoginName }); } } var siteSecurity = new SiteSecurity(); siteSecurity.AdditionalOwners.AddRange(owners); siteSecurity.AdditionalMembers.AddRange(members); siteSecurity.AdditionalVisitors.AddRange(visitors); var query = from user in web.SiteUsers where user.IsSiteAdmin select user; var allUsers = web.Context.LoadQuery(query); web.Context.ExecuteQueryRetry(); var admins = new List <User>(); foreach (var member in allUsers) { admins.Add(new User() { Name = member.LoginName }); } siteSecurity.AdditionalAdministrators.AddRange(admins); if (creationInfo.IncludeSiteGroups) { web.Context.Load(web.SiteGroups, o => o.IncludeWithDefaultProperties( gr => gr.Title, gr => gr.AllowMembersEditMembership, gr => gr.AutoAcceptRequestToJoinLeave, gr => gr.AllowRequestToJoinLeave, gr => gr.Description, gr => gr.Users.Include(u => u.LoginName), gr => gr.OnlyAllowMembersViewMembership, gr => gr.Owner.LoginName, gr => gr.RequestToJoinLeaveEmailSetting )); web.Context.ExecuteQueryRetry(); if (web.IsSubSite()) { WriteMessage("You are requesting to export sitegroups from a subweb. Notice that ALL sitegroups from the site collection are included in the result.", ProvisioningMessageType.Warning); } foreach (var group in web.SiteGroups.AsEnumerable().Where(o => !associatedGroupIds.Contains(o.Id))) { try { scope.LogDebug("Processing group {0}", group.Title); var siteGroup = new SiteGroup() { Title = !string.IsNullOrEmpty(web.Title) ? group.Title.Replace(web.Title, "{sitename}") : group.Title, AllowMembersEditMembership = group.AllowMembersEditMembership, AutoAcceptRequestToJoinLeave = group.AutoAcceptRequestToJoinLeave, AllowRequestToJoinLeave = group.AllowRequestToJoinLeave, Description = group.Description, OnlyAllowMembersViewMembership = group.OnlyAllowMembersViewMembership, Owner = ReplaceGroupTokens(web, group.Owner.LoginName), RequestToJoinLeaveEmailSetting = group.RequestToJoinLeaveEmailSetting }; foreach (var member in group.Users) { scope.LogDebug("Processing member {0} of group {0}", member.LoginName, group.Title); siteGroup.Members.Add(new User() { Name = member.LoginName }); } siteSecurity.SiteGroups.Add(siteGroup); } catch (Exception ee) { scope.LogError(ee.StackTrace); scope.LogError(ee.Message); scope.LogError(ee.InnerException.StackTrace); } } } var webRoleDefinitions = web.Context.LoadQuery(web.RoleDefinitions.Include(r => r.Name, r => r.Description, r => r.BasePermissions, r => r.RoleTypeKind)); web.Context.ExecuteQueryRetry(); if (web.HasUniqueRoleAssignments) { var permissionKeys = Enum.GetNames(typeof(PermissionKind)); if (!web.IsSubSite()) { foreach (var webRoleDefinition in webRoleDefinitions) { if (webRoleDefinition.RoleTypeKind == RoleType.None) { scope.LogDebug("Processing custom role definition {0}", webRoleDefinition.Name); var modelRoleDefinitions = new Model.RoleDefinition(); modelRoleDefinitions.Description = webRoleDefinition.Description; modelRoleDefinitions.Name = webRoleDefinition.Name; foreach (var permissionKey in permissionKeys) { scope.LogDebug("Processing custom permissionKey definition {0}", permissionKey); var permissionKind = (PermissionKind)Enum.Parse(typeof(PermissionKind), permissionKey); if (webRoleDefinition.BasePermissions.Has(permissionKind)) { modelRoleDefinitions.Permissions.Add(permissionKind); } } siteSecurity.SiteSecurityPermissions.RoleDefinitions.Add(modelRoleDefinitions); } else { scope.LogDebug("Skipping OOTB role definition {0}", webRoleDefinition.Name); } } } var webRoleAssignments = web.Context.LoadQuery(web.RoleAssignments.Include( r => r.RoleDefinitionBindings.Include( rd => rd.Name, rd => rd.RoleTypeKind), r => r.Member.LoginName, r => r.Member.PrincipalType)); web.Context.ExecuteQueryRetry(); foreach (var webRoleAssignment in webRoleAssignments) { scope.LogDebug("Processing Role Assignment {0}", webRoleAssignment.ToString()); if (webRoleAssignment.Member.PrincipalType == PrincipalType.SharePointGroup && !creationInfo.IncludeSiteGroups) { continue; } if (webRoleAssignment.Member.LoginName != "Excel Services Viewers") { foreach (var roleDefinition in webRoleAssignment.RoleDefinitionBindings) { if (roleDefinition.RoleTypeKind != RoleType.Guest) { var modelRoleAssignment = new Model.RoleAssignment(); var roleDefinitionValue = roleDefinition.Name; if (roleDefinition.RoleTypeKind != RoleType.None) { // Replace with token roleDefinitionValue = $"{{roledefinition:{roleDefinition.RoleTypeKind}}}"; } modelRoleAssignment.RoleDefinition = roleDefinitionValue; if (webRoleAssignment.Member.PrincipalType == PrincipalType.SharePointGroup) { modelRoleAssignment.Principal = ReplaceGroupTokens(web, webRoleAssignment.Member.LoginName); } else { modelRoleAssignment.Principal = webRoleAssignment.Member.LoginName; } siteSecurity.SiteSecurityPermissions.RoleAssignments.Add(modelRoleAssignment); } } } } } template.Security = siteSecurity; // If a base template is specified then use that one to "cleanup" the generated template model if (creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate); } } return(template); }
public override TokenParser ProvisionObjects(Web web, 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); }