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;
        }
Example #2
0
        public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                // if this is a sub site then we're not provisioning fields. Technically this can be done but it's not a recommended practice
                if (web.IsSubSite())
                {
                    scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Fields_Context_web_is_subweb__skipping_site_columns);
                    return parser;
                }

                var existingFields = web.Fields;

                web.Context.Load(existingFields, fs => fs.Include(f => f.Id));
                web.Context.ExecuteQueryRetry();
                var existingFieldIds = existingFields.AsEnumerable<SPField>().Select(l => l.Id).ToList();
                var fields = template.SiteFields;

                foreach (var field in fields)
                {
                    XElement templateFieldElement = XElement.Parse(parser.ParseString(field.SchemaXml, "~sitecollection", "~site"));
                    var fieldId = templateFieldElement.Attribute("ID").Value;

                    if (!existingFieldIds.Contains(Guid.Parse(fieldId)))
                    {
                        try
                        {
                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Fields_Adding_field__0__to_site, fieldId);
                            CreateField(web, templateFieldElement, scope, parser, field.SchemaXml);
                        }
                        catch (Exception ex)
                        {
                            scope.LogError(CoreResources.Provisioning_ObjectHandlers_Fields_Adding_field__0__failed___1_____2_, fieldId, ex.Message, ex.StackTrace);
                            throw;
                        }
                    }
                    else
                        try
                        {
                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Fields_Updating_field__0__in_site, fieldId);
                            UpdateField(web, fieldId, templateFieldElement, scope, parser, field.SchemaXml);
                        }
                        catch (Exception ex)
                        {
                            scope.LogError(CoreResources.Provisioning_ObjectHandlers_Fields_Updating_field__0__failed___1_____2_, fieldId, ex.Message, ex.StackTrace);
                            throw;
                        }
                }
            }
            return parser;
        }
 public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
 {
     using (var scope = new PnPMonitoredScope(this.Name))
     {
         var context = web.Context as ClientContext;
         foreach (var handler in template.ExtensibilityHandlers
             .Union(template.Providers)
             .Union(applyingInformation.ExtensibilityHandlers))
         {
             if (handler.Enabled)
             {
                 try
                 {
                     if (!string.IsNullOrEmpty(handler.Configuration))
                     {
                         //replace tokens in configuration data
                         handler.Configuration = parser.ParseString(handler.Configuration);
                     }
                     scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ExtensibilityProviders_Calling_extensibility_callout__0_, handler.Assembly);
                     _extManager.ExecuteExtensibilityProvisionCallOut(context, handler, template, applyingInformation, parser, scope);
                 }
                 catch (Exception ex)
                 {
                     scope.LogError(CoreResources.Provisioning_ObjectHandlers_ExtensibilityProviders_callout_failed___0_____1_, ex.Message, ex.StackTrace);
                     throw;
                 }
             }
         }
     }
     return parser;
 }
 public TokenParser AddExtendedTokens(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
 {
     using (var scope = new PnPMonitoredScope(this.Name))
     {
         var context = web.Context as ClientContext;
         foreach (var provider in template.Providers)
         {
             if (provider.Enabled)
             {
                 try
                 {
                     if (!string.IsNullOrEmpty(provider.Configuration))
                     {
                         provider.Configuration = parser.ParseString(provider.Configuration);
                     }
                     scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ExtensibilityProviders_Calling_tokenprovider_extensibility_callout__0_, provider.Assembly);
                     var _providedTokens = _extManager.ExecuteTokenProviderCallOut(context, provider, template);
                     if (_providedTokens != null)
                     {
                         foreach (var token in _providedTokens)
                         {
                             parser.AddToken(token);
                         }
                     }
                 }
                 catch (Exception ex)
                 {
                     scope.LogError(CoreResources.Provisioning_ObjectHandlers_ExtensibilityProviders_tokenprovider_callout_failed___0_____1_, ex.Message, ex.StackTrace);
                     throw;
                 }
             }
         }
         return parser;
     }
 }
 public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
 {
     using (var scope = new PnPMonitoredScope(this.Name))
     {
         var context = web.Context as ClientContext;
         foreach (var provider in template.Providers)
         {
             if (provider.Enabled)
             {
                 try
                 {
                     scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ExtensibilityProviders_Calling_extensibility_callout__0_, provider.Assembly);
                     _extManager.ExecuteExtensibilityCallOut(context, provider, template);
                 }
                 catch (Exception ex)
                 {
                     scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ExtensibilityProviders_callout_failed___0_____1_, ex.Message, ex.StackTrace);
                 }
             }
         }
     }
     return parser;
 }
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(CoreResources.Provisioning_ObjectHandlers_CustomActions))
            {
                var context = web.Context as ClientContext;
                bool isSubSite = web.IsSubSite();
                var webCustomActions = web.GetCustomActions();
                var siteCustomActions = context.Site.GetCustomActions();

                var customActions = new CustomActions();
                foreach (var customAction in webCustomActions)
                {
                    scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Adding_web_scoped_custom_action___0___to_template, customAction.Name);
                    customActions.WebCustomActions.Add(CopyUserCustomAction(customAction));
                }

                // if this is a sub site then we're not creating entities for site collection scoped custom actions
                if (!isSubSite)
                {
                    foreach (var customAction in siteCustomActions)
                    {
                        scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Adding_site_scoped_custom_action___0___to_template, customAction.Name);
                        customActions.SiteCustomActions.Add(CopyUserCustomAction(customAction));
                    }
                }

                template.CustomActions = customActions;

                // If a base template is specified then use that one to "cleanup" the generated template model
                if (creationInfo.BaseTemplate != null)
                {
                    template = CleanupEntities(template, creationInfo.BaseTemplate, isSubSite, scope);
                }
            }
            return template;
        }
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(CoreResources.Provisioning_ObjectHandlers_ContentTypes))
            {
                // if this is a sub site then we're not creating content type entities.
                if (web.IsSubSite())
                {
                    scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ContentTypes_Context_web_is_subweb__Skipping_content_types_);
                    return template;
                }

                template.ContentTypes.AddRange(GetEntities(web, scope));

                // If a base template is specified then use that one to "cleanup" the generated template model
                if (creationInfo.BaseTemplate != null)
                {
                    template = CleanupEntities(template, creationInfo.BaseTemplate, scope);
                }
            }
            return template;
        }
        public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                if (template.Lists.Any())
                {
                    var rootWeb = (web.Context as ClientContext).Site.RootWeb;

                    #region DataRows

                    foreach (var listInstance in template.Lists)
                    {
                        if (listInstance.DataRows != null && listInstance.DataRows.Any())
                        {
                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Processing_data_rows_for__0_, listInstance.Title);
                            // Retrieve the target list
                            var list = web.Lists.GetByTitle(listInstance.Title);
                            web.Context.Load(list);
                            web.Context.ExecuteQueryRetry();

                            ListItemsProvider provider = new ListItemsProvider(list, web, template);
                            provider.AddListItems(listInstance.DataRows, template, parser, scope);
                            if (null == m_listContentProviders)
                            {
                                m_listContentProviders = new Dictionary<Guid, ListItemsProvider>();
                            }
                            m_listContentProviders[list.Id] = provider;
                        }
                    }

                    UpdateLookupValues(web, scope);

                    #endregion
                }
            }

            return parser;
        }
 public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
 {
     using (var scope = new PnPMonitoredScope(this.Name))
     {
         var context = web.Context as ClientContext;
         foreach (var handler in creationInfo.ExtensibilityHandlers)
         {
             if (handler.Enabled)
             {
                 try
                 {
                     scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ExtensibilityProviders_Calling_extensibility_callout__0_, handler.Assembly);
                     template = _extManager.ExecuteExtensibilityExtractionCallOut(context, handler, template, creationInfo, scope);
                 }
                 catch (Exception ex)
                 {
                     scope.LogError(CoreResources.Provisioning_ObjectHandlers_ExtensibilityProviders_callout_failed___0_____1_, ex.Message, ex.StackTrace);
                     throw;
                 }
             }
         }
     }
     return template;
 }
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                // Load object if not there
            #if !CLIENTSDKV15
                web.EnsureProperties(w => w.Url, w => w.MasterUrl, w => w.AlternateCssUrl, w => w.SiteLogoUrl);
            #else
                web.EnsureProperties(w => w.Url, w => w.MasterUrl);
            #endif

                // Information coming from the site
                template.ComposedLook.MasterPage = Tokenize(web.MasterUrl, web.Url);
            #if !CLIENTSDKV15
                template.ComposedLook.AlternateCSS = Tokenize(web.AlternateCssUrl, web.Url);
                template.ComposedLook.SiteLogo = Tokenize(web.SiteLogoUrl, web.Url);
            #else
            template.ComposedLook.AlternateCSS = null;
            template.ComposedLook.SiteLogo = null;
            #endif
                scope.LogInfo(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Retrieving_current_composed_look);
                var theme = web.GetCurrentComposedLook();

                if (theme != null)
                {
                    if (creationInfo != null)
                    {
                        // Don't exclude the DesignPreviewThemedCssFolderUrl property bag, if any
                        creationInfo.PropertyBagPropertiesToPreserve.Add("DesignPreviewThemedCssFolderUrl");
                    }

                    template.ComposedLook.Name = theme.Name;

                    if (theme.IsCustomComposedLook)
                    {
                        if (creationInfo != null && creationInfo.PersistComposedLookFiles && creationInfo.FileConnector != null)
                        {
                            Site site = (web.Context as ClientContext).Site;
                            if (!site.IsObjectPropertyInstantiated("Url"))
                            {
                                web.Context.Load(site);
                                web.Context.ExecuteQueryRetry();
                            }

                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Creating_SharePointConnector);
                            // Let's create a SharePoint connector since our files anyhow are in SharePoint at this moment
                            SharePointConnector spConnector = new SharePointConnector(web.Context, web.Url, "dummy");

                            // to get files from theme catalog we need a connector linked to the root site
                            SharePointConnector spConnectorRoot;
                            if (!site.Url.Equals(web.Url, StringComparison.InvariantCultureIgnoreCase))
                            {
                                spConnectorRoot = new SharePointConnector(web.Context.Clone(site.Url), site.Url, "dummy");
                            }
                            else
                            {
                                spConnectorRoot = spConnector;
                            }

                            // Download the theme/branding specific files
                            DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, web.AlternateCssUrl, scope);
                            DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, web.SiteLogoUrl, scope);
                            DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.BackgroundImage, scope);
                            DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.Theme, scope);
                            DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.Font, scope);
                        }

                        template.ComposedLook.BackgroundFile = FixFileUrl(Tokenize(theme.BackgroundImage, web.Url));
                        template.ComposedLook.ColorFile = FixFileUrl(Tokenize(theme.Theme, web.Url));
                        template.ComposedLook.FontFile = FixFileUrl(Tokenize(theme.Font, web.Url));

                        // Create file entries for the custom theme files
                        if (!string.IsNullOrEmpty(template.ComposedLook.BackgroundFile))
                        {
                            template.Files.Add(GetComposedLookFile(template.ComposedLook.BackgroundFile));
                        }
                        if (!string.IsNullOrEmpty(template.ComposedLook.ColorFile))
                        {
                            template.Files.Add(GetComposedLookFile(template.ComposedLook.ColorFile));
                        }
                        if (!string.IsNullOrEmpty(template.ComposedLook.FontFile))
                        {

                            template.Files.Add(GetComposedLookFile(template.ComposedLook.FontFile));
                        }
                        if (!string.IsNullOrEmpty(template.ComposedLook.SiteLogo))
                        {
                            template.Files.Add(GetComposedLookFile(template.ComposedLook.SiteLogo));
                        }

                        // If a base template is specified then use that one to "cleanup" the generated template model
                        if (creationInfo != null && creationInfo.BaseTemplate != null)
                        {
                            template = CleanupEntities(template, creationInfo.BaseTemplate);
                        }
                    }
                    else
                    {
                        template.ComposedLook.BackgroundFile = "";
                        template.ComposedLook.ColorFile = "";
                        template.ComposedLook.FontFile = "";
                    }
                }
                else
                {
                    template.ComposedLook = null;
                }

                if (creationInfo != null && creationInfo.BaseTemplate != null)
                {
                    template = CleanupEntities(template, creationInfo.BaseTemplate);
                }
            }
            return template;
        }
        private void ProvisionCustomActionImplementation(object parent, CustomActionCollection customActions, TokenParser parser, PnPMonitoredScope scope)
        {
            Web web = null;
            Site site = null;
            if (parent is Site)
            {
                site = parent as Site;

                // Switch parser context;
                parser.Rebase(site.RootWeb);
            }
            else
            {
                web = parent as Web;

                // Switch parser context
                parser.Rebase(web);
            }
            foreach (var customAction in customActions)
            {
                var caExists = false;
                if (site != null)
                {
                    caExists = site.CustomActionExists(customAction.Name);
                }
                else
                {
                    caExists = web.CustomActionExists(customAction.Name);
                }

                // If the CustomAction does not exist, we don't have to remove it, and it is enabled
                if (!caExists && !customAction.Remove && customAction.Enabled)
                {
                    // Then we add it to the target
                    var customActionEntity = new CustomActionEntity()
                    {
                        CommandUIExtension = customAction.CommandUIExtension != null ? parser.ParseString(customAction.CommandUIExtension.ToString()) : string.Empty,
                        Description = parser.ParseString(customAction.Description),
                        Group = customAction.Group,
                        ImageUrl = parser.ParseString(customAction.ImageUrl),
                        Location = customAction.Location,
                        Name = customAction.Name,
                        RegistrationId = customAction.RegistrationId,
                        RegistrationType = customAction.RegistrationType,
                        Remove = customAction.Remove,
                        Rights = customAction.Rights,
                        ScriptBlock = parser.ParseString(customAction.ScriptBlock),
                        ScriptSrc = parser.ParseString(customAction.ScriptSrc, "~site", "~sitecollection"),
                        Sequence = customAction.Sequence,
                        Title = parser.ParseString(customAction.Title),
                        Url = parser.ParseString(customAction.Url)
                    };

                    if (site != null)
                    {
                        scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Adding_custom_action___0___to_scope_Site, customActionEntity.Name);
                        site.AddCustomAction(customActionEntity);
            #if !ONPREMISES
                        if ((!string.IsNullOrEmpty(customAction.Title) && customAction.Title.ContainsResourceToken()) ||
                            (!string.IsNullOrEmpty(customAction.Description) && customAction.Description.ContainsResourceToken()))
                        {
                            var uca = site.GetCustomActions().Where(uc => uc.Name == customAction.Name).FirstOrDefault();
                            SetCustomActionResourceValues(parser, customAction, uca);
                        }
            #endif
                    }
                    else
                    {
                        scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Adding_custom_action___0___to_scope_Web, customActionEntity.Name);
                        web.AddCustomAction(customActionEntity);
            #if !ONPREMISES
                        if (customAction.Title.ContainsResourceToken() || customAction.Description.ContainsResourceToken())
                        {
                            var uca = web.GetCustomActions().Where(uc => uc.Name == customAction.Name).FirstOrDefault();
                            SetCustomActionResourceValues(parser, customAction, uca);
                        }
            #endif
                    }
                }
                else
                {
                    UserCustomAction existingCustomAction = null;
                    if (site != null)
                    {
                        existingCustomAction = site.GetCustomActions().FirstOrDefault(c => c.Name == customAction.Name);
                    }
                    else
                    {
                        existingCustomAction = web.GetCustomActions().FirstOrDefault(c => c.Name == customAction.Name);
                    }
                    if (existingCustomAction != null)
                    {
                        // If we have to remove the existing CustomAction
                        if (customAction.Remove)
                        {
                            // We simply remove it
                            existingCustomAction.DeleteObject();
                            existingCustomAction.Context.ExecuteQueryRetry();
                        }
                        else
                        {
                            UpdateCustomAction(parser, scope, customAction, existingCustomAction);
                        }
                    }
                }
            }
        }
Example #12
0
        public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                var context = web.Context as ClientContext;

                web.EnsureProperties(w => w.ServerRelativeUrl, w => w.Url);

                foreach (var file in template.Files)
                {
                    var folderName = parser.ParseString(file.Folder);

                    if (folderName.ToLower().StartsWith((web.ServerRelativeUrl.ToLower())))
                    {
                        folderName = folderName.Substring(web.ServerRelativeUrl.Length);
                    }

                    var folder = web.EnsureFolderPath(folderName);

                    File targetFile = null;

                    var checkedOut = false;

                    targetFile = folder.GetFile(template.Connector.GetFilenamePart(file.Src));

                    if (targetFile != null)
                    {
                        if (file.Overwrite)
                        {
                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Files_Uploading_and_overwriting_existing_file__0_, file.Src);
                            checkedOut = CheckOutIfNeeded(web, targetFile);

                            using (var stream = GetFileStream(template, file))
                            {
                                targetFile = UploadFile(template, file, folder, stream);
                            }
                        }
                        else
                        {
                            checkedOut = CheckOutIfNeeded(web, targetFile);
                        }
                    }
                    else
                    {
                        using (var stream = GetFileStream(template, file))
                        {
                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Files_Uploading_file__0_, file.Src);
                            targetFile = UploadFile(template, file, folder, stream);
                        }

                        checkedOut = CheckOutIfNeeded(web, targetFile);
                    }

                    if (targetFile != null)
                    {
                        if (file.Properties != null && file.Properties.Any())
                        {
                            Dictionary<string, string> transformedProperties = file.Properties.ToDictionary(property => property.Key, property => parser.ParseString(property.Value));
                            SetFileProperties(targetFile, transformedProperties, false);
                        }

                        if (file.WebParts != null && file.WebParts.Any())
                        {
                            targetFile.EnsureProperties(f => f.ServerRelativeUrl);

                            var existingWebParts = web.GetWebParts(targetFile.ServerRelativeUrl);
                            foreach (var webpart in file.WebParts)
                            {
                                // check if the webpart is already set on the page
                                if (existingWebParts.FirstOrDefault(w => w.WebPart.Title == webpart.Title) == null)
                                {
                                    scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Files_Adding_webpart___0___to_page, webpart.Title);
                                    var wpEntity = new WebPartEntity();
                                    wpEntity.WebPartTitle = webpart.Title;
                                    wpEntity.WebPartXml = parser.ParseString(webpart.Contents).Trim(new[] { '\n', ' ' });
                                    wpEntity.WebPartZone = webpart.Zone;
                                    wpEntity.WebPartIndex = (int)webpart.Order;
                                    web.AddWebPartToWebPartPage(targetFile.ServerRelativeUrl, wpEntity);
                                }
                            }
                        }

                        if (checkedOut)
                        {
                            targetFile.CheckIn("", CheckinType.MajorCheckIn);
                            web.Context.ExecuteQueryRetry();
                        }

                        // Don't set security when nothing is defined. This otherwise breaks on files set outside of a list
                        if (file.Security != null &&
                            (file.Security.ClearSubscopes == true || file.Security.CopyRoleAssignments == true || file.Security.RoleAssignments.Count > 0))
                        {
                            targetFile.ListItemAllFields.SetSecurity(parser, file.Security);
                        }
                    }

                }
            }
            return parser;
        }
Example #13
0
        public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                var context = web.Context as ClientContext;

                web.EnsureProperties(w => w.ServerRelativeUrl, w => w.RootFolder.WelcomePage);

                foreach (var page in template.Pages)
                {
                    var url = parser.ParseString(page.Url);

                    if (!url.ToLower().StartsWith(web.ServerRelativeUrl.ToLower()))
                    {
                        url = UrlUtility.Combine(web.ServerRelativeUrl, url);
                    }

                    var exists = true;
                    Microsoft.SharePoint.Client.File file = null;
                    try
                    {
                        file = web.GetFileByServerRelativeUrl(url);
                        web.Context.Load(file);
                        web.Context.ExecuteQuery();
                    }
                    catch (ServerException ex)
                    {
                        if (ex.ServerErrorTypeName == "System.IO.FileNotFoundException")
                        {
                            exists = false;
                        }
                    }
                    if (exists)
                    {
                        if (page.Overwrite)
                        {
                            try
                            {
                                scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Pages_Overwriting_existing_page__0_, url);

                                if (page.WelcomePage && url.Contains(web.RootFolder.WelcomePage))
                                {
                                    web.SetHomePage(string.Empty);
                                }

                                file.DeleteObject();
                                web.Context.ExecuteQueryRetry();
                                web.AddWikiPageByUrl(url);
                                if (page.Layout == WikiPageLayout.Custom)
                                {
                                    web.AddLayoutToWikiPage(WikiPageLayout.OneColumn, url);
                                }
                                else
                                {
                                    web.AddLayoutToWikiPage(page.Layout, url);
                                }
                            }
                            catch (Exception ex)
                            {
                                scope.LogError(CoreResources.Provisioning_ObjectHandlers_Pages_Overwriting_existing_page__0__failed___1_____2_, url, ex.Message, ex.StackTrace);
                            }
                        }
                    }
                    else
                    {
                        try
                        {
                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Pages_Creating_new_page__0_, url);

                            web.AddWikiPageByUrl(url);
                            if (page.Layout == WikiPageLayout.Custom)
                            {
                                web.AddLayoutToWikiPage(WikiPageLayout.OneColumn, url);
                            }
                            else
                            {
                                web.AddLayoutToWikiPage(page.Layout, url);
                            }
                        }
                        catch (Exception ex)
                        {
                            scope.LogError(CoreResources.Provisioning_ObjectHandlers_Pages_Creating_new_page__0__failed___1_____2_, url, ex.Message, ex.StackTrace);
                        }
                    }

                    if (page.WelcomePage)
                    {
                        web.RootFolder.EnsureProperty(p => p.ServerRelativeUrl);
                        var rootFolderRelativeUrl = url.Substring(web.RootFolder.ServerRelativeUrl.Length);
                        web.SetHomePage(rootFolderRelativeUrl);
                    }

                    if (page.WebParts != null & page.WebParts.Any())
                    {
                        var existingWebParts = web.GetWebParts(url);

                        foreach (var webpart in page.WebParts)
                        {
                            if (existingWebParts.FirstOrDefault(w => w.WebPart.Title == webpart.Title) == null)
                            {
                                WebPartEntity wpEntity = new WebPartEntity();
                                wpEntity.WebPartTitle = webpart.Title;
                                wpEntity.WebPartXml   = parser.ParseString(webpart.Contents.Trim(new[] { '\n', ' ' }));
                                web.AddWebPartToWikiPage(url, wpEntity, (int)webpart.Row, (int)webpart.Column, false);
                            }
                        }
                        var allWebParts = web.GetWebParts(url);
                        foreach (var webpart in allWebParts)
                        {
                            parser.AddToken(new WebPartIdToken(web, webpart.WebPart.Title, webpart.Id));
                        }
                    }

                    file = web.GetFileByServerRelativeUrl(url);
                    file.EnsureProperty(f => f.ListItemAllFields);

                    if (page.Fields.Any())
                    {
                        var item = file.ListItemAllFields;
                        foreach (var fieldValue in page.Fields)
                        {
                            item[fieldValue.Key] = parser.ParseString(fieldValue.Value);
                        }
                        item.Update();
                        web.Context.ExecuteQueryRetry();
                    }
                    if (page.Security != null && page.Security.RoleAssignments.Count != 0)
                    {
                        web.Context.Load(file.ListItemAllFields);
                        web.Context.ExecuteQuery();
                        file.ListItemAllFields.SetSecurity(parser, page.Security);
                    }
                }
            }
            return(parser);
        }
Example #14
0
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                GlobalNavigationType  globalNavigationType;
                CurrentNavigationType currentNavigationType;

                // The Navigation handler works only for sites with Publishing Features enabled
                if (!web.IsPublishingWeb())
                {
                    scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Navigation_Context_web_is_not_publishing);
                    return(template);
                }

                // Retrieve the current web navigation settings
                var navigationSettings = new WebNavigationSettings(web.Context, web);
                web.Context.Load(navigationSettings, ns => ns.CurrentNavigation, ns => ns.GlobalNavigation);
                web.Context.ExecuteQueryRetry();

                switch (navigationSettings.GlobalNavigation.Source)
                {
                case StandardNavigationSource.InheritFromParentWeb:
                    // Global Navigation is Inherited
                    globalNavigationType = GlobalNavigationType.Inherit;
                    break;

                case StandardNavigationSource.TaxonomyProvider:
                    // Global Navigation is Managed
                    globalNavigationType = GlobalNavigationType.Managed;
                    break;

                case StandardNavigationSource.PortalProvider:
                default:
                    // Global Navigation is Structural
                    globalNavigationType = GlobalNavigationType.Structural;
                    break;
                }

                switch (navigationSettings.CurrentNavigation.Source)
                {
                case StandardNavigationSource.InheritFromParentWeb:
                    // Current Navigation is Inherited
                    currentNavigationType = CurrentNavigationType.Inherit;
                    break;

                case StandardNavigationSource.TaxonomyProvider:
                    // Current Navigation is Managed
                    currentNavigationType = CurrentNavigationType.Managed;
                    break;

                case StandardNavigationSource.PortalProvider:
                default:
                    // Current Navigation is Structural
                    if (AreSiblingsEnabledForCurrentStructuralNavigation(web))
                    {
                        currentNavigationType = CurrentNavigationType.Structural;
                    }
                    else
                    {
                        currentNavigationType = CurrentNavigationType.StructuralLocal;
                    }
                    break;
                }

                template.Navigation = new Model.Navigation(
                    new GlobalNavigation(globalNavigationType,
                                         globalNavigationType == GlobalNavigationType.Structural ? GetGlobalStructuralNavigation(web, navigationSettings) : null,
                                         globalNavigationType == GlobalNavigationType.Managed ? GetGlobalManagedNavigation(web, navigationSettings) : null),
                    new CurrentNavigation(currentNavigationType,
                                          currentNavigationType == CurrentNavigationType.Structural | currentNavigationType == CurrentNavigationType.StructuralLocal ? GetCurrentStructuralNavigation(web, navigationSettings) : null,
                                          currentNavigationType == CurrentNavigationType.Managed ? GetCurrentManagedNavigation(web, navigationSettings) : null)
                    );
            }

            return(template);
        }
        public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {

                if (template.Lists.Any())
                {
                    var rootWeb = (web.Context as ClientContext).Site.RootWeb;

                    web.EnsureProperties(w => w.ServerRelativeUrl);

                    web.Context.Load(web.Lists, lc => lc.IncludeWithDefaultProperties(l => l.RootFolder.ServerRelativeUrl));
                    web.Context.ExecuteQueryRetry();
                    var existingLists = web.Lists.AsEnumerable<List>().Select(existingList => existingList.RootFolder.ServerRelativeUrl).ToList();
                    var serverRelativeUrl = web.ServerRelativeUrl;

                    #region DataRows

                    foreach (var listInstance in template.Lists)
                    {
                        if (listInstance.DataRows != null && listInstance.DataRows.Any())
                        {
                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Processing_data_rows_for__0_, listInstance.Title);
                            // Retrieve the target list
                            var list = web.Lists.GetByTitle(listInstance.Title);
                            web.Context.Load(list);

                            // Retrieve the fields' types from the list
                            FieldCollection fields = list.Fields;
                            web.Context.Load(fields, fs => fs.Include(f => f.InternalName, f => f.FieldTypeKind));
                            web.Context.ExecuteQueryRetry();

                            foreach (var dataRow in listInstance.DataRows)
                            {
                                try
                                {
                                    scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Creating_list_item__0_, listInstance.DataRows.IndexOf(dataRow) + 1);
                                    var listitemCI = new ListItemCreationInformation();
                                    var listitem = list.AddItem(listitemCI);

                                    foreach (var dataValue in dataRow.Values)
                                    {
                                        Field dataField = fields.FirstOrDefault(
                                            f => f.InternalName == parser.ParseString(dataValue.Key));

                                        if (dataField != null)
                                        {
                                            String fieldValue = parser.ParseString(dataValue.Value);

                                            switch (dataField.FieldTypeKind)
                                            {
                                                case FieldType.Geolocation:
                                                    // FieldGeolocationValue - Expected format: Altitude,Latitude,Longitude,Measure
                                                    var geolocationArray = fieldValue.Split(',');
                                                    if (geolocationArray.Length == 4)
                                                    {
                                                        var geolocationValue = new FieldGeolocationValue
                                                        {
                                                            Altitude = Double.Parse(geolocationArray[0]),
                                                            Latitude = Double.Parse(geolocationArray[1]),
                                                            Longitude = Double.Parse(geolocationArray[2]),
                                                            Measure = Double.Parse(geolocationArray[3]),
                                                        };
                                                        listitem[parser.ParseString(dataValue.Key)] = geolocationValue;
                                                    }
                                                    else
                                                    {
                                                        listitem[parser.ParseString(dataValue.Key)] = fieldValue;
                                                    }
                                                    break;
                                                case FieldType.Lookup:
                                                    // FieldLookupValue - Expected format: LookupID
                                                    var lookupValue = new FieldLookupValue
                                                    {
                                                        LookupId = Int32.Parse(fieldValue),
                                                    };
                                                    listitem[parser.ParseString(dataValue.Key)] = lookupValue;
                                                    break;
                                                case FieldType.URL:
                                                    // FieldUrlValue - Expected format: URL,Description
                                                    var urlArray = fieldValue.Split(',');
                                                    var linkValue = new FieldUrlValue();
                                                    if (urlArray.Length == 2)
                                                    {
                                                        linkValue.Url = urlArray[0];
                                                        linkValue.Description = urlArray[1];
                                                    }
                                                    else
                                                    {
                                                        linkValue.Url = urlArray[0];
                                                        linkValue.Description = urlArray[0];
                                                    }
                                                    listitem[parser.ParseString(dataValue.Key)] = linkValue;
                                                    break;
                                                case FieldType.User:
                                                    // FieldUserValue - Expected format: loginName
                                                    var user = web.EnsureUser(fieldValue);
                                                    web.Context.Load(user);
                                                    web.Context.ExecuteQueryRetry();

                                                    if (user != null)
                                                    {
                                                        var userValue = new FieldUserValue
                                                        {
                                                            LookupId = user.Id,
                                                        };
                                                        listitem[parser.ParseString(dataValue.Key)] = userValue;
                                                    }
                                                    else
                                                    {
                                                        listitem[parser.ParseString(dataValue.Key)] = fieldValue;
                                                    }
                                                    break;
                                                default:
                                                    listitem[parser.ParseString(dataValue.Key)] = fieldValue;
                                                    break;
                                            }
                                        }
                                        listitem.Update();
                                    }
                                    web.Context.ExecuteQueryRetry(); // TODO: Run in batches?

                                    if (dataRow.Security != null)
                                    {
                                        listitem.SetSecurity(parser, dataRow.Security);
                                    }
                                }
                                catch (Exception ex)
                                {
                                    scope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Creating_listitem_failed___0_____1_, ex.Message, ex.StackTrace);
                                    throw;
                                }
                            }
                        }
                    }

                    #endregion
                }
            }

            return parser;
        }
Example #16
0
        public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                // Check if this is not a noscript site as we're not allowed to write to the web property bag is that one
                bool isNoScriptSite = web.IsNoScriptSite();

                var context = web.Context as ClientContext;

                web.EnsureProperties(w => w.ServerRelativeUrl, w => w.Url);

                // Build on the fly the list of additional files coming from the Directories
                var directoryFiles = new List <Model.File>();
                foreach (var directory in template.Directories)
                {
                    var metadataProperties = directory.GetMetadataProperties();
                    directoryFiles.AddRange(directory.GetDirectoryFiles(metadataProperties));
                }

                var filesToProcess   = template.Files.Union(directoryFiles).ToArray();
                var currentFileIndex = 0;
                foreach (var file in filesToProcess)
                {
                    var targetFileName = !String.IsNullOrEmpty(file.TargetFileName) ? file.TargetFileName : file.Src;

                    currentFileIndex++;
                    WriteMessage($"File|{targetFileName}|{currentFileIndex}|{filesToProcess.Length}", ProvisioningMessageType.Progress);
                    var folderName = parser.ParseString(file.Folder);

                    if (folderName.ToLower().StartsWith((web.ServerRelativeUrl.ToLower())))
                    {
                        folderName = folderName.Substring(web.ServerRelativeUrl.Length);
                    }

                    if (SkipFile(isNoScriptSite, targetFileName, folderName))
                    {
                        // add log message
                        scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_Files_SkipFileUpload, targetFileName, folderName);
                        continue;
                    }

                    var folder = web.EnsureFolderPath(folderName);

                    var checkedOut = false;

                    var targetFile = folder.GetFile(template.Connector.GetFilenamePart(targetFileName));

                    if (targetFile != null)
                    {
                        if (file.Overwrite)
                        {
                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Files_Uploading_and_overwriting_existing_file__0_, targetFileName);
                            checkedOut = CheckOutIfNeeded(web, targetFile);

                            using (var stream = GetFileStream(template, file))
                            {
                                targetFile = UploadFile(template, file, folder, stream);
                            }
                        }
                        else
                        {
                            checkedOut = CheckOutIfNeeded(web, targetFile);
                        }
                    }
                    else
                    {
                        using (var stream = GetFileStream(template, file))
                        {
                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Files_Uploading_file__0_, targetFileName);
                            targetFile = UploadFile(template, file, folder, stream);
                        }

                        checkedOut = CheckOutIfNeeded(web, targetFile);
                    }

                    if (targetFile != null)
                    {
                        if (file.Properties != null && file.Properties.Any())
                        {
                            Dictionary <string, string> transformedProperties = file.Properties.ToDictionary(property => property.Key, property => parser.ParseString(property.Value));
                            SetFileProperties(targetFile, transformedProperties, false);
                        }

#if !SP2013
                        bool webPartsNeedLocalization = false;
#endif
                        if (file.WebParts != null && file.WebParts.Any())
                        {
                            targetFile.EnsureProperties(f => f.ServerRelativeUrl);

                            var existingWebParts = web.GetWebParts(targetFile.ServerRelativeUrl).ToList();
                            foreach (var webPart in file.WebParts)
                            {
                                // check if the webpart is already set on the page
                                if (existingWebParts.FirstOrDefault(w => w.WebPart.Title == parser.ParseString(webPart.Title)) == null)
                                {
                                    scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Files_Adding_webpart___0___to_page, webPart.Title);
                                    var wpEntity = new WebPartEntity();
                                    wpEntity.WebPartTitle = parser.ParseString(webPart.Title);
                                    wpEntity.WebPartXml   = parser.ParseXmlString(webPart.Contents).Trim(new[] { '\n', ' ' });
                                    wpEntity.WebPartZone  = webPart.Zone;
                                    wpEntity.WebPartIndex = (int)webPart.Order;
                                    var wpd = web.AddWebPartToWebPartPage(targetFile.ServerRelativeUrl, wpEntity);
#if !SP2013
                                    if (webPart.Title.ContainsResourceToken())
                                    {
                                        // update data based on where it was added - needed in order to localize wp title
#if !SP2016
                                        wpd.EnsureProperties(w => w.ZoneId, w => w.WebPart, w => w.WebPart.Properties);
                                        webPart.Zone = wpd.ZoneId;
#else
                                        wpd.EnsureProperties(w => w.WebPart, w => w.WebPart.Properties);
#endif
                                        webPart.Order            = (uint)wpd.WebPart.ZoneIndex;
                                        webPartsNeedLocalization = true;
                                    }
#endif
                                }
                            }
                        }

#if !SP2013
                        if (webPartsNeedLocalization)
                        {
                            file.LocalizeWebParts(web, parser, targetFile, scope);
                        }
#endif

                        switch (file.Level)
                        {
                        case Model.FileLevel.Published:
                        {
                            targetFile.PublishFileToLevel(Microsoft.SharePoint.Client.FileLevel.Published);
                            break;
                        }

                        case Model.FileLevel.Draft:
                        {
                            targetFile.PublishFileToLevel(Microsoft.SharePoint.Client.FileLevel.Draft);
                            break;
                        }

                        default:
                        {
                            if (checkedOut)
                            {
                                targetFile.CheckIn("", CheckinType.MajorCheckIn);
                                web.Context.ExecuteQueryRetry();
                            }
                            break;
                        }
                        }

                        // Don't set security when nothing is defined. This otherwise breaks on files set outside of a list
                        if (file.Security != null &&
                            (file.Security.ClearSubscopes == true || file.Security.CopyRoleAssignments == true || file.Security.RoleAssignments.Count > 0))
                        {
                            targetFile.ListItemAllFields.SetSecurity(parser, file.Security);
                        }
                    }
                }
            }
            WriteMessage("Done processing files", ProvisioningMessageType.Completed);
            return(parser);
        }
Example #17
0
        public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                var context = web.Context as ClientContext;

                web.EnsureProperties(w => w.ServerRelativeUrl, w => w.RootFolder.WelcomePage);

                // Check if this is not a noscript site as we're not allowed to update some properties
                bool isNoScriptSite = web.IsNoScriptSite();

                foreach (var page in template.Pages)
                {
                    var url = parser.ParseString(page.Url);

                    if (!url.ToLower().StartsWith(web.ServerRelativeUrl.ToLower()))
                    {
                        url = UrlUtility.Combine(web.ServerRelativeUrl, url);
                    }

                    var exists = true;
                    Microsoft.SharePoint.Client.File file = null;
                    try
                    {
                        file = web.GetFileByServerRelativeUrl(url);
                        web.Context.Load(file);
                        web.Context.ExecuteQueryRetry();
                    }
                    catch (ServerException ex)
                    {
                        if (ex.ServerErrorTypeName == "System.IO.FileNotFoundException")
                        {
                            exists = false;
                        }
                    }
                    if (exists)
                    {
                        if (page.Overwrite)
                        {
                            try
                            {
                                scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Pages_Overwriting_existing_page__0_, url);

                                // determine url of current home page
                                string welcomePageUrl = web.RootFolder.WelcomePage;
                                string welcomePageServerRelativeUrl = welcomePageUrl != null
                                    ? UrlUtility.Combine(web.ServerRelativeUrl, web.RootFolder.WelcomePage)
                                    : null;

                                bool overwriteWelcomePage = string.Equals(url, welcomePageServerRelativeUrl, StringComparison.InvariantCultureIgnoreCase);

                                // temporarily reset home page so we can delete it
                                if (overwriteWelcomePage)
                                {
                                    web.SetHomePage(string.Empty);
                                }

                                file.DeleteObject();
                                web.Context.ExecuteQueryRetry();
                                web.AddWikiPageByUrl(url);
                                if (page.Layout == WikiPageLayout.Custom)
                                {
                                    web.AddLayoutToWikiPage(WikiPageLayout.OneColumn, url);
                                }
                                else
                                {
                                    web.AddLayoutToWikiPage(page.Layout, url);
                                }

                                if (overwriteWelcomePage)
                                {
                                    // restore welcome page to previous value
                                    web.SetHomePage(welcomePageUrl);
                                }
                            }
                            catch (Exception ex)
                            {
                                scope.LogError(CoreResources.Provisioning_ObjectHandlers_Pages_Overwriting_existing_page__0__failed___1_____2_, url, ex.Message, ex.StackTrace);
                            }
                        }
                    }
                    else
                    {
                        try
                        {
                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Pages_Creating_new_page__0_, url);

                            web.AddWikiPageByUrl(url);
                            if (page.Layout == WikiPageLayout.Custom)
                            {
                                web.AddLayoutToWikiPage(WikiPageLayout.OneColumn, url);
                            }
                            else
                            {
                                web.AddLayoutToWikiPage(page.Layout, url);
                            }
                        }
                        catch (Exception ex)
                        {
                            scope.LogError(CoreResources.Provisioning_ObjectHandlers_Pages_Creating_new_page__0__failed___1_____2_, url, ex.Message, ex.StackTrace);
                        }
                    }

#pragma warning disable 618
                    if (page.WelcomePage)
#pragma warning restore 618
                    {
                        web.RootFolder.EnsureProperty(p => p.ServerRelativeUrl);
                        var rootFolderRelativeUrl = url.Substring(web.RootFolder.ServerRelativeUrl.Length);
                        web.SetHomePage(rootFolderRelativeUrl);
                    }

#if !SP2013
                    bool webPartsNeedLocalization = false;
#endif
                    if (page.WebParts != null & page.WebParts.Any())
                    {
                        if (!isNoScriptSite)
                        {
                            var existingWebParts = web.GetWebParts(url);

                            foreach (var webPart in page.WebParts)
                            {
                                if (existingWebParts.FirstOrDefault(w => w.WebPart.Title == parser.ParseString(webPart.Title)) == null)
                                {
                                    WebPartEntity wpEntity = new WebPartEntity();
                                    wpEntity.WebPartTitle = parser.ParseString(webPart.Title);
                                    wpEntity.WebPartXml   = parser.ParseXmlString(webPart.Contents.Trim(new[] { '\n', ' ' }), "~sitecollection", "~site");
                                    var wpd = web.AddWebPartToWikiPage(url, wpEntity, (int)webPart.Row, (int)webPart.Column, false);
#if !SP2013
                                    if (webPart.Title.ContainsResourceToken())
                                    {
                                        // update data based on where it was added - needed in order to localize wp title
#if !SP2016
                                        wpd.EnsureProperties(w => w.ZoneId, w => w.WebPart, w => w.WebPart.Properties);
                                        webPart.Zone = wpd.ZoneId;
#else
                                        wpd.EnsureProperties(w => w.WebPart, w => w.WebPart.Properties);
#endif
                                        webPart.Order            = (uint)wpd.WebPart.ZoneIndex;
                                        webPartsNeedLocalization = true;
                                    }
#endif
                                }
                            }

                            // Remove any existing WebPartIdToken tokens in the parser that were added by other pages. They won't apply to this page,
                            // and they'll cause issues if this page contains web parts with the same name as web parts on other pages.
                            parser.Tokens.RemoveAll(t => t is WebPartIdToken);

                            var allWebParts = web.GetWebParts(url);
                            foreach (var webpart in allWebParts)
                            {
                                parser.AddToken(new WebPartIdToken(web, webpart.WebPart.Title, webpart.Id));
                            }
                        }
                        else
                        {
                            scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_Pages_SkipAddingWebParts, page.Url);
                        }
                    }

#if !SP2013
                    if (webPartsNeedLocalization)
                    {
                        page.LocalizeWebParts(web, parser, scope);
                    }
#endif

                    file = web.GetFileByServerRelativeUrl(url);
                    file.EnsureProperty(f => f.ListItemAllFields);

                    if (page.Fields.Any())
                    {
                        var item = file.ListItemAllFields;
                        foreach (var fieldValue in page.Fields)
                        {
                            item[fieldValue.Key] = parser.ParseString(fieldValue.Value);
                        }
                        item.Update();
                        web.Context.ExecuteQueryRetry();
                    }
                    if (page.Security != null && page.Security.RoleAssignments.Count != 0)
                    {
                        web.Context.Load(file.ListItemAllFields);
                        web.Context.ExecuteQueryRetry();
                        file.ListItemAllFields.SetSecurity(parser, page.Security);
                    }
                }
            }
            return(parser);
        }
Example #18
0
        public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                var context = web.Context as ClientContext;
                var site    = (web.Context as ClientContext).Site;

                // Check if this is not a noscript site as publishing features are not supported
                if (web.IsNoScriptSite())
                {
                    scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_Publishing_SkipProvisioning);
                    return(parser);
                }

                var webFeatureActive  = web.IsFeatureActive(Constants.FeatureId_Web_Publishing);
                var siteFeatureActive = site.IsFeatureActive(Constants.FeatureId_Site_Publishing);
                if (template.Publishing.AutoCheckRequirements == AutoCheckRequirementsOptions.SkipIfNotCompliant && !webFeatureActive)
                {
                    scope.LogDebug("Publishing Feature (Web Scoped) not active. Skipping provisioning of Publishing Image Renditions");
                    return(parser);
                }
                else if (template.Publishing.AutoCheckRequirements == AutoCheckRequirementsOptions.MakeCompliant)
                {
                    if (!siteFeatureActive)
                    {
                        scope.LogDebug("Making site compliant for publishing");
                        site.ActivateFeature(Constants.FeatureId_Site_Publishing);
                        web.ActivateFeature(Constants.FeatureId_Web_Publishing);
                    }
                    else
                    {
                        if (!web.IsFeatureActive(Constants.FeatureId_Web_Publishing))
                        {
                            scope.LogDebug("Making site compliant for publishing");
                            web.ActivateFeature(Constants.FeatureId_Web_Publishing);
                        }
                    }
                }
                else if (!webFeatureActive)
                {
                    throw new Exception("Publishing Feature not active. Provisioning failed");
                }

                if (template.Publishing != null &&
                    template.Publishing.ImageRenditions != null &&
                    template.Publishing.ImageRenditions.Count > 0)
                {
                    var renditions = SiteImageRenditions.GetRenditions(context);
                    context.ExecuteQueryRetry();

                    foreach (var r in template.Publishing.ImageRenditions)
                    {
                        var rendition = new Microsoft.SharePoint.Client.Publishing.ImageRendition();
                        rendition.Name   = r.Name;
                        rendition.Height = r.Height;
                        rendition.Width  = r.Width;

                        if (!renditions.Contains(rendition))
                        {
                            renditions.Add(rendition);
                        }
                    }

                    SiteImageRenditions.SetRenditions(context, renditions);
                    context.ExecuteQueryRetry();
                }
            }
            return(parser);
        }
Example #19
0
        public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                var site = (web.Context as ClientContext).Site;

                // Check if this is not a noscript site as publishing features are not supported
                if (web.IsNoScriptSite())
                {
                    scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_Publishing_SkipProvisioning);
                    return(parser);
                }

                var webFeatureActive  = web.IsFeatureActive(Constants.FeatureId_Web_Publishing);
                var siteFeatureActive = site.IsFeatureActive(Constants.FeatureId_Site_Publishing);
                if (template.Publishing.AutoCheckRequirements == AutoCheckRequirementsOptions.SkipIfNotCompliant && !webFeatureActive)
                {
                    scope.LogDebug("Publishing Feature (Web Scoped) not active. Skipping provisioning of Publishing settings");
                    return(parser);
                }
                else if (template.Publishing.AutoCheckRequirements == AutoCheckRequirementsOptions.MakeCompliant)
                {
                    if (!siteFeatureActive)
                    {
                        scope.LogDebug("Making site compliant for publishing");
                        site.ActivateFeature(Constants.FeatureId_Site_Publishing);
                        web.ActivateFeature(Constants.FeatureId_Web_Publishing);
                    }
                    else
                    {
                        if (!web.IsFeatureActive(Constants.FeatureId_Web_Publishing))
                        {
                            scope.LogDebug("Making site compliant for publishing");
                            web.ActivateFeature(Constants.FeatureId_Web_Publishing);
                        }
                    }
                }
                else if (!webFeatureActive)
                {
                    throw new Exception("Publishing Feature not active. Provisioning failed");
                }

                // Set allowed web templates
                var availableWebTemplates = template.Publishing.AvailableWebTemplates.Select(t => new WebTemplateEntity()
                {
                    LanguageCode = t.LanguageCode.ToString(), TemplateName = t.TemplateName
                }).ToList();
                if (availableWebTemplates.Any())
                {
                    web.SetAvailableWebTemplates(availableWebTemplates);
                }

                if (template.Publishing.DesignPackage != null)
                {
                    var package = template.Publishing.DesignPackage;

                    var tempFileName = Path.Combine(Path.GetTempPath(), template.Connector.GetFilenamePart(package.DesignPackagePath));
                    scope.LogDebug("Saving {0} to temporary file: {1}", package.DesignPackagePath, tempFileName);
                    using (var stream = template.Connector.GetFileStream(package.DesignPackagePath))
                    {
                        using (var outstream = System.IO.File.Create(tempFileName))
                        {
                            stream.CopyTo(outstream);
                        }
                    }
                    scope.LogDebug("Installing design package");
                    site.InstallSolution(package.PackageGuid, tempFileName, package.MajorVersion, package.MinorVersion);
                    System.IO.File.Delete(tempFileName);
                }
                // Set allowed page layouts
                var availablePageLayouts = template.Publishing.PageLayouts.Select(p => p.Path);
                if (availablePageLayouts.Any())
                {
                    web.SetAvailablePageLayouts(site.RootWeb, availablePageLayouts);
                }

                // Set default page layout, if any
                var defaultPageLayout = template.Publishing.PageLayouts.FirstOrDefault(p => p.IsDefault);
                if (defaultPageLayout != null)
                {
                    web.SetDefaultPageLayoutForSite(site.RootWeb, defaultPageLayout.Path);
                }


                return(parser);
            }
        }
Example #20
0
        public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                var context = web.Context as ClientContext;

                web.EnsureProperties(w => w.ServerRelativeUrl);

                foreach (var file in template.Files)
                {
                    var folderName = parser.ParseString(file.Folder);

                    if (folderName.ToLower().StartsWith((web.ServerRelativeUrl.ToLower())))
                    {
                        folderName = folderName.Substring(web.ServerRelativeUrl.Length);
                    }


                    var folder = web.EnsureFolderPath(folderName);

                    File targetFile = null;

                    var checkedOut = false;

                    targetFile = folder.GetFile(template.Connector.GetFilenamePart(file.Src));

                    if (targetFile != null)
                    {
                        if (file.Overwrite)
                        {
                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Files_Uploading_and_overwriting_existing_file__0_, file.Src);
                            checkedOut = CheckOutIfNeeded(web, targetFile);

                            using (var stream = template.Connector.GetFileStream(file.Src))
                            {
                                targetFile = folder.UploadFile(template.Connector.GetFilenamePart(file.Src), stream, file.Overwrite);
                            }
                        }
                        else
                        {
                            checkedOut = CheckOutIfNeeded(web, targetFile);
                        }
                    }
                    else
                    {
                        using (var stream = template.Connector.GetFileStream(file.Src))
                        {
                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Files_Uploading_file__0_, file.Src);
                            targetFile = folder.UploadFile(template.Connector.GetFilenamePart(file.Src), stream, file.Overwrite);
                        }

                        checkedOut = CheckOutIfNeeded(web, targetFile);
                    }

                    if (targetFile != null)
                    {
                        if (file.Properties != null && file.Properties.Any())
                        {
                            Dictionary <string, string> transformedProperties = file.Properties.ToDictionary(property => property.Key, property => parser.ParseString(property.Value));
                            targetFile.SetFileProperties(transformedProperties, false); // if needed, the file is already checked out
                        }

                        if (file.WebParts != null && file.WebParts.Any())
                        {
                            targetFile.EnsureProperties(f => f.ServerRelativeUrl);

                            var existingWebParts = web.GetWebParts(targetFile.ServerRelativeUrl);
                            foreach (var webpart in file.WebParts)
                            {
                                // check if the webpart is already set on the page
                                if (existingWebParts.FirstOrDefault(w => w.WebPart.Title == webpart.Title) == null)
                                {
                                    scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Files_Adding_webpart___0___to_page, webpart.Title);
                                    var wpEntity = new WebPartEntity();
                                    wpEntity.WebPartTitle = webpart.Title;
                                    wpEntity.WebPartXml   = parser.ParseString(webpart.Contents).Trim(new[] { '\n', ' ' });
                                    wpEntity.WebPartZone  = webpart.Zone;
                                    wpEntity.WebPartIndex = (int)webpart.Order;

                                    web.AddWebPartToWebPartPage(targetFile.ServerRelativeUrl, wpEntity);
                                }
                            }
                        }

                        if (checkedOut)
                        {
                            targetFile.CheckIn("", CheckinType.MajorCheckIn);
                            web.Context.ExecuteQueryRetry();
                        }

                        // Don't set security when nothing is defined. This otherwise breaks on files set outside of a list
                        if (file.Security != null &&
                            (file.Security.ClearSubscopes == true || file.Security.CopyRoleAssignments == true || file.Security.RoleAssignments.Count > 0))
                        {
                            targetFile.ListItemAllFields.SetSecurity(parser, file.Security);
                        }
                    }
                }
            }
            return(parser);
        }
        private void ProvisionCustomActionImplementation(object parent, CustomActionCollection customActions, TokenParser parser, PnPMonitoredScope scope)
        {
            Web  web  = null;
            Site site = null;

            if (parent is Site)
            {
                site = parent as Site;

                // Switch parser context;
                parser.Rebase(site.RootWeb);
            }
            else
            {
                web = parent as Web;

                // Switch parser context
                parser.Rebase(web);
            }
            foreach (var customAction in customActions)
            {
                var caExists = false;
                if (site != null)
                {
                    caExists = site.CustomActionExists(customAction.Name);
                }
                else
                {
                    caExists = web.CustomActionExists(customAction.Name);
                }
                if (!caExists)
                {
                    var customActionEntity = new CustomActionEntity()
                    {
                        CommandUIExtension = customAction.CommandUIExtension != null?parser.ParseString(customAction.CommandUIExtension.ToString()) : string.Empty,
                                                 Description      = customAction.Description,
                                                 Group            = customAction.Group,
                                                 ImageUrl         = parser.ParseString(customAction.ImageUrl),
                                                 Location         = customAction.Location,
                                                 Name             = customAction.Name,
                                                 RegistrationId   = customAction.RegistrationId,
                                                 RegistrationType = customAction.RegistrationType,
                                                 Remove           = customAction.Remove,
                                                 Rights           = customAction.Rights,
                                                 ScriptBlock      = parser.ParseString(customAction.ScriptBlock),
                                                 ScriptSrc        = parser.ParseString(customAction.ScriptSrc, "~site", "~sitecollection"),
                                                 Sequence         = customAction.Sequence,
                                                 Title            = customAction.Title,
                                                 Url = parser.ParseString(customAction.Url)
                    };


                    if (site != null)
                    {
                        scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Adding_custom_action___0___to_scope_Site, customActionEntity.Name);
                        site.AddCustomAction(customActionEntity);
#if !CLIENTSDKV15
                        if (customAction.Title.ContainsResourceToken() || customAction.Description.ContainsResourceToken())
                        {
                            var uca = site.GetCustomActions().Where(uc => uc.Name == customAction.Name).FirstOrDefault();
                            SetCustomActionResourceValues(parser, customAction, uca);
                        }
#endif
                    }
                    else
                    {
                        scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Adding_custom_action___0___to_scope_Web, customActionEntity.Name);
                        web.AddCustomAction(customActionEntity);
#if !CLIENTSDKV15
                        if (customAction.Title.ContainsResourceToken() || customAction.Description.ContainsResourceToken())
                        {
                            var uca = web.GetCustomActions().Where(uc => uc.Name == customAction.Name).FirstOrDefault();
                            SetCustomActionResourceValues(parser, customAction, uca);
                        }
#endif
                    }
                }
                else
                {
                    UserCustomAction existingCustomAction = null;
                    if (site != null)
                    {
                        existingCustomAction = site.GetCustomActions().FirstOrDefault(c => c.Name == customAction.Name);
                    }
                    else
                    {
                        existingCustomAction = web.GetCustomActions().FirstOrDefault(c => c.Name == customAction.Name);
                    }
                    if (existingCustomAction != null)
                    {
                        var isDirty = false;

                        if (customAction.CommandUIExtension != null)
                        {
                            if (existingCustomAction.CommandUIExtension != parser.ParseString(customAction.CommandUIExtension.ToString()))
                            {
                                scope.LogPropertyUpdate("CommandUIExtension");
                                existingCustomAction.CommandUIExtension = parser.ParseString(customAction.CommandUIExtension.ToString());
                                isDirty = true;
                            }
                        }

                        if (existingCustomAction.Description != customAction.Description)
                        {
                            scope.LogPropertyUpdate("Description");
                            existingCustomAction.Description = customAction.Description;
                            isDirty = true;
                        }
#if !CLIENTSDKV15
                        if (customAction.Description.ContainsResourceToken())
                        {
                            if (existingCustomAction.DescriptionResource.SetUserResourceValue(customAction.Description, parser))
                            {
                                isDirty = true;
                            }
                        }
#endif
                        if (existingCustomAction.Group != customAction.Group)
                        {
                            scope.LogPropertyUpdate("Group");
                            existingCustomAction.Group = customAction.Group;
                            isDirty = true;
                        }
                        if (existingCustomAction.ImageUrl != parser.ParseString(customAction.ImageUrl))
                        {
                            scope.LogPropertyUpdate("ImageUrl");
                            existingCustomAction.ImageUrl = parser.ParseString(customAction.ImageUrl);
                            isDirty = true;
                        }
                        if (existingCustomAction.Location != customAction.Location)
                        {
                            scope.LogPropertyUpdate("Location");
                            existingCustomAction.Location = customAction.Location;
                            isDirty = true;
                        }
                        if (existingCustomAction.RegistrationId != customAction.RegistrationId)
                        {
                            scope.LogPropertyUpdate("RegistrationId");
                            existingCustomAction.RegistrationId = customAction.RegistrationId;
                            isDirty = true;
                        }
                        if (existingCustomAction.RegistrationType != customAction.RegistrationType)
                        {
                            scope.LogPropertyUpdate("RegistrationType");
                            existingCustomAction.RegistrationType = customAction.RegistrationType;
                            isDirty = true;
                        }
                        if (existingCustomAction.ScriptBlock != parser.ParseString(customAction.ScriptBlock))
                        {
                            scope.LogPropertyUpdate("ScriptBlock");
                            existingCustomAction.ScriptBlock = parser.ParseString(customAction.ScriptBlock);
                            isDirty = true;
                        }
                        if (existingCustomAction.ScriptSrc != parser.ParseString(customAction.ScriptSrc, "~site", "~sitecollection"))
                        {
                            scope.LogPropertyUpdate("ScriptSrc");
                            existingCustomAction.ScriptSrc = parser.ParseString(customAction.ScriptSrc, "~site", "~sitecollection");
                            isDirty = true;
                        }
                        if (existingCustomAction.Sequence != customAction.Sequence)
                        {
                            scope.LogPropertyUpdate("Sequence");
                            existingCustomAction.Sequence = customAction.Sequence;
                            isDirty = true;
                        }
                        if (existingCustomAction.Title != parser.ParseString(customAction.Title))
                        {
                            scope.LogPropertyUpdate("Title");
                            existingCustomAction.Title = parser.ParseString(customAction.Title);
                            isDirty = true;
                        }
#if !CLIENTSDKV15
                        if (customAction.Title.ContainsResourceToken())
                        {
                            if (existingCustomAction.TitleResource.SetUserResourceValue(customAction.Title, parser))
                            {
                                isDirty = true;
                            }
                        }
#endif
                        if (existingCustomAction.Url != parser.ParseString(customAction.Url))
                        {
                            scope.LogPropertyUpdate("Url");
                            existingCustomAction.Url = parser.ParseString(customAction.Url);
                            isDirty = true;
                        }
                        if (isDirty)
                        {
                            existingCustomAction.Update();
                            existingCustomAction.Context.ExecuteQueryRetry();
                        }
                    }
                }
            }
        }
Example #22
0
        public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                // Check if this is not a noscript site as we're not allowed to write to the web property bag is that one
                bool isNoScriptSite = web.IsNoScriptSite();

                var context = web.Context as ClientContext;

                web.EnsureProperties(w => w.ServerRelativeUrl, w => w.Url);

                // Build on the fly the list of additional files coming from the Directories
                var directoryFiles = new List <Model.File>();
                foreach (var directory in template.Directories)
                {
                    var metadataProperties = directory.GetMetadataProperties();
                    directoryFiles.AddRange(directory.GetDirectoryFiles(metadataProperties));
                }

                var filesToProcess   = template.Files.Union(directoryFiles).ToArray();
                var currentFileIndex = 0;
                foreach (var file in filesToProcess)
                {
                    var targetFileName = !String.IsNullOrEmpty(file.TargetFileName) ? file.TargetFileName : file.Src;

                    currentFileIndex++;
                    WriteMessage($"File|{targetFileName}|{currentFileIndex}|{filesToProcess.Length}", ProvisioningMessageType.Progress);
                    var folderName = parser.ParseString(file.Folder);

                    if (folderName.ToLower().StartsWith((web.ServerRelativeUrl.ToLower())))
                    {
                        folderName = folderName.Substring(web.ServerRelativeUrl.Length);
                    }

                    if (SkipFile(isNoScriptSite, targetFileName, folderName))
                    {
                        // add log message
                        scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_Files_SkipFileUpload, targetFileName, folderName);
                        continue;
                    }

                    var folder = web.EnsureFolderPath(folderName);

                    var checkedOut = false;

                    var targetFile = folder.GetFile(template.Connector.GetFilenamePart(targetFileName));

                    if (targetFile != null)
                    {
                        if (file.Overwrite)
                        {
                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Files_Uploading_and_overwriting_existing_file__0_, targetFileName);
                            checkedOut = CheckOutIfNeeded(web, targetFile);

                            using (var stream = GetFileStream(template, file))
                            {
                                targetFile = UploadFile(template, file, folder, stream);
                            }
                        }
                        else
                        {
                            checkedOut = CheckOutIfNeeded(web, targetFile);
                        }
                    }
                    else
                    {
                        using (var stream = GetFileStream(template, file))
                        {
        public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                if (!template.Lists.Any())
                {
                    return(parser);
                }

                web.EnsureProperties(w => w.ServerRelativeUrl);

                web.Context.Load(web.Lists, lc => lc.IncludeWithDefaultProperties(l => l.RootFolder.ServerRelativeUrl));
                web.Context.ExecuteQueryRetry();

                #region DataRows
                foreach (var listInstance in template.Lists)
                {
                    if (listInstance.DataRows == null || !listInstance.DataRows.Any())
                    {
                        continue;
                    }

                    scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Processing_data_rows_for__0_, listInstance.Title);
                    // Retrieve the target list
                    var list = web.Lists.GetByTitle(parser.ParseString(listInstance.Title));
                    web.Context.Load(list);

                    // Retrieve the fields' types from the list
                    Microsoft.SharePoint.Client.FieldCollection fields = list.Fields;
                    web.Context.Load(fields, fs => fs.Include(f => f.InternalName, f => f.FieldTypeKind, f => f.TypeAsString, f => f.ReadOnlyField, f => f.Title));
                    web.Context.ExecuteQueryRetry();

                    var keyColumnType   = "Text";
                    var parsedKeyColumn = parser.ParseString(listInstance.DataRows.KeyColumn);
                    if (!string.IsNullOrEmpty(parsedKeyColumn))
                    {
                        var keyColumn = fields.FirstOrDefault(f => f.InternalName.Equals(parsedKeyColumn, StringComparison.InvariantCultureIgnoreCase));
                        if (keyColumn != null)
                        {
                            switch (keyColumn.FieldTypeKind)
                            {
                            case FieldType.User:
                            case FieldType.Lookup:
                                keyColumnType = "Lookup";
                                break;

                            case FieldType.URL:
                                keyColumnType = "Url";
                                break;

                            case FieldType.DateTime:
                                keyColumnType = "DateTime";
                                break;

                            case FieldType.Number:
                            case FieldType.Counter:
                                keyColumnType = "Number";
                                break;
                            }
                        }
                    }

                    foreach (var dataRow in listInstance.DataRows)
                    {
                        try
                        {
                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Creating_list_item__0_, listInstance.DataRows.IndexOf(dataRow) + 1);


                            bool     processItem  = true;
                            ListItem listitem     = null;
                            var      updateValues = new List <FieldUpdateValue>();

                            if (!string.IsNullOrEmpty(listInstance.DataRows.KeyColumn))
                            {
                                // Get value from key column
                                var dataRowValues = dataRow.Values.Where(v => v.Key == listInstance.DataRows.KeyColumn).ToList();

                                // if it is empty, skip the check
                                if (dataRowValues.Any())
                                {
                                    var query     = $@"<View><Query><Where><Eq><FieldRef Name=""{parsedKeyColumn}""/><Value Type=""{keyColumnType}"">{parser.ParseString(dataRowValues.FirstOrDefault().Value)}</Value></Eq></Where></Query><RowLimit>1</RowLimit></View>";
                                    var camlQuery = new CamlQuery()
                                    {
                                        ViewXml = query
                                    };
                                    var existingItems = list.GetItems(camlQuery);
                                    list.Context.Load(existingItems);
                                    list.Context.ExecuteQueryRetry();
                                    if (existingItems.Count > 0)
                                    {
                                        if (listInstance.DataRows.UpdateBehavior == UpdateBehavior.Skip)
                                        {
                                            processItem = false;
                                        }
                                        else
                                        {
                                            listitem    = existingItems[0];
                                            processItem = true;
                                        }
                                    }
                                }
                            }

                            if (!processItem)
                            {
                                continue;
                            }

                            if (listitem == null)
                            {
                                var listitemCI = new ListItemCreationInformation();
                                listitem = list.AddItem(listitemCI);
                            }

                            foreach (var dataValue in dataRow.Values)
                            {
                                Field dataField = fields.FirstOrDefault(
                                    f => f.InternalName == parser.ParseString(dataValue.Key));

                                if (dataField != null && dataField.ReadOnlyField &&
                                    !dataField.InternalName.Equals("ContentTypeId", StringComparison.OrdinalIgnoreCase))
                                {
                                    // skip read only fields, except ContentTypeId
                                    continue;
                                }

                                if (dataField == null)
                                {
                                    continue;
                                }

                                if (dataValue.Value == null)
                                {
                                    updateValues.Add(dataField.FieldTypeKind == FieldType.Invalid
                                        ? new FieldUpdateValue(dataValue.Key, null, dataField.TypeAsString)
                                        : new FieldUpdateValue(dataValue.Key, null));
                                }
                                else
                                {
                                    String fieldValue = parser.ParseString(dataValue.Value);

                                    switch (dataField.FieldTypeKind)
                                    {
                                    case FieldType.Geolocation:
                                        // FieldGeolocationValue - Expected format: Altitude,Latitude,Longitude,Measure
                                        var geolocationArray = fieldValue.Split(',');
                                        if (geolocationArray.Length == 4)
                                        {
                                            var geolocationValue = new FieldGeolocationValue
                                            {
                                                Altitude  = Double.Parse(geolocationArray[0]),
                                                Latitude  = Double.Parse(geolocationArray[1]),
                                                Longitude = Double.Parse(geolocationArray[2]),
                                                Measure   = Double.Parse(geolocationArray[3]),
                                            };
                                            updateValues.Add(new FieldUpdateValue(dataValue.Key, geolocationValue));
                                        }
                                        else
                                        {
                                            updateValues.Add(new FieldUpdateValue(dataValue.Key, fieldValue));
                                        }
                                        break;

                                    case FieldType.Lookup:
                                        // FieldLookupValue - Expected format: LookupID or LookupID,LookupID,LookupID...
                                        if (fieldValue.Contains(","))
                                        {
                                            var lookupValues = new List <FieldLookupValue>();
                                            fieldValue.Split(',').All(value =>
                                            {
                                                lookupValues.Add(new FieldLookupValue
                                                {
                                                    LookupId = int.Parse(value),
                                                });
                                                return(true);
                                            });
                                            updateValues.Add(new FieldUpdateValue(dataValue.Key, lookupValues.ToArray()));
                                        }
                                        else
                                        {
                                            var lookupValue = new FieldLookupValue
                                            {
                                                LookupId = int.Parse(fieldValue),
                                            };
                                            updateValues.Add(new FieldUpdateValue(dataValue.Key, lookupValue));
                                        }
                                        break;

                                    case FieldType.URL:
                                        // FieldUrlValue - Expected format: URL,Description
                                        var urlArray  = fieldValue.Split(',');
                                        var linkValue = new FieldUrlValue();
                                        if (urlArray.Length == 2)
                                        {
                                            linkValue.Url         = urlArray[0];
                                            linkValue.Description = urlArray[1];
                                        }
                                        else
                                        {
                                            linkValue.Url         = urlArray[0];
                                            linkValue.Description = urlArray[0];
                                        }
                                        updateValues.Add(new FieldUpdateValue(dataValue.Key, linkValue));
                                        break;

                                    case FieldType.User:
                                        // FieldUserValue - Expected format: loginName or loginName,loginName,loginName...
                                        if (fieldValue.Contains(","))
                                        {
                                            var userValues = new List <FieldUserValue>();
                                            fieldValue.Split(',').All(value =>
                                            {
                                                var user = web.EnsureUser(value);
                                                web.Context.Load(user);
                                                web.Context.ExecuteQueryRetry();
                                                if (user != null)
                                                {
                                                    userValues.Add(new FieldUserValue
                                                    {
                                                        LookupId = user.Id,
                                                    });;
                                                }
                                                return(true);
                                            });
                                            updateValues.Add(new FieldUpdateValue(dataValue.Key, userValues.ToArray()));
                                        }
                                        else
                                        {
                                            var user = web.EnsureUser(fieldValue);
                                            web.Context.Load(user);
                                            web.Context.ExecuteQueryRetry();
                                            if (user != null)
                                            {
                                                var userValue = new FieldUserValue
                                                {
                                                    LookupId = user.Id,
                                                };
                                                updateValues.Add(new FieldUpdateValue(dataValue.Key, userValue));
                                            }
                                            else
                                            {
                                                updateValues.Add(new FieldUpdateValue(dataValue.Key, fieldValue));
                                            }
                                        }
                                        break;

                                    case FieldType.DateTime:
                                        var dateTime = DateTime.MinValue;
                                        if (DateTime.TryParse(fieldValue, out dateTime))
                                        {
                                            updateValues.Add(new FieldUpdateValue(dataValue.Key, dateTime));
                                        }
                                        break;

                                    case FieldType.Invalid:
                                        switch (dataField.TypeAsString)
                                        {
                                        case "TaxonomyFieldType":
                                        // Single value field - Expected format: term label|term GUID
                                        case "TaxonomyFieldTypeMulti":
                                            // Multi value field - Expected format: term label|term GUID;term label|term GUID;term label|term GUID;...
                                        {
                                            if (fieldValue != null)
                                            {
                                                var termStrings = new List <string>();

                                                var termsArray = fieldValue.Split(new char[] { ';' });
                                                foreach (var term in termsArray)
                                                {
                                                    termStrings.Add($"-1;#{term}");
                                                }
                                                updateValues.Add(new FieldUpdateValue(dataValue.Key, termStrings, dataField.TypeAsString));
                                            }
                                            break;
                                        }

                                        default:
                                        {
                                            //Publishing image case, but can be others too
                                            updateValues.Add(new FieldUpdateValue(dataValue.Key, fieldValue));
                                            break;
                                        }
                                        }
                                        break;

                                    default:
                                        updateValues.Add(new FieldUpdateValue(dataValue.Key, fieldValue));
                                        break;
                                    }
                                }
                            }

                            foreach (var itemValue in updateValues.Where(u => u.FieldTypeString != "TaxonomyFieldTypeMulti" && u.FieldTypeString != "TaxonomyFieldType"))
                            {
                                if (string.IsNullOrEmpty(itemValue.FieldTypeString))
                                {
                                    listitem[itemValue.Key] = itemValue.Value;
                                }
                            }
                            listitem.Update();
                            web.Context.Load(listitem);
                            web.Context.ExecuteQueryRetry();
                            foreach (var itemValue in updateValues.Where(u => u.FieldTypeString == "TaxonomyFieldTypeMulti" || u.FieldTypeString == "TaxonomyFieldType"))
                            {
                                switch (itemValue.FieldTypeString)
                                {
                                case "TaxonomyFieldTypeMulti":
                                {
                                    var field    = fields.FirstOrDefault(f => f.InternalName == itemValue.Key as string || f.Title == itemValue.Key as string);
                                    var taxField = web.Context.CastTo <TaxonomyField>(field);
                                    if (itemValue.Value != null)
                                    {
                                        var valueCollection = new TaxonomyFieldValueCollection(web.Context, string.Join(";#", itemValue.Value as List <string>), taxField);
                                        taxField.SetFieldValueByValueCollection(listitem, valueCollection);
                                    }
                                    else
                                    {
                                        var valueCollection = new TaxonomyFieldValueCollection(web.Context, null, taxField);
                                        taxField.SetFieldValueByValueCollection(listitem, valueCollection);
                                    }
                                    listitem.Update();
                                    web.Context.Load(listitem);
                                    web.Context.ExecuteQueryRetry();
                                    break;
                                }

                                case "TaxonomyFieldType":
                                {
                                    var field    = fields.FirstOrDefault(f => f.InternalName == itemValue.Key as string || f.Title == itemValue.Key as string);
                                    var taxField = web.Context.CastTo <TaxonomyField>(field);
                                    taxField.EnsureProperty(f => f.TextField);
                                    var taxValue = new TaxonomyFieldValue();
                                    if (itemValue.Value != null)
                                    {
                                        var termString = (itemValue.Value as List <string>).First();
                                        taxValue.Label    = termString.Split(new string[] { ";#" }, StringSplitOptions.None)[1].Split(new char[] { '|' })[0];
                                        taxValue.TermGuid = termString.Split(new string[] { ";#" }, StringSplitOptions.None)[1].Split(new char[] { '|' })[1];
                                        taxValue.WssId    = -1;
                                        taxField.SetFieldValueByValue(listitem, taxValue);
                                    }
                                    else
                                    {
                                        taxValue.Label    = string.Empty;
                                        taxValue.TermGuid = "11111111-1111-1111-1111-111111111111";
                                        taxValue.WssId    = -1;
                                        Field hiddenField = list.Fields.GetById(taxField.TextField);
                                        listitem.Context.Load(hiddenField, tf => tf.InternalName);
                                        listitem.Context.ExecuteQueryRetry();
                                        taxField.SetFieldValueByValue(listitem, taxValue);     // this order of updates is important.
                                        listitem[hiddenField.InternalName] = string.Empty;     // this order of updates is important.
                                    }
                                    listitem.Update();
                                    web.Context.Load(listitem);
                                    web.Context.ExecuteQueryRetry();
                                    break;
                                }
                                }
                            }
                            if (dataRow.Security != null && (dataRow.Security.ClearSubscopes == true || dataRow.Security.CopyRoleAssignments == true || dataRow.Security.RoleAssignments.Count > 0))
                            {
                                listitem.SetSecurity(parser, dataRow.Security);
                            }
                        }
                        catch (Exception ex)
                        {
                            if (ex.GetType().Equals(typeof(ServerException)) &&
                                (ex as ServerException).ServerErrorTypeName.Equals("Microsoft.SharePoint.SPDuplicateValuesFoundException", StringComparison.InvariantCultureIgnoreCase) &&
                                applyingInformation.IgnoreDuplicateDataRowErrors)
                            {
                                scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Creating_listitem_duplicate);
                                continue;
                            }
                            else
                            {
                                scope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Creating_listitem_failed___0_____1_, ex.Message, ex.StackTrace);
                                throw;
                            }
                        }
                    }
                }

                #endregion
            }

            return(parser);
        }
        public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                if (template.Navigation != null)
                {
                    if (!WebSupportsProvisionNavigation(web, template))
                    {
                        scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Navigation_Context_web_is_not_publishing);
                        return(parser);
                    }

                    // Check if this is not a noscript site as navigation features are not supported
                    if (web.IsNoScriptSite())
                    {
                        scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_Navigation_SkipProvisioning);
                        return(parser);
                    }

                    // Retrieve the current web navigation settings
                    var navigationSettings = new WebNavigationSettings(web.Context, web);
                    web.Context.Load(navigationSettings, ns => ns.CurrentNavigation, ns => ns.GlobalNavigation);
                    web.Context.ExecuteQueryRetry();

                    navigationSettings.AddNewPagesToNavigation       = template.Navigation.AddNewPagesToNavigation;
                    navigationSettings.CreateFriendlyUrlsForNewPages = template.Navigation.CreateFriendlyUrlsForNewPages;

                    if (template.Navigation.GlobalNavigation != null)
                    {
                        switch (template.Navigation.GlobalNavigation.NavigationType)
                        {
                        case GlobalNavigationType.Inherit:
                            navigationSettings.GlobalNavigation.Source = StandardNavigationSource.InheritFromParentWeb;
                            web.Navigation.UseShared = true;
                            break;

                        case GlobalNavigationType.Managed:
                            if (template.Navigation.GlobalNavigation.ManagedNavigation == null)
                            {
                                throw new ApplicationException(CoreResources.Provisioning_ObjectHandlers_Navigation_missing_global_managed_navigation);
                            }
                            navigationSettings.GlobalNavigation.Source      = StandardNavigationSource.TaxonomyProvider;
                            navigationSettings.GlobalNavigation.TermStoreId = Guid.Parse(parser.ParseString(template.Navigation.GlobalNavigation.ManagedNavigation.TermStoreId));
                            navigationSettings.GlobalNavigation.TermSetId   = Guid.Parse(parser.ParseString(template.Navigation.GlobalNavigation.ManagedNavigation.TermSetId));
                            break;

                        case GlobalNavigationType.Structural:
                        default:
                            if (template.Navigation.GlobalNavigation.StructuralNavigation == null)
                            {
                                throw new ApplicationException(CoreResources.Provisioning_ObjectHandlers_Navigation_missing_global_structural_navigation);
                            }
                            navigationSettings.GlobalNavigation.Source = StandardNavigationSource.PortalProvider;

                            ProvisionGlobalStructuralNavigation(web,
                                                                template.Navigation.GlobalNavigation.StructuralNavigation, parser, applyingInformation.ClearNavigation, scope);

                            break;
                        }
                        navigationSettings.Update(TaxonomySession.GetTaxonomySession(web.Context));
                        web.Context.ExecuteQueryRetry();
                    }

                    if (template.Navigation.CurrentNavigation != null)
                    {
                        switch (template.Navigation.CurrentNavigation.NavigationType)
                        {
                        case CurrentNavigationType.Inherit:
                            navigationSettings.CurrentNavigation.Source = StandardNavigationSource.InheritFromParentWeb;
                            break;

                        case CurrentNavigationType.Managed:
                            if (template.Navigation.CurrentNavigation.ManagedNavigation == null)
                            {
                                throw new ApplicationException(CoreResources.Provisioning_ObjectHandlers_Navigation_missing_current_managed_navigation);
                            }
                            navigationSettings.CurrentNavigation.Source      = StandardNavigationSource.TaxonomyProvider;
                            navigationSettings.CurrentNavigation.TermStoreId = Guid.Parse(parser.ParseString(template.Navigation.CurrentNavigation.ManagedNavigation.TermStoreId));
                            navigationSettings.CurrentNavigation.TermSetId   = Guid.Parse(parser.ParseString(template.Navigation.CurrentNavigation.ManagedNavigation.TermSetId));
                            break;

                        case CurrentNavigationType.StructuralLocal:
                            web.SetPropertyBagValue(NavigationShowSiblings, "false");
                            if (template.Navigation.CurrentNavigation.StructuralNavigation == null)
                            {
                                throw new ApplicationException(CoreResources.Provisioning_ObjectHandlers_Navigation_missing_current_structural_navigation);
                            }
                            navigationSettings.CurrentNavigation.Source = StandardNavigationSource.PortalProvider;

                            ProvisionCurrentStructuralNavigation(web,
                                                                 template.Navigation.CurrentNavigation.StructuralNavigation, parser, applyingInformation.ClearNavigation, scope);

                            break;

                        case CurrentNavigationType.Structural:
                        default:
                            web.SetPropertyBagValue(NavigationShowSiblings, "true");
                            if (template.Navigation.CurrentNavigation.StructuralNavigation == null)
                            {
                                throw new ApplicationException(CoreResources.Provisioning_ObjectHandlers_Navigation_missing_current_structural_navigation);
                            }
                            navigationSettings.CurrentNavigation.Source = StandardNavigationSource.PortalProvider;

                            ProvisionCurrentStructuralNavigation(web,
                                                                 template.Navigation.CurrentNavigation.StructuralNavigation, parser, applyingInformation.ClearNavigation, scope);

                            break;
                        }
                        navigationSettings.Update(TaxonomySession.GetTaxonomySession(web.Context));
                        web.Context.ExecuteQueryRetry();
                    }
                }
            }

            return(parser);
        }
        private static void AddUserToGroup(Web web, Group group, List<User> members, PnPMonitoredScope scope)
        {
            if (members.Any())
            {
                scope.LogDebug("Adding users to group {0}", group.Title);
                try
                {
                    foreach (var user in members)
                    {
                        scope.LogDebug("Adding user {0}", user.Name);
                        var existingUser = web.EnsureUser(user.Name);
                        group.Users.AddUser(existingUser);

                    }
                    web.Context.ExecuteQueryRetry();
                }
                catch (Exception ex)
                {
                    scope.LogError(CoreResources.Provisioning_ObjectHandlers_SiteSecurity_Add_users_failed_for_group___0_____1_____2_, group.Title, ex.Message, ex.StackTrace);
                    throw;
                }
            }
        }
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                GlobalNavigationType  globalNavigationType;
                CurrentNavigationType currentNavigationType;

                if (!WebSupportsExtractNavigation(web))
                {
                    scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Navigation_Context_web_is_not_publishing);
                    return(template);
                }

                // Retrieve the current web navigation settings
                var navigationSettings = new WebNavigationSettings(web.Context, web);
                navigationSettings.EnsureProperties(ns => ns.AddNewPagesToNavigation, ns => ns.CreateFriendlyUrlsForNewPages,
                                                    ns => ns.CurrentNavigation, ns => ns.GlobalNavigation);

                switch (navigationSettings.GlobalNavigation.Source)
                {
                case StandardNavigationSource.InheritFromParentWeb:
                    // Global Navigation is Inherited
                    globalNavigationType = GlobalNavigationType.Inherit;
                    break;

                case StandardNavigationSource.TaxonomyProvider:
                    // Global Navigation is Managed
                    globalNavigationType = GlobalNavigationType.Managed;
                    break;

                case StandardNavigationSource.PortalProvider:
                default:
                    // Global Navigation is Structural
                    globalNavigationType = GlobalNavigationType.Structural;
                    break;
                }

                switch (navigationSettings.CurrentNavigation.Source)
                {
                case StandardNavigationSource.InheritFromParentWeb:
                    // Current Navigation is Inherited
                    currentNavigationType = CurrentNavigationType.Inherit;
                    break;

                case StandardNavigationSource.TaxonomyProvider:
                    // Current Navigation is Managed
                    currentNavigationType = CurrentNavigationType.Managed;
                    break;

                case StandardNavigationSource.PortalProvider:
                default:
                    // Current Navigation is Structural
                    if (AreSiblingsEnabledForCurrentStructuralNavigation(web))
                    {
                        currentNavigationType = CurrentNavigationType.Structural;
                    }
                    else
                    {
                        currentNavigationType = CurrentNavigationType.StructuralLocal;
                    }
                    break;
                }

                var navigationEntity = new Model.Navigation(new GlobalNavigation(globalNavigationType,
                                                                                 globalNavigationType == GlobalNavigationType.Structural ? GetGlobalStructuralNavigation(web, navigationSettings) : null,
                                                                                 globalNavigationType == GlobalNavigationType.Managed ? GetGlobalManagedNavigation(web, navigationSettings) : null),
                                                            new CurrentNavigation(currentNavigationType,
                                                                                  currentNavigationType == CurrentNavigationType.Structural | currentNavigationType == CurrentNavigationType.StructuralLocal ? GetCurrentStructuralNavigation(web, navigationSettings) : null,
                                                                                  currentNavigationType == CurrentNavigationType.Managed ? GetCurrentManagedNavigation(web, navigationSettings) : null)
                                                            );

                navigationEntity.AddNewPagesToNavigation       = navigationSettings.AddNewPagesToNavigation;
                navigationEntity.CreateFriendlyUrlsForNewPages = navigationSettings.CreateFriendlyUrlsForNewPages;

                // If a base template is specified then use that one to "cleanup" the generated template model
                if (creationInfo.BaseTemplate != null)
                {
                    if (!navigationEntity.Equals(creationInfo.BaseTemplate.Navigation))
                    {
                        template.Navigation = navigationEntity;
                    }
                }
                else
                {
                    template.Navigation = navigationEntity;
                }
            }

            return(template);
        }
Example #27
0
        public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                var context = web.Context as ClientContext;

                web.EnsureProperties(w => w.ServerRelativeUrl, w => w.RootFolder.WelcomePage);

                foreach (var page in template.Pages)
                {
                    var url = parser.ParseString(page.Url);

                    if (!url.ToLower().StartsWith(web.ServerRelativeUrl.ToLower()))
                    {
                        url = UrlUtility.Combine(web.ServerRelativeUrl, url);
                    }

                    var exists = true;
                    Microsoft.SharePoint.Client.File file = null;
                    try
                    {
                        file = web.GetFileByServerRelativeUrl(url);
                        web.Context.Load(file);
                        web.Context.ExecuteQuery();
                    }
                    catch (ServerException ex)
                    {
                        if (ex.ServerErrorTypeName == "System.IO.FileNotFoundException")
                        {
                            exists = false;
                        }
                    }
                    if (exists)
                    {
                        if (page.Overwrite)
                        {
                            try
                            {
                                scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Pages_Overwriting_existing_page__0_, url);

                                if (page.WelcomePage && url.Contains(web.RootFolder.WelcomePage))
                                    web.SetHomePage(string.Empty);

                                file.DeleteObject();
                                web.Context.ExecuteQueryRetry();
                                web.AddWikiPageByUrl(url);
                                if (page.Layout == WikiPageLayout.Custom)
                                {
                                    web.AddLayoutToWikiPage(WikiPageLayout.OneColumn, url);
                                }
                                else {
                                    web.AddLayoutToWikiPage(page.Layout, url);
                                }
                            }
                            catch (Exception ex)
                            {
                                scope.LogError(CoreResources.Provisioning_ObjectHandlers_Pages_Overwriting_existing_page__0__failed___1_____2_, url, ex.Message, ex.StackTrace);
                            }
                        }
                    }
                    else
                    {
                        try
                        {
                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Pages_Creating_new_page__0_, url);

                            web.AddWikiPageByUrl(url);
                            web.AddLayoutToWikiPage(page.Layout, url);
                        }
                        catch (Exception ex)
                        {
                            scope.LogError(CoreResources.Provisioning_ObjectHandlers_Pages_Creating_new_page__0__failed___1_____2_, url, ex.Message, ex.StackTrace);
                        }
                    }

                    if (page.WelcomePage)
                    {
                        web.RootFolder.EnsureProperty(p => p.ServerRelativeUrl);
                        var rootFolderRelativeUrl = url.Substring(web.RootFolder.ServerRelativeUrl.Length);
                        web.SetHomePage(rootFolderRelativeUrl);
                    }

                    if (page.WebParts != null & page.WebParts.Any())
                    {
                        var existingWebParts = web.GetWebParts(url);

                        foreach (var webpart in page.WebParts)
                        {
                            if (existingWebParts.FirstOrDefault(w => w.WebPart.Title == webpart.Title) == null)
                            {
                                WebPartEntity wpEntity = new WebPartEntity();
                                wpEntity.WebPartTitle = webpart.Title;
                                wpEntity.WebPartXml = parser.ParseString(webpart.Contents.Trim(new[] { '\n', ' ' }));
                                web.AddWebPartToWikiPage(url, wpEntity, (int)webpart.Row, (int)webpart.Column, false);
                            }
                        }
                        var allWebParts = web.GetWebParts(url);
                        foreach (var webpart in allWebParts)
                        {
                            parser.AddToken(new WebPartIdToken(web, webpart.WebPart.Title, webpart.Id));
                        }
                    }

                    file = web.GetFileByServerRelativeUrl(url);
                    file.EnsureProperty(f => f.ListItemAllFields);

                    if (page.Fields.Any())
                    {
                        var item = file.ListItemAllFields;
                        foreach (var fieldValue in page.Fields)
                        {
                            item[fieldValue.Key] = parser.ParseString(fieldValue.Value);
                        }
                        item.Update();
                        web.Context.ExecuteQueryRetry();
                    }
                    if (page.Security != null && page.Security.RoleAssignments.Count != 0)
                    {
                        web.Context.Load(file.ListItemAllFields);
                        web.Context.ExecuteQuery();
                        file.ListItemAllFields.SetSecurity(parser, page.Security);
                    }
                }
            }
            return parser;
        }
Example #28
0
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                // if this is a sub site then we're not creating security entities as by default security is inherited from the root site
                if (web.IsSubSite())
                {
                    return(template);
                }

                web.Context.Load(web, w => w.HasUniqueRoleAssignments, w => w.Title);

                var ownerGroup   = web.AssociatedOwnerGroup;
                var memberGroup  = web.AssociatedMemberGroup;
                var visitorGroup = web.AssociatedVisitorGroup;
                web.Context.ExecuteQueryRetry();

                if (!ownerGroup.ServerObjectIsNull.Value)
                {
                    web.Context.Load(ownerGroup, o => o.Id, o => o.Users, o => o.Title);
                }
                if (!memberGroup.ServerObjectIsNull.Value)
                {
                    web.Context.Load(memberGroup, o => o.Id, o => o.Users, o => o.Title);
                }
                if (!visitorGroup.ServerObjectIsNull.Value)
                {
                    web.Context.Load(visitorGroup, o => o.Id, o => o.Users, o => o.Title);
                }
                web.Context.ExecuteQueryRetry();

                List <int> associatedGroupIds = new List <int>();
                var        owners             = new List <User>();
                var        members            = new List <User>();
                var        visitors           = new List <User>();
                if (!ownerGroup.ServerObjectIsNull.Value)
                {
                    associatedGroupIds.Add(ownerGroup.Id);
                    foreach (var member in ownerGroup.Users)
                    {
                        owners.Add(new User()
                        {
                            Name = member.LoginName
                        });
                    }
                }
                if (!memberGroup.ServerObjectIsNull.Value)
                {
                    associatedGroupIds.Add(memberGroup.Id);
                    foreach (var member in memberGroup.Users)
                    {
                        members.Add(new User()
                        {
                            Name = member.LoginName
                        });
                    }
                }
                if (!visitorGroup.ServerObjectIsNull.Value)
                {
                    associatedGroupIds.Add(visitorGroup.Id);
                    foreach (var member in visitorGroup.Users)
                    {
                        visitors.Add(new User()
                        {
                            Name = member.LoginName
                        });
                    }
                }
                var siteSecurity = new SiteSecurity();
                siteSecurity.AdditionalOwners.AddRange(owners);
                siteSecurity.AdditionalMembers.AddRange(members);
                siteSecurity.AdditionalVisitors.AddRange(visitors);

                var query = from user in web.SiteUsers
                            where user.IsSiteAdmin
                            select user;
                var allUsers = web.Context.LoadQuery(query);

                web.Context.ExecuteQueryRetry();

                var admins = new List <User>();
                foreach (var member in allUsers)
                {
                    admins.Add(new User()
                    {
                        Name = member.LoginName
                    });
                }
                siteSecurity.AdditionalAdministrators.AddRange(admins);

                if (creationInfo.IncludeSiteGroups)
                {
                    web.Context.Load(web.SiteGroups,
                                     o => o.IncludeWithDefaultProperties(
                                         gr => gr.Title,
                                         gr => gr.AllowMembersEditMembership,
                                         gr => gr.AutoAcceptRequestToJoinLeave,
                                         gr => gr.AllowRequestToJoinLeave,
                                         gr => gr.Description,
                                         gr => gr.Users.Include(u => u.LoginName),
                                         gr => gr.OnlyAllowMembersViewMembership,
                                         gr => gr.Owner.LoginName,
                                         gr => gr.RequestToJoinLeaveEmailSetting
                                         ));

                    web.Context.ExecuteQueryRetry();

                    foreach (var group in web.SiteGroups.AsEnumerable().Where(o => !associatedGroupIds.Contains(o.Id)))
                    {
                        scope.LogDebug("Processing group {0}", group.Title);
                        var siteGroup = new SiteGroup()
                        {
                            Title = group.Title.Replace(web.Title, "{sitename}"),
                            AllowMembersEditMembership   = group.AllowMembersEditMembership,
                            AutoAcceptRequestToJoinLeave = group.AutoAcceptRequestToJoinLeave,
                            AllowRequestToJoinLeave      = group.AllowRequestToJoinLeave,
                            Description = group.Description,
                            OnlyAllowMembersViewMembership = group.OnlyAllowMembersViewMembership,
                            Owner = ReplaceGroupTokens(web, group.Owner.LoginName),
                            RequestToJoinLeaveEmailSetting = group.RequestToJoinLeaveEmailSetting
                        };

                        foreach (var member in group.Users)
                        {
                            siteGroup.Members.Add(new User()
                            {
                                Name = member.LoginName
                            });
                        }
                        siteSecurity.SiteGroups.Add(siteGroup);
                    }
                }

                var webRoleDefinitions = web.Context.LoadQuery(web.RoleDefinitions.Include(r => r.Name, r => r.Description, r => r.BasePermissions, r => r.RoleTypeKind));
                web.Context.ExecuteQueryRetry();

                if (web.HasUniqueRoleAssignments)
                {
                    var permissionKeys = Enum.GetNames(typeof(PermissionKind));

                    foreach (var webRoleDefinition in webRoleDefinitions)
                    {
                        if (webRoleDefinition.RoleTypeKind == RoleType.None)
                        {
                            scope.LogDebug("Processing custom role definition {0}", webRoleDefinition.Name);
                            var modelRoleDefinitions = new Model.RoleDefinition();

                            modelRoleDefinitions.Description = webRoleDefinition.Description;
                            modelRoleDefinitions.Name        = webRoleDefinition.Name;
                            var permissions = new List <PermissionKind>();

                            foreach (var permissionKey in permissionKeys)
                            {
                                var permissionKind = (PermissionKind)Enum.Parse(typeof(PermissionKind), permissionKey);
                                if (webRoleDefinition.BasePermissions.Has(permissionKind))
                                {
                                    modelRoleDefinitions.Permissions.Add(permissionKind);
                                }
                            }
                            siteSecurity.SiteSecurityPermissions.RoleDefinitions.Add(modelRoleDefinitions);
                        }
                        else
                        {
                            scope.LogDebug("Skipping OOTB role definition {0}", webRoleDefinition.Name);
                        }
                    }

                    var webRoleAssignments = web.Context.LoadQuery(web.RoleAssignments.Include(
                                                                       r => r.RoleDefinitionBindings.Include(
                                                                           rd => rd.Name,
                                                                           rd => rd.RoleTypeKind),
                                                                       r => r.Member.LoginName));

                    web.Context.ExecuteQueryRetry();

                    foreach (var webRoleAssignment in webRoleAssignments)
                    {
                        if (webRoleAssignment.Member.LoginName != "Excel Services Viewers")
                        {
                            foreach (var roleDefinition in webRoleAssignment.RoleDefinitionBindings)
                            {
                                if (roleDefinition.RoleTypeKind != RoleType.Guest)
                                {
                                    var modelRoleAssignment = new Model.RoleAssignment();
                                    modelRoleAssignment.RoleDefinition = roleDefinition.Name;
                                    modelRoleAssignment.Principal      = ReplaceGroupTokens(web, webRoleAssignment.Member.LoginName);
                                    siteSecurity.SiteSecurityPermissions.RoleAssignments.Add(modelRoleAssignment);
                                }
                            }
                        }
                    }

                    template.Security = siteSecurity;
                }
                // If a base template is specified then use that one to "cleanup" the generated template model
                if (creationInfo.BaseTemplate != null)
                {
                    template = CleanupEntities(template, creationInfo.BaseTemplate);
                }
            }
            return(template);
        }
        public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                if (template.Lists.Any())
                {
                    var rootWeb = (web.Context as ClientContext).Site.RootWeb;

                    web.EnsureProperties(w => w.ServerRelativeUrl);

                    web.Context.Load(web.Lists, lc => lc.IncludeWithDefaultProperties(l => l.RootFolder.ServerRelativeUrl));
                    web.Context.ExecuteQueryRetry();
                    var existingLists = web.Lists.AsEnumerable().ToList();
                    var serverRelativeUrl = web.ServerRelativeUrl;

                    var processedLists = new List<ListInfo>();

                    // Check if this is not a noscript site as we're not allowed to update some properties
                    bool isNoScriptSite = web.IsNoScriptSite();

                    #region Lists

                    foreach (var templateList in template.Lists)
                    {
                        // Check for the presence of the references content types and throw an exception if not present or in template
                        if (templateList.ContentTypesEnabled)
                        {
                            var existingCts = web.Context.LoadQuery(web.AvailableContentTypes);
                            web.Context.ExecuteQueryRetry();
                            foreach (var ct in templateList.ContentTypeBindings)
                            {
                                var found = template.ContentTypes.Any(t => t.Id.ToUpperInvariant() == ct.ContentTypeId.ToUpperInvariant());
                                if (found == false)
                                {
                                    found = existingCts.Any(t => t.StringId.ToUpperInvariant() == ct.ContentTypeId.ToUpperInvariant());
                                }
                                if (!found)
                                {
                                    scope.LogError("Referenced content type {0} not available in site or in template", ct.ContentTypeId);
                                    throw new Exception(string.Format("Referenced content type {0} not available in site or in template", ct.ContentTypeId));
                                }
                            }
                        }
                        // check if the List exists by url or by title
                        var index = existingLists.FindIndex(x => x.Title.Equals(templateList.Title, StringComparison.OrdinalIgnoreCase) || x.RootFolder.ServerRelativeUrl.Equals(UrlUtility.Combine(serverRelativeUrl, templateList.Url), StringComparison.OrdinalIgnoreCase));

                        if (index == -1)
                        {
                            try
                            {
                                scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Creating_list__0_, templateList.Title);
                                var returnTuple = CreateList(web, templateList, parser, scope, isNoScriptSite);
                                var createdList = returnTuple.Item1;
                                parser = returnTuple.Item2;
                                processedLists.Add(new ListInfo { SiteList = createdList, TemplateList = templateList });

                                parser.AddToken(new ListIdToken(web, templateList.Title, createdList.Id));

                                parser.AddToken(new ListUrlToken(web, templateList.Title, createdList.RootFolder.ServerRelativeUrl.Substring(web.ServerRelativeUrl.Length + 1)));
                            }
                            catch (Exception ex)
                            {
                                scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Creating_list__0__failed___1_____2_, templateList.Title, ex.Message, ex.StackTrace);
                                throw;
                            }
                        }
                        else
                        {
                            try
                            {
                                scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Updating_list__0_, templateList.Title);
                                var existingList = web.Lists[index];
                                var returnTuple = UpdateList(web, existingList, templateList, parser, scope, isNoScriptSite);
                                var updatedList = returnTuple.Item1;
                                parser = returnTuple.Item2;
                                if (updatedList != null)
                                {
                                    processedLists.Add(new ListInfo { SiteList = updatedList, TemplateList = templateList });
                                }
                            }
                            catch (Exception ex)
                            {
                                scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Updating_list__0__failed___1_____2_, templateList.Title, ex.Message, ex.StackTrace);
                                throw;
                            }
                        }
                    }

                    #endregion

                    #region FieldRefs

                    foreach (var listInfo in processedLists)
                    {

                        if (listInfo.TemplateList.FieldRefs.Any())
                        {

                            foreach (var fieldRef in listInfo.TemplateList.FieldRefs)
                            {
                                var field = rootWeb.GetFieldById<Field>(fieldRef.Id);
                                if (field == null)
                                {
                                    // log missing referenced field
                                    this.WriteWarning(string.Format(CoreResources.Provisioning_ObjectHandlers_ListInstances_InvalidFieldReference, listInfo.TemplateList.Title, fieldRef.Name, fieldRef.Id), ProvisioningMessageType.Error);

                                    // move onto next field reference
                                    continue;
                                }

                                if (!listInfo.SiteList.FieldExistsById(fieldRef.Id))
                                {
                                    field = CreateFieldRef(listInfo, field, fieldRef);
                                }
                                else
                                {
                                    field = UpdateFieldRef(listInfo.SiteList, field.Id, fieldRef);
                                }

                                field.EnsureProperties(f => f.InternalName, f => f.Title);

                                parser.AddToken(new FieldTitleToken(web, field.InternalName, field.Title));

            #if !SP2013
                                var siteField = template.SiteFields.FirstOrDefault(f => Guid.Parse(XElement.Parse(f.SchemaXml).Attribute("ID").Value).Equals(field.Id));

                                if (siteField != null && siteField.SchemaXml.ContainsResourceToken())
                                {
                                    var isDirty = false;
                                    var originalFieldElement = XElement.Parse(siteField.SchemaXml);
                                    var nameAttributeValue = originalFieldElement.Attribute("DisplayName") != null ? originalFieldElement.Attribute("DisplayName").Value : "";
                                    if (nameAttributeValue.ContainsResourceToken())
                                    {
                                        if (field.TitleResource.SetUserResourceValue(nameAttributeValue, parser))
                                        {
                                            isDirty = true;
                                        }
                                    }
                                    var descriptionAttributeValue = originalFieldElement.Attribute("Description") != null ? originalFieldElement.Attribute("Description").Value : "";
                                    if (descriptionAttributeValue.ContainsResourceToken())
                                    {
                                        if (field.DescriptionResource.SetUserResourceValue(descriptionAttributeValue, parser))
                                        {
                                            isDirty = true;
                                        }
                                    }

                                    if (isDirty)
                                    {
                                        field.Update();
                                        field.Context.ExecuteQueryRetry();
                                    }
                                }
            #endif
                            }

                            listInfo.SiteList.Update();
                            web.Context.ExecuteQueryRetry();
                        }
                    }

                    #endregion

                    #region Fields

                    foreach (var listInfo in processedLists)
                    {
                        if (listInfo.TemplateList.Fields.Any())
                        {
                            foreach (var field in listInfo.TemplateList.Fields)
                            {
                                var fieldElement = XElement.Parse(parser.ParseString(field.SchemaXml, "~sitecollection", "~site"));
                                if (fieldElement.Attribute("ID") == null)
                                {
                                    scope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstances_Field_schema_has_no_ID_attribute___0_, field.SchemaXml);
                                    throw new Exception(string.Format(CoreResources.Provisioning_ObjectHandlers_ListInstances_Field_schema_has_no_ID_attribute___0_, field.SchemaXml));
                                }
                                var id = fieldElement.Attribute("ID").Value;

                                Guid fieldGuid;
                                if (!Guid.TryParse(id, out fieldGuid))
                                {
                                    scope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstances_ID_for_field_is_not_a_valid_Guid___0_, field.SchemaXml);
                                    throw new Exception(string.Format(CoreResources.Provisioning_ObjectHandlers_ListInstances_ID_for_field_is_not_a_valid_Guid___0_, id));
                                }
                                else
                                {
                                    var fieldFromList = listInfo.SiteList.GetFieldById<Field>(fieldGuid);
                                    if (fieldFromList == null)
                                    {
                                        try
                                        {
                                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Creating_field__0_, fieldGuid);
                                            var createdField = CreateField(fieldElement, listInfo, parser, field.SchemaXml, web.Context, scope);
                                            if (createdField != null)
                                            {
                                                createdField.EnsureProperties(f => f.InternalName, f => f.Title);
                                                parser.AddToken(new FieldTitleToken(web, createdField.InternalName,
                                                    createdField.Title));
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            scope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstances_Creating_field__0__failed___1_____2_, fieldGuid, ex.Message, ex.StackTrace);
                                            throw;
                                        }
                                    }
                                    else
                                    {
                                        try
                                        {
                                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Updating_field__0_, fieldGuid);
                                            var updatedField = UpdateField(web, listInfo, fieldGuid, fieldElement, fieldFromList, scope, parser, field.SchemaXml);
                                            if (updatedField != null)
                                            {
                                                updatedField.EnsureProperties(f => f.InternalName, f => f.Title);
                                                parser.AddToken(new FieldTitleToken(web, updatedField.InternalName,
                                                    updatedField.Title));
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            scope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstances_Updating_field__0__failed___1_____2_, fieldGuid, ex.Message, ex.StackTrace);
                                            throw;
                                        }

                                    }
                                }
                            }
                        }
                        listInfo.SiteList.Update();
                        web.Context.ExecuteQueryRetry();
                    }

                    #endregion

                    #region Default Field Values
                    foreach (var listInfo in processedLists)
                    {
                        if (listInfo.TemplateList.FieldDefaults.Any())
                        {
                            foreach (var fieldDefault in listInfo.TemplateList.FieldDefaults)
                            {
                                var field = listInfo.SiteList.Fields.GetByInternalNameOrTitle(fieldDefault.Key);
                                field.DefaultValue = fieldDefault.Value;
                                field.Update();
                                web.Context.ExecuteQueryRetry();
                            }
                        }
                    }
                    #endregion

                    #region Views

                    foreach (var listInfo in processedLists)
                    {
                        var list = listInfo.TemplateList;
                        var createdList = listInfo.SiteList;

                        if (list.Views.Any() && list.RemoveExistingViews)
                        {
                            while (createdList.Views.Any())
                            {
                                createdList.Views[0].DeleteObject();
                            }
                            web.Context.ExecuteQueryRetry();
                        }

                        var existingViews = createdList.Views;
                        web.Context.Load(existingViews, vs => vs.Include(v => v.Title, v => v.Id));
                        web.Context.ExecuteQueryRetry();
                        foreach (var view in list.Views)
                        {

                            CreateView(web, view, existingViews, createdList, scope);

                        }

                        //// Removing existing views set the OnQuickLaunch option to false and need to be re-set.
                        //if (list.OnQuickLaunch && list.RemoveExistingViews && list.Views.Count > 0)
                        //{
                        //    createdList.RefreshLoad();
                        //    web.Context.ExecuteQueryRetry();
                        //    createdList.OnQuickLaunch = list.OnQuickLaunch;
                        //    createdList.Update();
                        //    web.Context.ExecuteQueryRetry();
                        //}
                    }

                    #endregion

                    #region Folders

                    // Folders are supported for document libraries and generic lists only
                    foreach (var list in processedLists)
                    {
                        list.SiteList.EnsureProperties(l => l.BaseType);
                        if ((list.SiteList.BaseType == BaseType.DocumentLibrary |
                            list.SiteList.BaseType == BaseType.GenericList) &&
                            list.TemplateList.Folders != null && list.TemplateList.Folders.Count > 0)
                        {
                            list.SiteList.EnableFolderCreation = true;
                            list.SiteList.Update();
                            web.Context.ExecuteQueryRetry();

                            var rootFolder = list.SiteList.RootFolder;
                            foreach (var folder in list.TemplateList.Folders)
                            {
                                CreateFolderInList(rootFolder, folder, parser, scope);
                            }
                        }
                    }

                    #endregion

                    // If an existing view is updated, and the list is to be listed on the QuickLaunch, it is removed because the existing view will be deleted and recreated from scratch.
                    foreach (var listInfo in processedLists)
                    {
                        listInfo.SiteList.OnQuickLaunch = listInfo.TemplateList.OnQuickLaunch;
                        listInfo.SiteList.Update();
                    }
                    web.Context.ExecuteQueryRetry();

                }
            }
            return parser;
        }
        private ProvisioningTemplate CleanupEntities(ProvisioningTemplate template, ProvisioningTemplate baseTemplate, bool isSubSite, PnPMonitoredScope scope)
        {
            if (!isSubSite)
            {
                foreach (var customAction in baseTemplate.CustomActions.SiteCustomActions)
                {
                    int index = template.CustomActions.SiteCustomActions.FindIndex(f => f.Name.Equals(customAction.Name));

                    if (index > -1)
                    {
                        scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Removing_site_scoped_custom_action___0___from_template_because_already_available_in_base_template, customAction.Name);
                        template.CustomActions.SiteCustomActions.RemoveAt(index);
                    }
                }
            }

            foreach (var customAction in baseTemplate.CustomActions.WebCustomActions)
            {
                int index = template.CustomActions.WebCustomActions.FindIndex(f => f.Name.Equals(customAction.Name));

                if (index > -1)
                {
                    scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Removing_web_scoped_custom_action___0___from_template_because_already_available_in_base_template, customAction.Name);
                    template.CustomActions.WebCustomActions.RemoveAt(index);
                }
            }

            return template;
        }
        private void ProvisionCustomActionImplementation(object parent, CustomActionCollection customActions, TokenParser parser, PnPMonitoredScope scope, bool isNoScriptSite = false)
        {
            Web  web  = null;
            Site site = null;

            if (parent is Site)
            {
                site = parent as Site;

                // Switch parser context;
                parser.Rebase(site.RootWeb);
            }
            else
            {
                web = parent as Web;

                // Switch parser context
                parser.Rebase(web);
            }
            foreach (var customAction in customActions)
            {
                if (isNoScriptSite && Guid.Empty == customAction.ClientSideComponentId)
                {
                    scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_CustomActions_SkippingAddUpdateDueToNoScript, customAction.Name);
                    continue;
                }

                var caExists = false;
                if (site != null)
                {
                    caExists = site.CustomActionExists(customAction.Name);
                }
                else
                {
                    caExists = web.CustomActionExists(customAction.Name);
                }

                // If the CustomAction does not exist, we don't have to remove it, and it is enabled
                if (!caExists && !customAction.Remove && customAction.Enabled)
                {
                    // Then we add it to the target
                    var customActionEntity = new CustomActionEntity()
                    {
#if !ONPREMISES
                        ClientSideComponentId         = customAction.ClientSideComponentId,
                        ClientSideComponentProperties = customAction.ClientSideComponentProperties != null?parser.ParseString(customAction.ClientSideComponentProperties) : customAction.ClientSideComponentProperties,
#endif
                        CommandUIExtension = customAction.CommandUIExtension != null?parser.ParseString(customAction.CommandUIExtension.ToString()) : string.Empty,
                                                 Description      = parser.ParseString(customAction.Description),
                                                 Group            = customAction.Group,
                                                 ImageUrl         = parser.ParseString(customAction.ImageUrl),
                                                 Location         = customAction.Location,
                                                 Name             = customAction.Name,
                                                 RegistrationId   = customAction.RegistrationId,
                                                 RegistrationType = customAction.RegistrationType,
                                                 Remove           = customAction.Remove,
                                                 Rights           = customAction.Rights,
                                                 ScriptBlock      = parser.ParseString(customAction.ScriptBlock),
                                                 ScriptSrc        = parser.ParseString(customAction.ScriptSrc, "~site", "~sitecollection"),
                                                 Sequence         = customAction.Sequence,
                                                 Title            = parser.ParseString(customAction.Title),
                                                 Url = parser.ParseString(customAction.Url)
                    };


                    if (site != null)
                    {
                        scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Adding_custom_action___0___to_scope_Site, customActionEntity.Name);
                        site.AddCustomAction(customActionEntity);
#if !ONPREMISES
                        if ((!string.IsNullOrEmpty(customAction.Title) && customAction.Title.ContainsResourceToken()) ||
                            (!string.IsNullOrEmpty(customAction.Description) && customAction.Description.ContainsResourceToken()))
                        {
                            var uca = site.GetCustomActions().FirstOrDefault(uc => uc.Name == customAction.Name);
                            SetCustomActionResourceValues(parser, customAction, uca);
                        }
#endif
                    }
                    else
                    {
                        scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Adding_custom_action___0___to_scope_Web, customActionEntity.Name);
                        web.AddCustomAction(customActionEntity);
#if !ONPREMISES
                        if (customAction.Title.ContainsResourceToken() || customAction.Description.ContainsResourceToken())
                        {
                            var uca = web.GetCustomActions().FirstOrDefault(uc => uc.Name == customAction.Name);
                            SetCustomActionResourceValues(parser, customAction, uca);
                        }
#endif
                    }
                }
                else
                {
                    UserCustomAction existingCustomAction;
                    if (site != null)
                    {
                        existingCustomAction = site.GetCustomActions().FirstOrDefault(c => c.Name == customAction.Name);
                    }
                    else
                    {
                        existingCustomAction = web.GetCustomActions().FirstOrDefault(c => c.Name == customAction.Name);
                    }
                    if (existingCustomAction != null)
                    {
                        // If we have to remove the existing CustomAction
                        if (customAction.Remove)
                        {
                            // We simply remove it
                            existingCustomAction.DeleteObject();
                            existingCustomAction.Context.ExecuteQueryRetry();
                        }
                        else
                        {
                            UpdateCustomAction(parser, scope, customAction, existingCustomAction, isNoScriptSite);
                        }
                    }
                }
            }
        }
Example #32
0
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                // if this is a sub site then we're not creating field entities.
                if (web.IsSubSite())
                {
                    scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Fields_Context_web_is_subweb__skipping_site_columns);
                    return(template);
                }

                var existingFields = web.Fields;
                web.Context.Load(web, w => w.ServerRelativeUrl);
                web.Context.Load(existingFields, fs => fs.Include(f => f.Id, f => f.SchemaXml, f => f.TypeAsString, f => f.InternalName, f => f.Title));
                web.Context.Load(web.Lists, ls => ls.Include(l => l.Id, l => l.Title));
                web.Context.ExecuteQueryRetry();

                var taxTextFieldsToMoveUp = new List <Guid>();

                foreach (var field in existingFields)
                {
                    if (!BuiltInFieldId.Contains(field.Id))
                    {
                        var      fieldXml = field.SchemaXml;
                        XElement element  = XElement.Parse(fieldXml);

                        // Check if the field contains a reference to a list. If by Guid, rewrite the value of the attribute to use web relative paths
                        var listIdentifier = element.Attribute("List") != null?element.Attribute("List").Value : null;

                        if (!string.IsNullOrEmpty(listIdentifier))
                        {
                            var listGuid = Guid.Empty;
                            fieldXml = ParseFieldSchema(fieldXml, web.Lists);
                            element  = XElement.Parse(fieldXml);
                            //if (Guid.TryParse(listIdentifier, out listGuid))
                            //{
                            //    fieldXml = ParseListSchema(fieldXml, web.Lists);
                            //if (newfieldXml == fieldXml)
                            //{
                            //    var list = web.Lists.GetById(listGuid);
                            //    web.Context.Load(list, l => l.RootFolder.ServerRelativeUrl);
                            //    web.Context.ExecuteQueryRetry();

                            //    var listUrl = list.RootFolder.ServerRelativeUrl.Substring(web.ServerRelativeUrl.Length).TrimStart('/');
                            //    element.Attribute("List").SetValue(listUrl);
                            //    fieldXml = element.ToString();
                            //}
                            //}
                        }

                        // Check if the field is of type TaxonomyField
                        if (field.TypeAsString.StartsWith("TaxonomyField"))
                        {
                            var taxField = (TaxonomyField)field;
                            web.Context.Load(taxField, tf => tf.TextField, tf => tf.Id);
                            web.Context.ExecuteQueryRetry();
                            taxTextFieldsToMoveUp.Add(taxField.TextField);

                            fieldXml = TokenizeTaxonomyField(web, element);
                        }

                        // Check if we have version attribute. Remove if exists
                        if (element.Attribute("Version") != null)
                        {
                            element.Attributes("Version").Remove();
                            fieldXml = element.ToString();
                        }
                        if (element.Attribute("Type").Value == "Calculated")
                        {
                            fieldXml = TokenizeFieldFormula(fieldXml);
                        }
                        if (creationInfo.PersistMultiLanguageResources)
                        {
#if !SP2013
                            // only persist language values for fields we actually will keep...no point in spending time on this is we clean the field afterwards
                            bool persistLanguages = true;
                            if (creationInfo.BaseTemplate != null)
                            {
                                int index = creationInfo.BaseTemplate.SiteFields.FindIndex(f => Guid.Parse(XElement.Parse(f.SchemaXml).Attribute("ID").Value).Equals(field.Id));

                                if (index > -1)
                                {
                                    persistLanguages = false;
                                }
                            }

                            if (persistLanguages)
                            {
                                var fieldElement = XElement.Parse(fieldXml);
                                if (UserResourceExtensions.PersistResourceValue(field.TitleResource, string.Format("Field_{0}_DisplayName", field.Title.Replace(" ", "_")), template, creationInfo))
                                {
                                    var fieldTitle = string.Format("{{res:Field_{0}_DisplayName}}", field.Title.Replace(" ", "_"));
                                    fieldElement.SetAttributeValue("DisplayName", fieldTitle);
                                }
                                if (UserResourceExtensions.PersistResourceValue(field.DescriptionResource, string.Format("Field_{0}_Description", field.Title.Replace(" ", "_")), template, creationInfo))
                                {
                                    var fieldDescription = string.Format("{{res:Field_{0}_Description}}", field.Title.Replace(" ", "_"));
                                    fieldElement.SetAttributeValue("Description", fieldDescription);
                                }

                                fieldXml = fieldElement.ToString();
                            }
#endif
                        }

                        template.SiteFields.Add(new Field()
                        {
                            SchemaXml = fieldXml
                        });
                    }
                }
                // move hidden taxonomy text fields to the top of the list
                foreach (var textFieldId in taxTextFieldsToMoveUp)
                {
                    var field = template.SiteFields.First(f => Guid.Parse(f.SchemaXml.ElementAttributeValue("ID")).Equals(textFieldId));
                    template.SiteFields.RemoveAll(f => Guid.Parse(f.SchemaXml.ElementAttributeValue("ID")).Equals(textFieldId));
                    template.SiteFields.Insert(0, field);
                }
                // If a base template is specified then use that one to "cleanup" the generated template model
                if (creationInfo.BaseTemplate != null)
                {
                    template = CleanupEntities(template, creationInfo.BaseTemplate);
                }
            }
            return(template);
        }
        public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                var systemPropertyBagEntriesExclusions = new List <string>(new[]
                {
                    "_",
                    "vti_",
                    "dlc_",
                    "ecm_",
                    "profileschemaversion",
                    "DesignPreview"
                });

                // Check if this is not a noscript site as we're not allowed to write to the web property bag is that one
                bool isNoScriptSite = web.IsNoScriptSite();
                if (isNoScriptSite)
                {
                    return(parser);
                }

                // To handle situations where the propertybag is not updated fully when applying a theme,
                // we need to create a new context and use that one. Reloading the propertybag does not solve this.
                var webUrl     = web.EnsureProperty(w => w.Url);
                var newContext = web.Context.Clone(webUrl);

                web = newContext.Web;

                foreach (var propbagEntry in template.PropertyBagEntries)
                {
                    bool propExists = web.PropertyBagContainsKey(propbagEntry.Key);

                    if (propbagEntry.Overwrite)
                    {
                        var systemProp = systemPropertyBagEntriesExclusions.Any(k => propbagEntry.Key.StartsWith(k, StringComparison.OrdinalIgnoreCase));
                        if (!systemProp || (systemProp && applyingInformation.OverwriteSystemPropertyBagValues))
                        {
                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_PropertyBagEntries_Overwriting_existing_propertybag_entry__0__with_value__1_, propbagEntry.Key, propbagEntry.Value);
                            web.SetPropertyBagValue(propbagEntry.Key, parser.ParseString(propbagEntry.Value));
                            if (propbagEntry.Indexed)
                            {
                                web.AddIndexedPropertyBagKey(propbagEntry.Key);
                            }
                        }
                    }
                    else
                    {
                        if (!propExists)
                        {
                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_PropertyBagEntries_Creating_new_propertybag_entry__0__with_value__1__2_, propbagEntry.Key, propbagEntry.Value, propbagEntry.Indexed ? ",Indexed = true" : "");
                            web.SetPropertyBagValue(propbagEntry.Key, parser.ParseString(propbagEntry.Value));
                            if (propbagEntry.Indexed)
                            {
                                web.AddIndexedPropertyBagKey(propbagEntry.Key);
                            }
                        }
                    }
                }
            }
            return(parser);
        }
Example #34
0
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                // if this is a sub site then we're not creating field entities.
                if (web.IsSubSite())
                {
                    scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Fields_Context_web_is_subweb__skipping_site_columns);
                    return template;
                }

                var existingFields = web.Fields;
                web.Context.Load(web, w => w.ServerRelativeUrl);
                web.Context.Load(existingFields, fs => fs.Include(f => f.Id, f => f.SchemaXml, f => f.TypeAsString, f => f.InternalName, f => f.Title));
                web.Context.Load(web.Lists, ls => ls.Include(l => l.Id, l => l.Title));
                web.Context.ExecuteQueryRetry();

                var taxTextFieldsToMoveUp = new List<Guid>();

                foreach (var field in existingFields)
                {
                    if (!BuiltInFieldId.Contains(field.Id))
                    {
                        var fieldXml = field.SchemaXml;
                        XElement element = XElement.Parse(fieldXml);

                        // Check if the field contains a reference to a list. If by Guid, rewrite the value of the attribute to use web relative paths
                        var listIdentifier = element.Attribute("List") != null ? element.Attribute("List").Value : null;
                        if (!string.IsNullOrEmpty(listIdentifier))
                        {
                            var listGuid = Guid.Empty;
                            fieldXml = ParseFieldSchema(fieldXml, web.Lists);
                            element = XElement.Parse(fieldXml);
                            //if (Guid.TryParse(listIdentifier, out listGuid))
                            //{
                            //    fieldXml = ParseListSchema(fieldXml, web.Lists);
                            //if (newfieldXml == fieldXml)
                            //{
                            //    var list = web.Lists.GetById(listGuid);
                            //    web.Context.Load(list, l => l.RootFolder.ServerRelativeUrl);
                            //    web.Context.ExecuteQueryRetry();

                            //    var listUrl = list.RootFolder.ServerRelativeUrl.Substring(web.ServerRelativeUrl.Length).TrimStart('/');
                            //    element.Attribute("List").SetValue(listUrl);
                            //    fieldXml = element.ToString();
                            //}
                            //}
                        }
                        // Check if the field is of type TaxonomyField
                        if (field.TypeAsString.StartsWith("TaxonomyField"))
                        {
                            var taxField = (TaxonomyField)field;
                            web.Context.Load(taxField, tf => tf.TextField, tf => tf.Id);
                            web.Context.ExecuteQueryRetry();
                            taxTextFieldsToMoveUp.Add(taxField.TextField);

                            // Replace Taxonomy field references to SspId, TermSetId with tokens
                            TaxonomySession session = TaxonomySession.GetTaxonomySession(web.Context);
                            TermStore store = session.GetDefaultSiteCollectionTermStore();

                            var sspIdElement = element.XPathSelectElement("./Customization/ArrayOfProperty/Property[Name = 'SspId']/Value");
                            if (sspIdElement != null)
                            {
                                sspIdElement.Value = "{sitecollectiontermstoreid}";
                            }
                            var termSetIdElement = element.XPathSelectElement("./Customization/ArrayOfProperty/Property[Name = 'TermSetId']/Value");
                            if (termSetIdElement != null)
                            {
                                Guid termSetId = Guid.Parse(termSetIdElement.Value);
                                if (termSetId != Guid.Empty)
                                {
                                    Microsoft.SharePoint.Client.Taxonomy.TermSet termSet = store.GetTermSet(termSetId);
                                    if (!termSet.ServerObjectIsNull())
                                    {
                                        termSet.EnsureProperties(ts => ts.Name, ts => ts.Group);
                                        termSetIdElement.Value = String.Format("{{termsetid:{0}:{1}}}", termSet.Group.Name, termSet.Name); // TODO
                                    }
                                }
                            }
                        }
                        // Check if we have version attribute. Remove if exists
                        if (element.Attribute("Version") != null)
                        {
                            element.Attributes("Version").Remove();
                            fieldXml = element.ToString();
                        }
                        if (element.Attribute("Type").Value == "Calculated")
                        {
                            fieldXml = TokenizeFieldFormula(fieldXml);
                        }
                        template.SiteFields.Add(new Field() { SchemaXml = fieldXml });
                    }
                }
                // move hidden taxonomy text fields to the top of the list
                foreach (var textFieldId in taxTextFieldsToMoveUp)
                {
                    var field = template.SiteFields.First(f => Guid.Parse(f.SchemaXml.ElementAttributeValue("ID")).Equals(textFieldId));
                    template.SiteFields.RemoveAll(f => Guid.Parse(f.SchemaXml.ElementAttributeValue("ID")).Equals(textFieldId));
                    template.SiteFields.Insert(0, field);
                }
                // If a base template is specified then use that one to "cleanup" the generated template model
                if (creationInfo.BaseTemplate != null)
                {
                    template = CleanupEntities(template, creationInfo.BaseTemplate);
                }
            }
            return template;
        }
Example #35
0
        public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                if (template.Navigation != null)
                {
                    // The Navigation handler works only for sites with Publishing Features enabled
                    if (!web.IsPublishingWeb())
                    {
                        scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Navigation_Context_web_is_not_publishing);
                        return(parser);
                    }

                    // Retrieve the current web navigation settings
                    var navigationSettings = new WebNavigationSettings(web.Context, web);
                    web.Context.Load(navigationSettings, ns => ns.CurrentNavigation, ns => ns.GlobalNavigation);
                    web.Context.ExecuteQueryRetry();

                    if (template.Navigation.GlobalNavigation != null)
                    {
                        switch (template.Navigation.GlobalNavigation.NavigationType)
                        {
                        case GlobalNavigationType.Inherit:
                            navigationSettings.GlobalNavigation.Source = StandardNavigationSource.InheritFromParentWeb;
                            break;

                        case GlobalNavigationType.Managed:
                            if (template.Navigation.GlobalNavigation.ManagedNavigation == null)
                            {
                                throw new ApplicationException(CoreResources.Provisioning_ObjectHandlers_Navigation_missing_global_managed_navigation);
                            }
                            navigationSettings.GlobalNavigation.Source      = StandardNavigationSource.TaxonomyProvider;
                            navigationSettings.GlobalNavigation.TermStoreId = Guid.Parse(parser.ParseString(template.Navigation.GlobalNavigation.ManagedNavigation.TermStoreId));
                            navigationSettings.GlobalNavigation.TermSetId   = Guid.Parse(parser.ParseString(template.Navigation.GlobalNavigation.ManagedNavigation.TermSetId));
                            break;

                        case GlobalNavigationType.Structural:
                        default:
                            if (template.Navigation.GlobalNavigation.StructuralNavigation == null)
                            {
                                throw new ApplicationException(CoreResources.Provisioning_ObjectHandlers_Navigation_missing_global_structural_navigation);
                            }
                            ProvisionGlobalStructuralNavigation(web,
                                                                template.Navigation.GlobalNavigation.StructuralNavigation, parser);
                            break;
                        }
                        web.Context.ExecuteQueryRetry();
                    }

                    if (template.Navigation.CurrentNavigation != null)
                    {
                        switch (template.Navigation.CurrentNavigation.NavigationType)
                        {
                        case CurrentNavigationType.Inherit:
                            navigationSettings.CurrentNavigation.Source = StandardNavigationSource.InheritFromParentWeb;
                            break;

                        case CurrentNavigationType.Managed:
                            if (template.Navigation.CurrentNavigation.ManagedNavigation == null)
                            {
                                throw new ApplicationException(CoreResources.Provisioning_ObjectHandlers_Navigation_missing_current_managed_navigation);
                            }
                            navigationSettings.CurrentNavigation.Source      = StandardNavigationSource.TaxonomyProvider;
                            navigationSettings.CurrentNavigation.TermStoreId = Guid.Parse(parser.ParseString(template.Navigation.CurrentNavigation.ManagedNavigation.TermStoreId));
                            navigationSettings.CurrentNavigation.TermSetId   = Guid.Parse(parser.ParseString(template.Navigation.CurrentNavigation.ManagedNavigation.TermSetId));
                            break;

                        case CurrentNavigationType.StructuralLocal:
                            web.SetPropertyBagValue(NavigationShowSiblings, "false");
                            if (template.Navigation.CurrentNavigation.StructuralNavigation == null)
                            {
                                throw new ApplicationException(CoreResources.Provisioning_ObjectHandlers_Navigation_missing_current_structural_navigation);
                            }
                            ProvisionCurrentStructuralNavigation(web,
                                                                 template.Navigation.CurrentNavigation.StructuralNavigation, parser);
                            break;

                        case CurrentNavigationType.Structural:
                        default:
                            if (template.Navigation.CurrentNavigation.StructuralNavigation == null)
                            {
                                throw new ApplicationException(CoreResources.Provisioning_ObjectHandlers_Navigation_missing_current_structural_navigation);
                            }
                            ProvisionCurrentStructuralNavigation(web,
                                                                 template.Navigation.CurrentNavigation.StructuralNavigation, parser);
                            break;
                        }
                        web.Context.ExecuteQueryRetry();
                    }
                }
            }

            return(parser);
        }
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                web.EnsureProperties(w => w.ServerRelativeUrl, w => w.Url);

                var serverRelativeUrl = web.ServerRelativeUrl;

                // For each list in the site
                var lists = web.Lists;

                web.Context.Load(lists,
                    lc => lc.IncludeWithDefaultProperties(
                        l => l.ContentTypes,
                        l => l.Views,
                        l => l.BaseTemplate,
                        l => l.OnQuickLaunch,
                        l => l.RootFolder.ServerRelativeUrl,
                        l => l.Fields.IncludeWithDefaultProperties(
                            f => f.Id,
                            f => f.Title,
                            f => f.Hidden,
                            f => f.InternalName,
                            f => f.Required)));

                web.Context.ExecuteQueryRetry();

                // Let's see if there are workflow subscriptions
                Microsoft.SharePoint.Client.WorkflowServices.WorkflowSubscription[] workflowSubscriptions = null;
                try
                {
                    workflowSubscriptions = web.GetWorkflowSubscriptions();
                }
                catch (ServerException)
                {
                    // If there is no workflow service present in the farm this method will throw an error.
                    // Swallow the exception
                }

                // Retrieve all not hidden lists and the Workflow History Lists, just in case there are active workflow subscriptions
                var includeWorkflowSubscriptions = workflowSubscriptions != null && workflowSubscriptions.Length > 0;
               // var allowedLists = lists.Where(l => !l.Hidden || includeWorkflowSubscriptions && l.BaseTemplate == 140);

                foreach (var siteList in lists)
                {
                    ListInstance baseTemplateList = null;
                    if (creationInfo.BaseTemplate != null)
                    {
                        // Check if we need to skip this list...if so let's do it before we gather all the other information for this list...improves performance
                        var index = creationInfo.BaseTemplate.Lists.FindIndex(f => f.Url.Equals(siteList.RootFolder.ServerRelativeUrl.Substring(serverRelativeUrl.Length + 1)) &&
                                                                                   f.TemplateType.Equals(siteList.BaseTemplate));
                        if (index != -1)
                        {
                            baseTemplateList = creationInfo.BaseTemplate.Lists[index];
                            if (siteList.Hidden && !(includeWorkflowSubscriptions && siteList.BaseTemplate == 140))
                            {
                                continue;
                            }
                        }
                    }

                    var contentTypeFields = new List<FieldRef>();
                    var list = new ListInstance
                    {
                        Description = siteList.Description,
                        EnableVersioning = siteList.EnableVersioning,
                        TemplateType = siteList.BaseTemplate,
                        Title = siteList.Title,
                        Hidden = siteList.Hidden,
                        EnableFolderCreation = siteList.EnableFolderCreation,
                        DocumentTemplate = Tokenize(siteList.DocumentTemplateUrl, web.Url),
                        ContentTypesEnabled = siteList.ContentTypesEnabled,
                        Url = siteList.RootFolder.ServerRelativeUrl.Substring(serverRelativeUrl.Length).TrimStart('/'),
                        TemplateFeatureID = siteList.TemplateFeatureId,
                        EnableAttachments = siteList.EnableAttachments,
                        OnQuickLaunch = siteList.OnQuickLaunch,
                        MaxVersionLimit =
                            siteList.IsObjectPropertyInstantiated("MajorVersionLimit") ? siteList.MajorVersionLimit : 0,
                        EnableMinorVersions = siteList.EnableMinorVersions,
                        MinorVersionLimit =
                            siteList.IsObjectPropertyInstantiated("MajorWithMinorVersionsLimit")
                                ? siteList.MajorWithMinorVersionsLimit
                                : 0
                    };

                    list = ExtractContentTypes(web, siteList, contentTypeFields, list);

                    list = ExtractViews(siteList, list);

                    list = ExtractFields(web, siteList, contentTypeFields, list, lists);

                    list.Security = siteList.GetSecurity();

                    var logCTWarning = false;
                    if (baseTemplateList != null)
                    {
                        if (!baseTemplateList.Equals(list))
                        {
                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Adding_list___0_____1_, list.Title, list.Url);
                            template.Lists.Add(list);
                            if (list.ContentTypesEnabled && list.ContentTypeBindings.Any() && web.IsSubSite())
                            {
                                logCTWarning = true;
                            }
                        }
                    }
                    else
                    {
                        scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Adding_list___0_____1_, list.Title, list.Url);
                        template.Lists.Add(list);
                        if (list.ContentTypesEnabled && list.ContentTypeBindings.Any() && web.IsSubSite())
                        {
                            logCTWarning = true;
                        }

                    }
                    if (logCTWarning)
                    {
                        scope.LogWarning("You are extracting a template from a subweb. List '{0}' refers to content types. Content types are not exported when extracting a template from a subweb", list.Title);
                        WriteWarning(string.Format("You are extracting a template from a subweb. List '{0}' refers to content types. Content types are not exported when extracting a template from a subweb", list.Title), ProvisioningMessageType.Warning);
                    }
                }

            }
            return template;
        }
        private void DownLoadFile(SharePointConnector reader, SharePointConnector readerRoot, FileConnectorBase writer, string webUrl, string asset, PnPMonitoredScope scope)
        {
            // No file passed...leave
            if (String.IsNullOrEmpty(asset))
            {
                return;
            }

            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_DownLoadFile_Downloading_asset___0_, asset);
            ;

            SharePointConnector readerToUse;
            Model.File f = GetComposedLookFile(asset);

            // Strip the /sites/root part from /sites/root/lib/folder structure
            Uri u = new Uri(webUrl);
            if (f.Folder.IndexOf(u.PathAndQuery, StringComparison.InvariantCultureIgnoreCase) > -1)
            {
                f.Folder = f.Folder.Replace(u.PathAndQuery, "");
            }

            // in case of a theme catalog we need to use the root site reader as that list only exists on root site level
            if (f.Folder.IndexOf("/_catalogs/theme", StringComparison.InvariantCultureIgnoreCase) > -1)
            {
                readerToUse = readerRoot;
            }
            else
            {
                readerToUse = reader;
            }

            using (Stream s = readerToUse.GetFileStream(f.Src, f.Folder))
            {
                if (s != null)
                {
                    writer.SaveFileStream(f.Src, s);
                }
            }
        }
        public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {

                // if this is a sub site then we're not provisioning security as by default security is inherited from the root site
                if (web.IsSubSite())
                {
                    scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_SiteSecurity_Context_web_is_subweb__skipping_site_security_provisioning);
                    return parser;
                }

                var siteSecurity = template.Security;

                var ownerGroup = web.AssociatedOwnerGroup;
                var memberGroup = web.AssociatedMemberGroup;
                var visitorGroup = web.AssociatedVisitorGroup;

                web.Context.Load(ownerGroup, o => o.Title, o => o.Users);
                web.Context.Load(memberGroup, o => o.Title, o => o.Users);
                web.Context.Load(visitorGroup, o => o.Title, o => o.Users);

                web.Context.ExecuteQueryRetry();

                if (!ownerGroup.ServerObjectIsNull.Value)
                {
                    AddUserToGroup(web, ownerGroup, siteSecurity.AdditionalOwners, scope);
                }
                if (!memberGroup.ServerObjectIsNull.Value)
                {
                    AddUserToGroup(web, memberGroup, siteSecurity.AdditionalMembers, scope);
                }
                if (!visitorGroup.ServerObjectIsNull.Value)
                {
                    AddUserToGroup(web, visitorGroup, siteSecurity.AdditionalVisitors, scope);
                }

                foreach (var siteGroup in siteSecurity.SiteGroups)
                {
                    Group group = null;
                    var allGroups = web.Context.LoadQuery(web.SiteGroups.Include(gr => gr.LoginName));
                    web.Context.ExecuteQueryRetry();

                    if (!web.GroupExists(siteGroup.Title))
                    {
                        scope.LogDebug("Creating group {0}", siteGroup.Title);
                        group = web.AddGroup(
                            parser.ParseString(siteGroup.Title),
                            parser.ParseString(siteGroup.Description),
                            parser.ParseString(siteGroup.Title) == parser.ParseString(siteGroup.Owner));
                        group.AllowMembersEditMembership = siteGroup.AllowMembersEditMembership;
                        group.AllowRequestToJoinLeave = siteGroup.AllowRequestToJoinLeave;
                        group.AutoAcceptRequestToJoinLeave = siteGroup.AutoAcceptRequestToJoinLeave;

                        if (parser.ParseString(siteGroup.Title) != parser.ParseString(siteGroup.Owner))
                        {
                            Principal ownerPrincipal = allGroups.FirstOrDefault(gr => gr.LoginName == parser.ParseString(siteGroup.Owner));
                            if (ownerPrincipal == null)
                            {
                                ownerPrincipal = web.EnsureUser(parser.ParseString(siteGroup.Owner));
                            }
                            group.Owner = ownerPrincipal;

                        }
                        group.Update();
                        web.Context.ExecuteQueryRetry();
                    }
                    else
                    {
                        group = web.SiteGroups.GetByName(parser.ParseString(siteGroup.Title));
                        web.Context.Load(group,
                            g => g.Title,
                            g => g.Description,
                            g => g.AllowMembersEditMembership,
                            g => g.AllowRequestToJoinLeave,
                            g => g.AutoAcceptRequestToJoinLeave,
                            g => g.Owner.LoginName);
                        web.Context.ExecuteQueryRetry();
                        var isDirty = false;
                        if (group.Description != parser.ParseString(siteGroup.Description))
                        {
                            group.Description = parser.ParseString(siteGroup.Description);
                            isDirty = true;
                        }
                        if (group.AllowMembersEditMembership != siteGroup.AllowMembersEditMembership)
                        {
                            group.AllowMembersEditMembership = siteGroup.AllowMembersEditMembership;
                            isDirty = true;
                        }
                        if (group.AllowRequestToJoinLeave != siteGroup.AllowRequestToJoinLeave)
                        {
                            group.AllowRequestToJoinLeave = siteGroup.AllowRequestToJoinLeave;
                            isDirty = true;
                        }
                        if (group.AutoAcceptRequestToJoinLeave != siteGroup.AutoAcceptRequestToJoinLeave)
                        {
                            group.AutoAcceptRequestToJoinLeave = siteGroup.AutoAcceptRequestToJoinLeave;
                            isDirty = true;
                        }
                        if (group.Owner.LoginName != parser.ParseString(siteGroup.Owner))
                        {
                            if (parser.ParseString(siteGroup.Title) != parser.ParseString(siteGroup.Owner))
                            {
                                Principal ownerPrincipal = allGroups.FirstOrDefault(gr => gr.LoginName == parser.ParseString(siteGroup.Owner));
                                if (ownerPrincipal == null)
                                {
                                    ownerPrincipal = web.EnsureUser(parser.ParseString(siteGroup.Owner));
                                }
                                group.Owner = ownerPrincipal;
                            }
                            else
                            {
                                group.Owner = group;
                            }
                            isDirty = true;
                        }
                        if (isDirty)
                        {
                            scope.LogDebug("Updating existing group {0}", group.Title);
                            group.Update();
                            web.Context.ExecuteQueryRetry();
                        }
                    }
                    if (group != null && siteGroup.Members.Any())
                    {
                        AddUserToGroup(web, group, siteGroup.Members, scope);
                    }
                }

                foreach (var admin in siteSecurity.AdditionalAdministrators)
                {
                    var user = web.EnsureUser(admin.Name);
                    user.IsSiteAdmin = true;
                    user.Update();
                    web.Context.ExecuteQueryRetry();
                }

                if (siteSecurity.SiteSecurityPermissions != null)
                {
                    var existingRoleDefinitions = web.Context.LoadQuery(web.RoleDefinitions.Include(wr => wr.Name, wr => wr.BasePermissions, wr => wr.Description));
                    web.Context.ExecuteQueryRetry();

                    if (siteSecurity.SiteSecurityPermissions.RoleDefinitions.Any())
                    {
                        foreach (var templateRoleDefinition in siteSecurity.SiteSecurityPermissions.RoleDefinitions)
                        {
                            var siteRoleDefinition = existingRoleDefinitions.FirstOrDefault(erd => erd.Name == parser.ParseString(templateRoleDefinition.Name));
                            if (siteRoleDefinition == null)
                            {
                                scope.LogDebug("Creation role definition {0}", parser.ParseString(templateRoleDefinition.Name));
                                var roleDefinitionCI = new RoleDefinitionCreationInformation();
                                roleDefinitionCI.Name = parser.ParseString(templateRoleDefinition.Name);
                                roleDefinitionCI.Description = parser.ParseString(templateRoleDefinition.Description);
                                BasePermissions basePermissions = new BasePermissions();

                                foreach (var permission in templateRoleDefinition.Permissions)
                                {
                                    basePermissions.Set(permission);
                                }

                                roleDefinitionCI.BasePermissions = basePermissions;

                                web.RoleDefinitions.Add(roleDefinitionCI);
                                web.Context.ExecuteQueryRetry();
                            }
                            else
                            {
                                var isDirty = false;
                                if (siteRoleDefinition.Description != parser.ParseString(templateRoleDefinition.Description))
                                {
                                    siteRoleDefinition.Description = parser.ParseString(templateRoleDefinition.Description);
                                    isDirty = true;
                                }
                                var templateBasePermissions = new BasePermissions();
                                templateRoleDefinition.Permissions.ForEach(p => templateBasePermissions.Set(p));
                                if (siteRoleDefinition.BasePermissions != templateBasePermissions)
                                {
                                    isDirty = true;
                                    foreach (var permission in templateRoleDefinition.Permissions)
                                    {
                                        siteRoleDefinition.BasePermissions.Set(permission);
                                    }
                                }
                                if (isDirty)
                                {
                                    scope.LogDebug("Updating role definition {0}", parser.ParseString(templateRoleDefinition.Name));
                                    siteRoleDefinition.Update();
                                    web.Context.ExecuteQueryRetry();
                                }
                            }
                        }
                    }

                    var webRoleDefinitions = web.Context.LoadQuery(web.RoleDefinitions);
                    var groups = web.Context.LoadQuery(web.SiteGroups.Include(g => g.LoginName));
                    web.Context.ExecuteQueryRetry();

                    if (siteSecurity.SiteSecurityPermissions.RoleAssignments.Any())
                    {
                        foreach (var roleAssignment in siteSecurity.SiteSecurityPermissions.RoleAssignments)
                        {
                            Principal principal = groups.FirstOrDefault(g => g.LoginName == parser.ParseString(roleAssignment.Principal));
                            if (principal == null)
                            {
                                principal = web.EnsureUser(parser.ParseString(roleAssignment.Principal));
                            }

                            var roleDefinitionBindingCollection = new RoleDefinitionBindingCollection(web.Context);

                            var roleDefinition = webRoleDefinitions.FirstOrDefault(r => r.Name == roleAssignment.RoleDefinition);

                            if (roleDefinition != null)
                            {
                                roleDefinitionBindingCollection.Add(roleDefinition);
                            }
                            web.RoleAssignments.Add(principal, roleDefinitionBindingCollection);
                            web.Context.ExecuteQueryRetry();
                        }
                    }
                }
            }
            return parser;
        }
Example #39
0
        /// <summary>
        /// Actual implementation of extracting configuration from existing site.
        /// </summary>
        /// <param name="web"></param>
        /// <param name="creationInfo"></param>
        /// <returns></returns>
        internal ProvisioningTemplate GetRemoteTemplate(Web web, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(CoreResources.Provisioning_ObjectHandlers_Extraction))
            {
                ProvisioningProgressDelegate progressDelegate = null;
                ProvisioningMessagesDelegate messagesDelegate = null;
                if (creationInfo != null)
                {
                    if (creationInfo.BaseTemplate != null)
                    {
                        scope.LogDebug(CoreResources.SiteToTemplateConversion_Base_template_available___0_, creationInfo.BaseTemplate.Id);
                    }
                    progressDelegate = creationInfo.ProgressDelegate;
                    if (creationInfo.ProgressDelegate != null)
                    {
                        scope.LogDebug(CoreResources.SiteToTemplateConversion_ProgressDelegate_registered);
                    }
                    messagesDelegate = creationInfo.MessagesDelegate;
                    if (creationInfo.MessagesDelegate != null)
                    {
                        scope.LogDebug(CoreResources.SiteToTemplateConversion_MessagesDelegate_registered);
                    }
                    if (creationInfo.IncludeAllTermGroups)
                    {
                        scope.LogDebug(CoreResources.SiteToTemplateConversion_IncludeAllTermGroups_is_set_to_true);
                    }
                    if (creationInfo.IncludeSiteCollectionTermGroup)
                    {
                        scope.LogDebug(CoreResources.SiteToTemplateConversion_IncludeSiteCollectionTermGroup_is_set_to_true);
                    }
                    if (creationInfo.PersistComposedLookFiles)
                    {
                        scope.LogDebug(CoreResources.SiteToTemplateConversion_PersistComposedLookFiles_is_set_to_true);
                    }
                }

                // Create empty object
                ProvisioningTemplate template = new ProvisioningTemplate();

                // Hookup connector, is handy when the generated template object is used to apply to another site
                template.Connector = creationInfo.FileConnector;

                List <ObjectHandlerBase> objectHandlers = new List <ObjectHandlerBase>();

                objectHandlers.Add(new ObjectRegionalSettings());
                objectHandlers.Add(new ObjectSupportedUILanguages());
                objectHandlers.Add(new ObjectAuditSettings());
                objectHandlers.Add(new ObjectSitePolicy());
                objectHandlers.Add(new ObjectSiteSecurity());
                objectHandlers.Add(new ObjectTermGroups());
                objectHandlers.Add(new ObjectField());
                objectHandlers.Add(new ObjectContentType());
                objectHandlers.Add(new ObjectListInstance());
                objectHandlers.Add(new ObjectCustomActions());
                objectHandlers.Add(new ObjectFeatures());
                objectHandlers.Add(new ObjectComposedLook());
                objectHandlers.Add(new ObjectSearchSettings());
                objectHandlers.Add(new ObjectFiles());
                objectHandlers.Add(new ObjectPages());
                objectHandlers.Add(new ObjectPropertyBagEntry());
                objectHandlers.Add(new ObjectPublishing());
                objectHandlers.Add(new ObjectWorkflows());
                objectHandlers.Add(new ObjectRetrieveTemplateInfo());

                int step = 1;

                var count = objectHandlers.Count(o => o.ReportProgress && o.WillExtract(web, template, creationInfo));

                foreach (var handler in objectHandlers)
                {
                    if (handler.WillExtract(web, template, creationInfo))
                    {
                        if (messagesDelegate != null)
                        {
                            handler.MessagesDelegate = messagesDelegate;
                        }
                        if (handler.ReportProgress && progressDelegate != null)
                        {
                            progressDelegate(handler.Name, step, count);
                            step++;
                        }
                        template = handler.ExtractObjects(web, template, creationInfo);
                    }
                }
                return(template);
            }
        }
        public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                if (template.Lists.Any())
                {
                    var rootWeb = (web.Context as ClientContext).Site.RootWeb;

                    web.EnsureProperties(w => w.ServerRelativeUrl);

                    web.Context.Load(web.Lists, lc => lc.IncludeWithDefaultProperties(l => l.RootFolder.ServerRelativeUrl));
                    web.Context.ExecuteQueryRetry();
                    var existingLists     = web.Lists.AsEnumerable <List>().Select(existingList => existingList.RootFolder.ServerRelativeUrl).ToList();
                    var serverRelativeUrl = web.ServerRelativeUrl;

                    #region DataRows

                    foreach (var listInstance in template.Lists)
                    {
                        if (listInstance.DataRows != null && listInstance.DataRows.Any())
                        {
                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Processing_data_rows_for__0_, listInstance.Title);
                            // Retrieve the target list
                            var list = web.Lists.GetByTitle(parser.ParseString(listInstance.Title));
                            web.Context.Load(list);

                            // Retrieve the fields' types from the list
                            Microsoft.SharePoint.Client.FieldCollection fields = list.Fields;
                            web.Context.Load(fields, fs => fs.Include(f => f.InternalName, f => f.FieldTypeKind));
                            web.Context.ExecuteQueryRetry();

                            foreach (var dataRow in listInstance.DataRows)
                            {
                                try
                                {
                                    scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Creating_list_item__0_, listInstance.DataRows.IndexOf(dataRow) + 1);
                                    var listitemCI = new ListItemCreationInformation();
                                    var listitem   = list.AddItem(listitemCI);

                                    foreach (var dataValue in dataRow.Values)
                                    {
                                        Field dataField = fields.FirstOrDefault(
                                            f => f.InternalName == parser.ParseString(dataValue.Key));

                                        if (dataField != null)
                                        {
                                            String fieldValue = parser.ParseString(dataValue.Value);

                                            switch (dataField.FieldTypeKind)
                                            {
                                            case FieldType.Geolocation:
                                                // FieldGeolocationValue - Expected format: Altitude,Latitude,Longitude,Measure
                                                var geolocationArray = fieldValue.Split(',');
                                                if (geolocationArray.Length == 4)
                                                {
                                                    var geolocationValue = new FieldGeolocationValue
                                                    {
                                                        Altitude  = Double.Parse(geolocationArray[0]),
                                                        Latitude  = Double.Parse(geolocationArray[1]),
                                                        Longitude = Double.Parse(geolocationArray[2]),
                                                        Measure   = Double.Parse(geolocationArray[3]),
                                                    };
                                                    listitem[parser.ParseString(dataValue.Key)] = geolocationValue;
                                                }
                                                else
                                                {
                                                    listitem[parser.ParseString(dataValue.Key)] = fieldValue;
                                                }
                                                break;

                                            case FieldType.Lookup:
                                                // FieldLookupValue - Expected format: LookupID or LookupID,LookupID,LookupID...
                                                if (fieldValue.Contains(","))
                                                {
                                                    var lookupValues = new List <FieldLookupValue>();
                                                    fieldValue.Split(',').All(value =>
                                                    {
                                                        lookupValues.Add(new FieldLookupValue
                                                        {
                                                            LookupId = int.Parse(value),
                                                        });
                                                        return(true);
                                                    });
                                                    listitem[parser.ParseString(dataValue.Key)] = lookupValues.ToArray();
                                                }
                                                else
                                                {
                                                    var lookupValue = new FieldLookupValue
                                                    {
                                                        LookupId = int.Parse(fieldValue),
                                                    };
                                                    listitem[parser.ParseString(dataValue.Key)] = lookupValue;
                                                }
                                                break;

                                            case FieldType.URL:
                                                // FieldUrlValue - Expected format: URL,Description
                                                var urlArray  = fieldValue.Split(',');
                                                var linkValue = new FieldUrlValue();
                                                if (urlArray.Length == 2)
                                                {
                                                    linkValue.Url         = urlArray[0];
                                                    linkValue.Description = urlArray[1];
                                                }
                                                else
                                                {
                                                    linkValue.Url         = urlArray[0];
                                                    linkValue.Description = urlArray[0];
                                                }
                                                listitem[parser.ParseString(dataValue.Key)] = linkValue;
                                                break;

                                            case FieldType.User:
                                                // FieldUserValue - Expected format: loginName or loginName,loginName,loginName...
                                                if (fieldValue.Contains(","))
                                                {
                                                    var userValues = new List <FieldUserValue>();
                                                    fieldValue.Split(',').All(value =>
                                                    {
                                                        var user = web.EnsureUser(value);
                                                        web.Context.Load(user);
                                                        web.Context.ExecuteQueryRetry();
                                                        if (user != null)
                                                        {
                                                            userValues.Add(new FieldUserValue
                                                            {
                                                                LookupId = user.Id,
                                                            });;
                                                        }
                                                        return(true);
                                                    });
                                                    listitem[parser.ParseString(dataValue.Key)] = userValues.ToArray();
                                                }
                                                else
                                                {
                                                    var user = web.EnsureUser(fieldValue);
                                                    web.Context.Load(user);
                                                    web.Context.ExecuteQueryRetry();
                                                    if (user != null)
                                                    {
                                                        var userValue = new FieldUserValue
                                                        {
                                                            LookupId = user.Id,
                                                        };
                                                        listitem[parser.ParseString(dataValue.Key)] = userValue;
                                                    }
                                                    else
                                                    {
                                                        listitem[parser.ParseString(dataValue.Key)] = fieldValue;
                                                    }
                                                }
                                                break;

                                            case FieldType.DateTime:
                                                var dateTime = DateTime.MinValue;
                                                if (DateTime.TryParse(fieldValue, out dateTime))
                                                {
                                                    listitem[parser.ParseString(dataValue.Key)] = dateTime;
                                                }
                                                break;

                                            default:
                                                listitem[parser.ParseString(dataValue.Key)] = fieldValue;
                                                break;
                                            }
                                        }
                                    }
                                    listitem.Update();
                                    web.Context.ExecuteQueryRetry(); // TODO: Run in batches?

                                    if (dataRow.Security != null && dataRow.Security.RoleAssignments.Count != 0)
                                    {
                                        listitem.SetSecurity(parser, dataRow.Security);
                                    }
                                }
                                catch (Exception ex)
                                {
                                    if (ex.GetType().Equals(typeof(ServerException)) &&
                                        (ex as ServerException).ServerErrorTypeName.Equals("Microsoft.SharePoint.SPDuplicateValuesFoundException", StringComparison.InvariantCultureIgnoreCase) &&
                                        applyingInformation.IgnoreDuplicateDataRowErrors)
                                    {
                                        scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Creating_listitem_duplicate);
                                        continue;
                                    }
                                    else
                                    {
                                        scope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Creating_listitem_failed___0_____1_, ex.Message, ex.StackTrace);
                                        throw;
                                    }
                                }
                            }
                        }
                    }

                    #endregion
                }
            }

            return(parser);
        }
        private void ProvisionCustomActionImplementation(object parent, List<CustomAction> customActions, TokenParser parser, PnPMonitoredScope scope)
        {
            Web web = null;
            Site site = null;
            if (parent is Site)
            {
                site = parent as Site;

                // Switch parser context;
                parser.Rebase(site.RootWeb);
            }
            else
            {
                web = parent as Web;

                // Switch parser context
                parser.Rebase(web);
            }
            foreach (var customAction in customActions)
            {
                var caExists = false;
                if (site != null)
                {
                    caExists = site.CustomActionExists(customAction.Name);
                }
                else
                {
                    caExists = web.CustomActionExists(customAction.Name);
                }
                if (!caExists)
                {
                    var customActionEntity = new CustomActionEntity()
                    {
                        CommandUIExtension = customAction.CommandUIExtension != null ? parser.ParseString(customAction.CommandUIExtension.ToString()) : string.Empty,
                        Description = customAction.Description,
                        Group = customAction.Group,
                        ImageUrl = parser.ParseString(customAction.ImageUrl),
                        Location = customAction.Location,
                        Name = customAction.Name,
                        RegistrationId = customAction.RegistrationId,
                        RegistrationType = customAction.RegistrationType,
                        Remove = customAction.Remove,
                        Rights = customAction.Rights,
                        ScriptBlock = parser.ParseString(customAction.ScriptBlock),
                        ScriptSrc = parser.ParseString(customAction.ScriptSrc, "~site", "~sitecollection"),
                        Sequence = customAction.Sequence,
                        Title = customAction.Title,
                        Url = parser.ParseString(customAction.Url)
                    };

                    if (site != null)
                    {
                        scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Adding_custom_action___0___to_scope_Site, customActionEntity.Name);
                        site.AddCustomAction(customActionEntity);
                    }
                    else
                    {
                        scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_CustomActions_Adding_custom_action___0___to_scope_Web, customActionEntity.Name);
                        web.AddCustomAction(customActionEntity);
                    }
                }
                else
                {
                    UserCustomAction existingCustomAction = null;
                    if (site != null)
                    {
                        existingCustomAction = site.GetCustomActions().FirstOrDefault(c => c.Name == customAction.Name);
                    }
                    else
                    {
                        existingCustomAction = web.GetCustomActions().FirstOrDefault(c => c.Name == customAction.Name);
                    }
                    if (existingCustomAction != null)
                    {
                        var isDirty = false;

                        if (customAction.CommandUIExtension != null)
                        {
                            if (existingCustomAction.CommandUIExtension != parser.ParseString(customAction.CommandUIExtension.ToString()))
                            {
                                scope.LogPropertyUpdate("CommandUIExtension");
                                existingCustomAction.CommandUIExtension = parser.ParseString(customAction.CommandUIExtension.ToString());
                                isDirty = true;
                            }
                        }

                        if (existingCustomAction.Description != customAction.Description)
                        {
                            scope.LogPropertyUpdate("Description");
                            existingCustomAction.Description = customAction.Description;
                            isDirty = true;
                        }
                        if (existingCustomAction.Group != customAction.Group)
                        {
                            scope.LogPropertyUpdate("Group");
                            existingCustomAction.Group = customAction.Group;
                            isDirty = true;
                        }
                        if (existingCustomAction.ImageUrl != parser.ParseString(customAction.ImageUrl))
                        {
                            scope.LogPropertyUpdate("ImageUrl");
                            existingCustomAction.ImageUrl = parser.ParseString(customAction.ImageUrl);
                            isDirty = true;
                        }
                        if (existingCustomAction.Location != customAction.Location)
                        {
                            scope.LogPropertyUpdate("Location");
                            existingCustomAction.Location = customAction.Location;
                            isDirty = true;
                        }
                        if (existingCustomAction.RegistrationId != customAction.RegistrationId)
                        {
                            scope.LogPropertyUpdate("RegistrationId");
                            existingCustomAction.RegistrationId = customAction.RegistrationId;
                            isDirty = true;
                        }
                        if (existingCustomAction.RegistrationType != customAction.RegistrationType)
                        {
                            scope.LogPropertyUpdate("RegistrationType");
                            existingCustomAction.RegistrationType = customAction.RegistrationType;
                            isDirty = true;
                        }
                        if (existingCustomAction.ScriptBlock != parser.ParseString(customAction.ScriptBlock))
                        {
                            scope.LogPropertyUpdate("ScriptBlock");
                            existingCustomAction.ScriptBlock = parser.ParseString(customAction.ScriptBlock);
                            isDirty = true;
                        }
                        if (existingCustomAction.ScriptSrc != parser.ParseString(customAction.ScriptSrc, "~site", "~sitecollection"))
                        {
                            scope.LogPropertyUpdate("ScriptSrc");
                            existingCustomAction.ScriptSrc = parser.ParseString(customAction.ScriptSrc, "~site", "~sitecollection");
                            isDirty = true;
                        }
                        if (existingCustomAction.Title != parser.ParseString(customAction.Title))
                        {
                            scope.LogPropertyUpdate("Title");
                            existingCustomAction.Title = parser.ParseString(customAction.Title);
                            isDirty = true;
                        }
                        if (existingCustomAction.Url != parser.ParseString(customAction.Url))
                        {
                            scope.LogPropertyUpdate("Url");
                            existingCustomAction.Url = parser.ParseString(customAction.Url);
                            isDirty = true;
                        }
                        if (isDirty)
                        {
                            existingCustomAction.Update();
                            existingCustomAction.Context.ExecuteQueryRetry();
                        }
                    }
                }
            }
        }
Example #42
0
        private static TokenParser ProvisionFeaturesImplementation <T>(T parent, IEnumerable <Feature> features, TokenParser parser, PnPMonitoredScope scope)
        {
            var  activeFeatures = new List <Microsoft.SharePoint.Client.Feature>();
            Web  web            = null;
            Site site           = null;

            if (parent is Site)
            {
                site = parent as Site;
                site.Context.Load(site.Features, fs => fs.Include(f => f.DefinitionId));
                site.Context.ExecuteQueryRetry();
                activeFeatures = site.Features.ToList();
            }
            else
            {
                web = parent as Web;
                web.Context.Load(web.Features, fs => fs.Include(f => f.DefinitionId));
                web.Context.ExecuteQueryRetry();
                activeFeatures = web.Features.ToList();
            }

            if (features != null)
            {
                foreach (var feature in features)
                {
                    if (!feature.Deactivate)
                    {
                        if (activeFeatures.FirstOrDefault(f => f.DefinitionId == feature.Id) == null)
                        {
                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Features_Activating__0__scoped_feature__1_, site != null ? "site" : "web", feature.Id);
                            if (site != null)
                            {
                                try
                                {
                                    site.ActivateFeature(feature.Id);
                                }
                                catch (ServerException ex)
                                {
                                    scope.LogError("Error activating feature {0}: {1}", feature.Id, ex.Message);
                                }
                            }
                            else
                            {
                                try
                                {
                                    web.ActivateFeature(feature.Id);
                                }
                                catch (ServerException ex)
                                {
                                    scope.LogError("Error activating feature {0}: {1}", feature.Id, ex.Message);
                                }
                            }
                        }
                    }
                    else
                    {
                        if (activeFeatures.FirstOrDefault(f => f.DefinitionId == feature.Id) != null)
                        {
                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Features_Deactivating__0__scoped_feature__1_, site != null ? "site" : "web", feature.Id);
                            if (site != null)
                            {
                                try
                                {
                                    site.DeactivateFeature(feature.Id);
                                }
                                catch (ServerException ex)
                                {
                                    scope.LogError("Error deactivating feature {0}: {1}", feature.Id, ex.Message);
                                }
                            }
                            else
                            {
                                try
                                {
                                    web.DeactivateFeature(feature.Id);
                                }
                                catch (ServerException ex)
                                {
                                    scope.LogError("Error deactivating feature {0}: {1}", feature.Id, ex.Message);
                                }
                            }
                        }
                    }
                }
            }
            if (parent is Site)
            {
                parser.RebuildListTokens((parent as Site).RootWeb);
            }
            else
            {
                parser.RebuildListTokens(parent as Web);
            }
            return(parser);
        }
        public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                // Changed by Paolo Pialorsi to embrace the new sub-site attributes for break role inheritance and copy role assignments
                // if this is a sub site then we're not provisioning security as by default security is inherited from the root site
                //if (web.IsSubSite() && !template.Security.BreakRoleInheritance)
                //{
                //    scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_SiteSecurity_Context_web_is_subweb__skipping_site_security_provisioning);
                //    return parser;
                //}

                if (web.IsSubSite() && template.Security.BreakRoleInheritance)
                {
                    web.BreakRoleInheritance(template.Security.CopyRoleAssignments, template.Security.ClearSubscopes);
                    web.Update();
                    web.Context.ExecuteQueryRetry();
                }

                var siteSecurity = template.Security;

                var ownerGroup   = web.AssociatedOwnerGroup;
                var memberGroup  = web.AssociatedMemberGroup;
                var visitorGroup = web.AssociatedVisitorGroup;


                web.Context.Load(ownerGroup, o => o.Title, o => o.Users);
                web.Context.Load(memberGroup, o => o.Title, o => o.Users);
                web.Context.Load(visitorGroup, o => o.Title, o => o.Users);

                web.Context.ExecuteQueryRetry();

                if (!ownerGroup.ServerObjectIsNull.Value)
                {
                    AddUserToGroup(web, ownerGroup, siteSecurity.AdditionalOwners, scope, parser);
                }
                if (!memberGroup.ServerObjectIsNull.Value)
                {
                    AddUserToGroup(web, memberGroup, siteSecurity.AdditionalMembers, scope, parser);
                }
                if (!visitorGroup.ServerObjectIsNull.Value)
                {
                    AddUserToGroup(web, visitorGroup, siteSecurity.AdditionalVisitors, scope, parser);
                }

                foreach (var siteGroup in siteSecurity.SiteGroups)
                {
                    Group group;
                    var   allGroups = web.Context.LoadQuery(web.SiteGroups.Include(gr => gr.LoginName));
                    web.Context.ExecuteQueryRetry();

                    string parsedGroupTitle       = parser.ParseString(siteGroup.Title);
                    string parsedGroupOwner       = parser.ParseString(siteGroup.Owner);
                    string parsedGroupDescription = parser.ParseString(siteGroup.Description);

                    if (!web.GroupExists(parsedGroupTitle))
                    {
                        scope.LogDebug("Creating group {0}", parsedGroupTitle);
                        group = web.AddGroup(
                            parsedGroupTitle,
                            parsedGroupDescription,
                            parsedGroupTitle == parsedGroupOwner);
                        group.AllowMembersEditMembership   = siteGroup.AllowMembersEditMembership;
                        group.AllowRequestToJoinLeave      = siteGroup.AllowRequestToJoinLeave;
                        group.AutoAcceptRequestToJoinLeave = siteGroup.AutoAcceptRequestToJoinLeave;

                        if (parsedGroupTitle != parsedGroupOwner)
                        {
                            Principal ownerPrincipal = allGroups.FirstOrDefault(gr => gr.LoginName == parsedGroupOwner);
                            if (ownerPrincipal == null)
                            {
                                ownerPrincipal = web.EnsureUser(parsedGroupOwner);
                            }
                            group.Owner = ownerPrincipal;
                        }
                        group.Update();
                        web.Context.Load(group, g => g.Id, g => g.Title);
                        web.Context.ExecuteQueryRetry();
                        parser.AddToken(new GroupIdToken(web, group.Title, group.Id));
                    }
                    else
                    {
                        group = web.SiteGroups.GetByName(parsedGroupTitle);
                        web.Context.Load(group,
                                         g => g.Title,
                                         g => g.Description,
                                         g => g.AllowMembersEditMembership,
                                         g => g.AllowRequestToJoinLeave,
                                         g => g.AutoAcceptRequestToJoinLeave,
                                         g => g.Owner.LoginName);
                        web.Context.ExecuteQueryRetry();
                        var isDirty = false;
                        if (!String.IsNullOrEmpty(group.Description) && group.Description != parsedGroupDescription)
                        {
                            group.Description = parsedGroupDescription;
                            isDirty           = true;
                        }
                        if (group.AllowMembersEditMembership != siteGroup.AllowMembersEditMembership)
                        {
                            group.AllowMembersEditMembership = siteGroup.AllowMembersEditMembership;
                            isDirty = true;
                        }
                        if (group.AllowRequestToJoinLeave != siteGroup.AllowRequestToJoinLeave)
                        {
                            group.AllowRequestToJoinLeave = siteGroup.AllowRequestToJoinLeave;
                            isDirty = true;
                        }
                        if (group.AutoAcceptRequestToJoinLeave != siteGroup.AutoAcceptRequestToJoinLeave)
                        {
                            group.AutoAcceptRequestToJoinLeave = siteGroup.AutoAcceptRequestToJoinLeave;
                            isDirty = true;
                        }
                        if (group.Owner.LoginName != parsedGroupOwner)
                        {
                            if (parsedGroupTitle != parsedGroupOwner)
                            {
                                Principal ownerPrincipal = allGroups.FirstOrDefault(gr => gr.LoginName == parsedGroupOwner);
                                if (ownerPrincipal == null)
                                {
                                    ownerPrincipal = web.EnsureUser(parsedGroupOwner);
                                }
                                group.Owner = ownerPrincipal;
                            }
                            else
                            {
                                group.Owner = group;
                            }
                            isDirty = true;
                        }
                        if (isDirty)
                        {
                            scope.LogDebug("Updating existing group {0}", group.Title);
                            group.Update();
                            web.Context.ExecuteQueryRetry();
                        }
                    }
                    if (group != null && siteGroup.Members.Any())
                    {
                        AddUserToGroup(web, group, siteGroup.Members, scope, parser);
                    }
                }

                foreach (var admin in siteSecurity.AdditionalAdministrators)
                {
                    var parsedAdminName = parser.ParseString(admin.Name);
                    var user            = web.EnsureUser(parsedAdminName);
                    user.IsSiteAdmin = true;
                    user.Update();
                    web.Context.ExecuteQueryRetry();
                }

                if (!web.IsSubSite() && siteSecurity.SiteSecurityPermissions != null) // Only manage permissions levels on sitecol level
                {
                    var existingRoleDefinitions = web.Context.LoadQuery(web.RoleDefinitions.Include(wr => wr.Name, wr => wr.BasePermissions, wr => wr.Description));
                    web.Context.ExecuteQueryRetry();

                    if (siteSecurity.SiteSecurityPermissions.RoleDefinitions.Any())
                    {
                        foreach (var templateRoleDefinition in siteSecurity.SiteSecurityPermissions.RoleDefinitions)
                        {
                            var roleDefinitions    = existingRoleDefinitions as RoleDefinition[] ?? existingRoleDefinitions.ToArray();
                            var siteRoleDefinition = roleDefinitions.FirstOrDefault(erd => erd.Name == parser.ParseString(templateRoleDefinition.Name));
                            if (siteRoleDefinition == null)
                            {
                                scope.LogDebug("Creation role definition {0}", parser.ParseString(templateRoleDefinition.Name));
                                var roleDefinitionCI = new RoleDefinitionCreationInformation();
                                roleDefinitionCI.Name        = parser.ParseString(templateRoleDefinition.Name);
                                roleDefinitionCI.Description = parser.ParseString(templateRoleDefinition.Description);
                                BasePermissions basePermissions = new BasePermissions();

                                foreach (var permission in templateRoleDefinition.Permissions)
                                {
                                    basePermissions.Set(permission);
                                }

                                roleDefinitionCI.BasePermissions = basePermissions;

                                web.RoleDefinitions.Add(roleDefinitionCI);
                                web.Context.ExecuteQueryRetry();
                            }
                            else
                            {
                                var isDirty = false;
                                if (siteRoleDefinition.Description != parser.ParseString(templateRoleDefinition.Description))
                                {
                                    siteRoleDefinition.Description = parser.ParseString(templateRoleDefinition.Description);
                                    isDirty = true;
                                }
                                var templateBasePermissions = new BasePermissions();
                                templateRoleDefinition.Permissions.ForEach(p => templateBasePermissions.Set(p));
                                if (siteRoleDefinition.BasePermissions != templateBasePermissions)
                                {
                                    isDirty = true;
                                    foreach (var permission in templateRoleDefinition.Permissions)
                                    {
                                        siteRoleDefinition.BasePermissions.Set(permission);
                                    }
                                }
                                if (isDirty)
                                {
                                    scope.LogDebug("Updating role definition {0}", parser.ParseString(templateRoleDefinition.Name));
                                    siteRoleDefinition.Update();
                                    web.Context.ExecuteQueryRetry();
                                }
                            }
                        }
                    }

                    var webRoleDefinitions = web.Context.LoadQuery(web.RoleDefinitions);
                    var groups             = web.Context.LoadQuery(web.SiteGroups.Include(g => g.LoginName));
                    web.Context.ExecuteQueryRetry();

                    if (siteSecurity.SiteSecurityPermissions.RoleAssignments.Any())
                    {
                        foreach (var roleAssignment in siteSecurity.SiteSecurityPermissions.RoleAssignments)
                        {
                            Principal principal = groups.FirstOrDefault(g => g.LoginName == parser.ParseString(roleAssignment.Principal));
                            if (principal == null)
                            {
                                principal = web.EnsureUser(parser.ParseString(roleAssignment.Principal));
                            }

                            var roleDefinitionBindingCollection = new RoleDefinitionBindingCollection(web.Context);

                            var roleDefinition = webRoleDefinitions.FirstOrDefault(r => r.Name == parser.ParseString(roleAssignment.RoleDefinition));

                            if (roleDefinition != null)
                            {
                                roleDefinitionBindingCollection.Add(roleDefinition);
                            }
                            web.RoleAssignments.Add(principal, roleDefinitionBindingCollection);
                            web.Context.ExecuteQueryRetry();
                        }
                    }
                }
            }
            return(parser);
        }
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                web.EnsureProperties(w => w.HasUniqueRoleAssignments, w => w.Title);

                // Changed by Paolo Pialorsi to embrace the new sub-site attributes for break role inheritance and copy role assignments
                // if this is a sub site then we're not creating security entities as by default security is inherited from the root site
                if (web.IsSubSite() && !web.HasUniqueRoleAssignments)
                {
                    return(template);
                }

                var ownerGroup   = web.AssociatedOwnerGroup;
                var memberGroup  = web.AssociatedMemberGroup;
                var visitorGroup = web.AssociatedVisitorGroup;
                web.Context.ExecuteQueryRetry();

                if (!ownerGroup.ServerObjectIsNull.Value)
                {
                    web.Context.Load(ownerGroup, o => o.Id, o => o.Users, o => o.Title);
                }
                if (!memberGroup.ServerObjectIsNull.Value)
                {
                    web.Context.Load(memberGroup, o => o.Id, o => o.Users, o => o.Title);
                }
                if (!visitorGroup.ServerObjectIsNull.Value)
                {
                    web.Context.Load(visitorGroup, o => o.Id, o => o.Users, o => o.Title);
                }
                web.Context.ExecuteQueryRetry();

                List <int> associatedGroupIds = new List <int>();
                var        owners             = new List <User>();
                var        members            = new List <User>();
                var        visitors           = new List <User>();
                if (!ownerGroup.ServerObjectIsNull.Value)
                {
                    associatedGroupIds.Add(ownerGroup.Id);
                    foreach (var member in ownerGroup.Users)
                    {
                        owners.Add(new User()
                        {
                            Name = member.LoginName
                        });
                    }
                }
                if (!memberGroup.ServerObjectIsNull.Value)
                {
                    associatedGroupIds.Add(memberGroup.Id);
                    foreach (var member in memberGroup.Users)
                    {
                        members.Add(new User()
                        {
                            Name = member.LoginName
                        });
                    }
                }
                if (!visitorGroup.ServerObjectIsNull.Value)
                {
                    associatedGroupIds.Add(visitorGroup.Id);
                    foreach (var member in visitorGroup.Users)
                    {
                        visitors.Add(new User()
                        {
                            Name = member.LoginName
                        });
                    }
                }
                var siteSecurity = new SiteSecurity();
                siteSecurity.AdditionalOwners.AddRange(owners);
                siteSecurity.AdditionalMembers.AddRange(members);
                siteSecurity.AdditionalVisitors.AddRange(visitors);

                var query = from user in web.SiteUsers
                            where user.IsSiteAdmin
                            select user;
                var allUsers = web.Context.LoadQuery(query);

                web.Context.ExecuteQueryRetry();

                var admins = new List <User>();
                foreach (var member in allUsers)
                {
                    admins.Add(new User()
                    {
                        Name = member.LoginName
                    });
                }
                siteSecurity.AdditionalAdministrators.AddRange(admins);

                if (creationInfo.IncludeSiteGroups)
                {
                    web.Context.Load(web.SiteGroups,
                                     o => o.IncludeWithDefaultProperties(
                                         gr => gr.Title,
                                         gr => gr.AllowMembersEditMembership,
                                         gr => gr.AutoAcceptRequestToJoinLeave,
                                         gr => gr.AllowRequestToJoinLeave,
                                         gr => gr.Description,
                                         gr => gr.Users.Include(u => u.LoginName),
                                         gr => gr.OnlyAllowMembersViewMembership,
                                         gr => gr.Owner.LoginName,
                                         gr => gr.RequestToJoinLeaveEmailSetting
                                         ));

                    web.Context.ExecuteQueryRetry();

                    if (web.IsSubSite())
                    {
                        WriteWarning("You are requesting to export sitegroups from a subweb. Notice that ALL sitegroups from the site collection are included in the result.", ProvisioningMessageType.Warning);
                    }
                    foreach (var group in web.SiteGroups.AsEnumerable().Where(o => !associatedGroupIds.Contains(o.Id)))
                    {
                        try
                        {
                            scope.LogDebug("Processing group {0}", group.Title);
                            var siteGroup = new SiteGroup()
                            {
                                Title = !string.IsNullOrEmpty(web.Title) ? group.Title.Replace(web.Title, "{sitename}") : group.Title,
                                AllowMembersEditMembership   = group.AllowMembersEditMembership,
                                AutoAcceptRequestToJoinLeave = group.AutoAcceptRequestToJoinLeave,
                                AllowRequestToJoinLeave      = group.AllowRequestToJoinLeave,
                                Description = group.Description,
                                OnlyAllowMembersViewMembership = group.OnlyAllowMembersViewMembership,
                                Owner = ReplaceGroupTokens(web, group.Owner.LoginName),
                                RequestToJoinLeaveEmailSetting = group.RequestToJoinLeaveEmailSetting
                            };

                            foreach (var member in group.Users)
                            {
                                scope.LogDebug("Processing member {0} of group {0}", member.LoginName, group.Title);
                                siteGroup.Members.Add(new User()
                                {
                                    Name = member.LoginName
                                });
                            }
                            siteSecurity.SiteGroups.Add(siteGroup);
                        }
                        catch (Exception ee)
                        {
                            scope.LogError(ee.StackTrace);
                            scope.LogError(ee.Message);
                            scope.LogError(ee.InnerException.StackTrace);
                        }
                    }
                }

                var webRoleDefinitions = web.Context.LoadQuery(web.RoleDefinitions.Include(r => r.Name, r => r.Description, r => r.BasePermissions, r => r.RoleTypeKind));
                web.Context.ExecuteQueryRetry();

                if (web.HasUniqueRoleAssignments)
                {
                    var permissionKeys = Enum.GetNames(typeof(PermissionKind));
                    if (!web.IsSubSite())
                    {
                        foreach (var webRoleDefinition in webRoleDefinitions)
                        {
                            if (webRoleDefinition.RoleTypeKind == RoleType.None)
                            {
                                scope.LogDebug("Processing custom role definition {0}", webRoleDefinition.Name);
                                var modelRoleDefinitions = new Model.RoleDefinition();

                                modelRoleDefinitions.Description = webRoleDefinition.Description;
                                modelRoleDefinitions.Name        = webRoleDefinition.Name;

                                foreach (var permissionKey in permissionKeys)
                                {
                                    scope.LogDebug("Processing custom permissionKey definition {0}", permissionKey);
                                    var permissionKind =
                                        (PermissionKind)Enum.Parse(typeof(PermissionKind), permissionKey);
                                    if (webRoleDefinition.BasePermissions.Has(permissionKind))
                                    {
                                        modelRoleDefinitions.Permissions.Add(permissionKind);
                                    }
                                }
                                siteSecurity.SiteSecurityPermissions.RoleDefinitions.Add(modelRoleDefinitions);
                            }
                            else
                            {
                                scope.LogDebug("Skipping OOTB role definition {0}", webRoleDefinition.Name);
                            }
                        }
                    }
                    var webRoleAssignments = web.Context.LoadQuery(web.RoleAssignments.Include(
                                                                       r => r.RoleDefinitionBindings.Include(
                                                                           rd => rd.Name,
                                                                           rd => rd.RoleTypeKind),
                                                                       r => r.Member.LoginName,
                                                                       r => r.Member.PrincipalType));

                    web.Context.ExecuteQueryRetry();

                    foreach (var webRoleAssignment in webRoleAssignments)
                    {
                        scope.LogDebug("Processing Role Assignment {0}", webRoleAssignment.ToString());
                        if (webRoleAssignment.Member.PrincipalType == PrincipalType.SharePointGroup &&
                            !creationInfo.IncludeSiteGroups)
                        {
                            continue;
                        }

                        if (webRoleAssignment.Member.LoginName != "Excel Services Viewers")
                        {
                            foreach (var roleDefinition in webRoleAssignment.RoleDefinitionBindings)
                            {
                                if (roleDefinition.RoleTypeKind != RoleType.Guest)
                                {
                                    var modelRoleAssignment = new Model.RoleAssignment();
                                    var roleDefinitionValue = roleDefinition.Name;
                                    if (roleDefinition.RoleTypeKind != RoleType.None)
                                    {
                                        // Replace with token
                                        roleDefinitionValue = $"{{roledefinition:{roleDefinition.RoleTypeKind}}}";
                                    }
                                    modelRoleAssignment.RoleDefinition = roleDefinitionValue;
                                    if (webRoleAssignment.Member.PrincipalType == PrincipalType.SharePointGroup)
                                    {
                                        modelRoleAssignment.Principal = ReplaceGroupTokens(web, webRoleAssignment.Member.LoginName);
                                    }
                                    else
                                    {
                                        modelRoleAssignment.Principal = webRoleAssignment.Member.LoginName;
                                    }
                                    siteSecurity.SiteSecurityPermissions.RoleAssignments.Add(modelRoleAssignment);
                                }
                            }
                        }
                    }
                }

                template.Security = siteSecurity;

                // If a base template is specified then use that one to "cleanup" the generated template model
                if (creationInfo.BaseTemplate != null)
                {
                    template = CleanupEntities(template, creationInfo.BaseTemplate);
                }
            }
            return(template);
        }
        public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                if (template.Lists.Any())
                {
                    var rootWeb = (web.Context as ClientContext).Site.RootWeb;

                    web.EnsureProperties(w => w.ServerRelativeUrl);

                    web.Context.Load(web.Lists, lc => lc.IncludeWithDefaultProperties(l => l.RootFolder.ServerRelativeUrl));
                    web.Context.ExecuteQueryRetry();
                    var existingLists = web.Lists.AsEnumerable().Select(existingList => existingList.RootFolder.ServerRelativeUrl).ToList();
                    var serverRelativeUrl = web.ServerRelativeUrl;

                    var processedLists = new List<ListInfo>();

                    #region Lists

                    foreach (var templateList in template.Lists)
                    {
                        // Check for the presence of the references content types and throw an exception if not present or in template
                        if (templateList.ContentTypesEnabled)
                        {
                            var existingCts = web.Context.LoadQuery(web.AvailableContentTypes);
                            web.Context.ExecuteQueryRetry();
                            foreach (var ct in templateList.ContentTypeBindings)
                            {
                                var found = template.ContentTypes.Any(t => t.Id.ToUpperInvariant() == ct.ContentTypeId.ToUpperInvariant());
                                if (found == false)
                                {
                                    found = existingCts.Any(t => t.StringId.ToUpperInvariant() == ct.ContentTypeId.ToUpperInvariant());
                                }
                                if (!found)
                                {
                                    scope.LogError("Referenced content type {0} not available in site or in template", ct.ContentTypeId);
                                    throw new Exception(string.Format("Referenced content type {0} not available in site or in template", ct.ContentTypeId));
                                }
                            }
                        }
                        var index = existingLists.FindIndex(x => x.Equals(UrlUtility.Combine(serverRelativeUrl, templateList.Url), StringComparison.OrdinalIgnoreCase));
                        if (index == -1)
                        {
                            try
                            {
                                scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Creating_list__0_, templateList.Title);
                                var returnTuple = CreateList(web, templateList, parser, scope);
                                var createdList = returnTuple.Item1;
                                parser = returnTuple.Item2;
                                processedLists.Add(new ListInfo { SiteList = createdList, TemplateList = templateList });

                                parser.AddToken(new ListIdToken(web, templateList.Title, createdList.Id));

                                parser.AddToken(new ListUrlToken(web, templateList.Title, createdList.RootFolder.ServerRelativeUrl.Substring(web.ServerRelativeUrl.Length + 1)));
                            }
                            catch (Exception ex)
                            {
                                scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Creating_list__0__failed___1_____2_, templateList.Title, ex.Message, ex.StackTrace);
                                throw;
                            }
                        }
                        else
                        {
                            try
                            {
                                scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Updating_list__0_, templateList.Title);
                                var existingList = web.Lists[index];
                                var returnTuple = UpdateList(web, existingList, templateList, parser, scope);
                                var updatedList = returnTuple.Item1;
                                parser = returnTuple.Item2;
                                if (updatedList != null)
                                {
                                    processedLists.Add(new ListInfo { SiteList = updatedList, TemplateList = templateList });
                                }
                            }
                            catch (Exception ex)
                            {
                                scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Updating_list__0__failed___1_____2_, templateList.Title, ex.Message, ex.StackTrace);
                                throw;
                            }
                        }
                    }

                    #endregion

                    #region FieldRefs

                    foreach (var listInfo in processedLists)
                    {

                        if (listInfo.TemplateList.FieldRefs.Any())
                        {

                            foreach (var fieldRef in listInfo.TemplateList.FieldRefs)
                            {
                                var field = rootWeb.GetFieldById<Field>(fieldRef.Id);
                                if (field != null)
                                {
                                    if (!listInfo.SiteList.FieldExistsById(fieldRef.Id))
                                    {
                                        CreateFieldRef(listInfo, field, fieldRef);
                                    }
                                    else
                                    {
                                        UpdateFieldRef(listInfo.SiteList, field.Id, fieldRef);
                                    }
                                }

                            }
                            listInfo.SiteList.Update();
                            web.Context.ExecuteQueryRetry();
                        }
                    }

                    #endregion

                    #region Fields

                    foreach (var listInfo in processedLists)
                    {
                        if (listInfo.TemplateList.Fields.Any())
                        {
                            foreach (var field in listInfo.TemplateList.Fields)
                            {
                                var fieldElement = XElement.Parse(parser.ParseString(field.SchemaXml, "~sitecollection", "~site"));
                                if (fieldElement.Attribute("ID") == null)
                                {
                                    scope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstances_Field_schema_has_no_ID_attribute___0_, field.SchemaXml);
                                    throw new Exception(string.Format(CoreResources.Provisioning_ObjectHandlers_ListInstances_Field_schema_has_no_ID_attribute___0_, field.SchemaXml));
                                }
                                var id = fieldElement.Attribute("ID").Value;

                                Guid fieldGuid;
                                if (!Guid.TryParse(id, out fieldGuid))
                                {
                                    scope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstances_ID_for_field_is_not_a_valid_Guid___0_, field.SchemaXml);
                                    throw new Exception(string.Format(CoreResources.Provisioning_ObjectHandlers_ListInstances_ID_for_field_is_not_a_valid_Guid___0_, id));
                                }
                                else
                                {
                                    var fieldFromList = listInfo.SiteList.GetFieldById<Field>(fieldGuid);
                                    if (fieldFromList == null)
                                    {
                                        try
                                        {
                                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Creating_field__0_, fieldGuid);
                                            CreateField(fieldElement, listInfo, parser);
                                        }
                                        catch (Exception ex)
                                        {
                                            scope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstances_Creating_field__0__failed___1_____2_, fieldGuid, ex.Message, ex.StackTrace);
                                            throw;
                                        }
                                    }
                                    else
                                    {
                                        try
                                        {
                                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Updating_field__0_, fieldGuid);
                                            UpdateField(web, listInfo, fieldGuid, fieldElement, fieldFromList, scope, parser);
                                        }
                                        catch (Exception ex)
                                        {
                                            scope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstances_Updating_field__0__failed___1_____2_, fieldGuid, ex.Message, ex.StackTrace);
                                            throw;
                                        }

                                    }
                                }
                            }
                        }
                        listInfo.SiteList.Update();
                        web.Context.ExecuteQueryRetry();
                    }

                    #endregion

                    #region Default Field Values
                    foreach (var listInfo in processedLists)
                    {
                        if (listInfo.TemplateList.FieldDefaults.Any())
                        {
                            foreach (var fieldDefault in listInfo.TemplateList.FieldDefaults)
                            {
                                var field = listInfo.SiteList.Fields.GetByInternalNameOrTitle(fieldDefault.Key);
                                field.DefaultValue = fieldDefault.Value;
                                field.Update();
                                web.Context.ExecuteQueryRetry();
                            }
                        }
                    }
                    #endregion

                    #region Views

                    foreach (var listInfo in processedLists)
                    {
                        var list = listInfo.TemplateList;
                        var createdList = listInfo.SiteList;

                        if (list.Views.Any() && list.RemoveExistingViews)
                        {
                            while (createdList.Views.Any())
                            {
                                createdList.Views[0].DeleteObject();
                            }
                            web.Context.ExecuteQueryRetry();
                        }

                        var existingViews = createdList.Views;
                        web.Context.Load(existingViews, vs => vs.Include(v => v.Title, v => v.Id));
                        web.Context.ExecuteQueryRetry();
                        foreach (var view in list.Views)
                        {

                            CreateView(web, view, existingViews, createdList, scope);

                        }

                        //// Removing existing views set the OnQuickLaunch option to false and need to be re-set.
                        //if (list.OnQuickLaunch && list.RemoveExistingViews && list.Views.Count > 0)
                        //{
                        //    createdList.RefreshLoad();
                        //    web.Context.ExecuteQueryRetry();
                        //    createdList.OnQuickLaunch = list.OnQuickLaunch;
                        //    createdList.Update();
                        //    web.Context.ExecuteQueryRetry();
                        //}
                    }

                    #endregion

                    // If an existing view is updated, and the list is to be listed on the QuickLaunch, it is removed because the existing view will be deleted and recreated from scratch.
                    foreach (var listInfo in processedLists)
                    {
                        listInfo.SiteList.OnQuickLaunch = listInfo.TemplateList.OnQuickLaunch;
                        listInfo.SiteList.Update();
                    }
                    web.Context.ExecuteQueryRetry();

                }
            }
            return parser;
        }
Example #46
0
        private ProvisioningTemplate DetectComposedLook(Web web, ProvisioningTemplate template,
                                                        ProvisioningTemplateCreationInformation creationInfo,
                                                        PnPMonitoredScope scope, SharePointConnector spConnector,
                                                        SharePointConnector spConnectorRoot)
        {
            var theme = web.GetCurrentComposedLook();

            if (theme != null)
            {
                if (creationInfo != null)
                {
                    // Don't exclude the DesignPreviewThemedCssFolderUrl property bag, if any
                    creationInfo.PropertyBagPropertiesToPreserve.Add("DesignPreviewThemedCssFolderUrl");
                }

                template.ComposedLook.Name =
                    theme.Name != null ? theme.Name : String.Empty;

                if (theme.IsCustomComposedLook)
                {
                    // Set the URL pointers to files
                    template.ComposedLook.BackgroundFile = FixFileUrl(Tokenize(theme.BackgroundImage, web.Url));
                    template.ComposedLook.ColorFile      = FixFileUrl(Tokenize(theme.Theme, web.Url));
                    template.ComposedLook.FontFile       = FixFileUrl(Tokenize(theme.Font, web.Url));

                    // Download files if this is root site, since theme files are only stored there
                    if (!web.IsSubSite() && creationInfo != null &&
                        creationInfo.PersistBrandingFiles && creationInfo.FileConnector != null)
                    {
                        scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Creating_SharePointConnector);
                        // Let's create a SharePoint connector since our files anyhow are in SharePoint at this moment
                        // Download the theme/branding specific files
                        DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.BackgroundImage, scope);
                        DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.Theme, scope);
                        DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.Font, scope);
                    }

                    // Create file entries for the custom theme files, but only if it's a root site
                    // If it's root site we do not extract or set theme files, since those are in the root of the site collection
                    if (!web.IsSubSite())
                    {
                        if (!string.IsNullOrEmpty(template.ComposedLook.BackgroundFile))
                        {
                            template.Files.Add(GetComposedLookFile(template.ComposedLook.BackgroundFile));
                        }
                        if (!string.IsNullOrEmpty(template.ComposedLook.ColorFile))
                        {
                            template.Files.Add(GetComposedLookFile(template.ComposedLook.ColorFile));
                        }
                        if (!string.IsNullOrEmpty(template.ComposedLook.FontFile))
                        {
                            template.Files.Add(GetComposedLookFile(template.ComposedLook.FontFile));
                        }
                    }
                    // If a base template is specified then use that one to "cleanup" the generated template model
                    if (creationInfo != null && creationInfo.BaseTemplate != null)
                    {
                        template = CleanupEntities(template, creationInfo.BaseTemplate);
                    }
                }
                else
                {
                    template.ComposedLook.BackgroundFile = "";
                    template.ComposedLook.ColorFile      = "";
                    template.ComposedLook.FontFile       = "";
                }
            }
            else
            {
                template.ComposedLook = null;
            }

            return(template);
        }
        public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser,
            ProvisioningTemplateApplyingInformation applyingInformation)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                var context = web.Context as ClientContext;

                web.EnsureProperties(w => w.ServerRelativeUrl, w => w.Url);

                foreach (PublishingPage page in template.Publishing.PublishingPages)
                {
                    string parsedFileName = parser.ParseString(page.FileName);
                    string parsedFullFileName = parser.ParseString(page.FullFileName);

                    Microsoft.SharePoint.Client.Publishing.PublishingPage existingPage =
                        web.GetPublishingPage(parsedFileName + ".aspx");

                    if (!web.IsPropertyAvailable("RootFolder"))
                    {
                        web.Context.Load(web.RootFolder);
                        web.Context.ExecuteQueryRetry();
                    }

                    if (existingPage != null && existingPage.ServerObjectIsNull.Value == false)
                    {
                        if (!page.Overwrite)
                        {
                            scope.LogDebug(
                                CoreResources.Provisioning_ObjectHandlers_PublishingPages_Skipping_As_Overwrite_false,
                                parsedFileName);
                            continue;
                        }

                        if (page.WelcomePage && web.RootFolder.WelcomePage.Contains(parsedFullFileName))
                        {
                            //set the welcome page to a Temp page to allow page deletion
                            web.RootFolder.WelcomePage = "home.aspx";
                            web.RootFolder.Update();
                            web.Update();
                            context.ExecuteQueryRetry();
                        }
                        existingPage.ListItem.DeleteObject();
                        context.ExecuteQuery();
                    }

                    web.AddPublishingPage(
                        parsedFileName,
                        page.Layout,
                        parser.ParseString(page.Title)
                        );
                    Microsoft.SharePoint.Client.Publishing.PublishingPage publishingPage =
                        web.GetPublishingPage(parsedFullFileName);
                    Microsoft.SharePoint.Client.File pageFile = publishingPage.ListItem.File;
                    pageFile.CheckOut();

                    if (page.Properties != null && page.Properties.Count > 0)
                    {
                        context.Load(pageFile, p => p.Name, p => p.CheckOutType);
                        context.ExecuteQueryRetry();
                        var parsedProperties = page.Properties.ToDictionary(p => p.Key, p => parser.ParseString(p.Value));
                        pageFile.SetFileProperties(parsedProperties, false);
                    }

                    if (page.WebParts != null && page.WebParts.Count > 0)
                    {
                        Microsoft.SharePoint.Client.WebParts.LimitedWebPartManager mgr =
                            pageFile.GetLimitedWebPartManager(
                                Microsoft.SharePoint.Client.WebParts.PersonalizationScope.Shared);
                        context.Load(mgr);
                        context.ExecuteQueryRetry();

                        AddWebPartsToPublishingPage(page, context, mgr, parser);
                    }

                    List pagesLibrary = publishingPage.ListItem.ParentList;
                    context.Load(pagesLibrary);
                    context.ExecuteQueryRetry();

                    ListItem pageItem = publishingPage.ListItem;
                    web.Context.Load(pageItem, p => p.File.CheckOutType);
                    web.Context.ExecuteQueryRetry();

                    if (pageItem.File.CheckOutType != CheckOutType.None)
                    {
                        pageItem.File.CheckIn(String.Empty, CheckinType.MajorCheckIn);
                    }

                    if (page.Publish && pagesLibrary.EnableMinorVersions)
                    {
                        pageItem.File.Publish(String.Empty);
                        if (pagesLibrary.EnableModeration)
                        {
                            pageItem.File.Approve(String.Empty);
                        }
                    }

                    if (page.WelcomePage)
                    {
                        SetWelcomePage(web, pageFile);
                    }

                    context.ExecuteQueryRetry();
                }
            }
            return parser;
        }
Example #48
0
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                scope.LogInfo(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Retrieving_current_composed_look);

                // Ensure that we have URL property loaded for web and site
                web.EnsureProperty(w => w.Url);
                Site site = (web.Context as ClientContext).Site;
                site.EnsureProperty(s => s.Url);

                SharePointConnector spConnector = new SharePointConnector(web.Context, web.Url, "dummy");
                // to get files from theme catalog we need a connector linked to the root site
                SharePointConnector spConnectorRoot;
                if (!site.Url.Equals(web.Url, StringComparison.InvariantCultureIgnoreCase))
                {
                    spConnectorRoot = new SharePointConnector(web.Context.Clone(site.Url), site.Url, "dummy");
                }
                else
                {
                    spConnectorRoot = spConnector;
                }

                // Check if we have composed look info in the property bag, if so, use that, otherwise try to detect the current composed look
                if (web.PropertyBagContainsKey("_PnP_ProvisioningTemplateComposedLookInfo"))
                {
                    scope.LogInfo(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Using_ComposedLookInfoFromPropertyBag);

                    try
                    {
                        var composedLook = JsonConvert.DeserializeObject <ComposedLook>(web.GetPropertyBagValueString("_PnP_ProvisioningTemplateComposedLookInfo", ""));
                        if (composedLook.Name == null)
                        {
                            scope.LogError(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_ComposedLookInfoFailedToDeserialize);
                            throw new JsonSerializationException();
                        }

                        composedLook.BackgroundFile = Tokenize(composedLook.BackgroundFile, web.Url);
                        composedLook.FontFile       = Tokenize(composedLook.FontFile, web.Url);
                        composedLook.ColorFile      = Tokenize(composedLook.ColorFile, web.Url);
                        template.ComposedLook       = composedLook;

                        if (!web.IsSubSite() && creationInfo != null &&
                            creationInfo.PersistBrandingFiles && creationInfo.FileConnector != null)
                        {
                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Creating_SharePointConnector);
                            // Let's create a SharePoint connector since our files anyhow are in SharePoint at this moment
                            TokenParser parser = new TokenParser(web, template);
                            DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, parser.ParseString(composedLook.BackgroundFile), scope);
                            DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, parser.ParseString(composedLook.ColorFile), scope);
                            DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, parser.ParseString(composedLook.FontFile), scope);
                        }
                        // Create file entries for the custom theme files
                        if (!string.IsNullOrEmpty(template.ComposedLook.BackgroundFile))
                        {
                            var f = GetComposedLookFile(template.ComposedLook.BackgroundFile);
                            f.Folder = Tokenize(f.Folder, web.Url);
                            template.Files.Add(f);
                        }
                        if (!string.IsNullOrEmpty(template.ComposedLook.ColorFile))
                        {
                            var f = GetComposedLookFile(template.ComposedLook.ColorFile);
                            f.Folder = Tokenize(f.Folder, web.Url);
                            template.Files.Add(f);
                        }
                        if (!string.IsNullOrEmpty(template.ComposedLook.FontFile))
                        {
                            var f = GetComposedLookFile(template.ComposedLook.FontFile);
                            f.Folder = Tokenize(f.Folder, web.Url);
                            template.Files.Add(f);
                        }
                    }
                    catch (JsonSerializationException)
                    {
                        // cannot deserialize the object, fall back to composed look detection
                        template = DetectComposedLook(web, template, creationInfo, scope, spConnector, spConnectorRoot);
                    }
                }
                else
                {
                    template = DetectComposedLook(web, template, creationInfo, scope, spConnector, spConnectorRoot);
                }

                if (creationInfo != null && creationInfo.BaseTemplate != null)
                {
                    template = CleanupEntities(template, creationInfo.BaseTemplate);
                }
            }
            return(template);
        }
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                // if this is a sub site then we're not creating security entities as by default security is inherited from the root site
                if (web.IsSubSite())
                {
                    return template;
                }

                web.Context.Load(web, w => w.HasUniqueRoleAssignments, w => w.Title);

                var ownerGroup = web.AssociatedOwnerGroup;
                var memberGroup = web.AssociatedMemberGroup;
                var visitorGroup = web.AssociatedVisitorGroup;
                web.Context.ExecuteQueryRetry();

                if (!ownerGroup.ServerObjectIsNull.Value)
                {
                    web.Context.Load(ownerGroup, o => o.Id, o => o.Users, o => o.Title);
                }
                if (!memberGroup.ServerObjectIsNull.Value)
                {
                    web.Context.Load(memberGroup, o => o.Id, o => o.Users, o => o.Title);
                }
                if (!visitorGroup.ServerObjectIsNull.Value)
                {
                    web.Context.Load(visitorGroup, o => o.Id, o => o.Users, o => o.Title);
                }
                web.Context.ExecuteQueryRetry();

                List<int> associatedGroupIds = new List<int>();
                var owners = new List<User>();
                var members = new List<User>();
                var visitors = new List<User>();
                if (!ownerGroup.ServerObjectIsNull.Value)
                {
                    associatedGroupIds.Add(ownerGroup.Id);
                    foreach (var member in ownerGroup.Users)
                    {
                        owners.Add(new User() { Name = member.LoginName });
                    }
                }
                if (!memberGroup.ServerObjectIsNull.Value)
                {
                    associatedGroupIds.Add(memberGroup.Id);
                    foreach (var member in memberGroup.Users)
                    {
                        members.Add(new User() { Name = member.LoginName });
                    }
                }
                if (!visitorGroup.ServerObjectIsNull.Value)
                {
                    associatedGroupIds.Add(visitorGroup.Id);
                    foreach (var member in visitorGroup.Users)
                    {
                        visitors.Add(new User() { Name = member.LoginName });
                    }
                }
                var siteSecurity = new SiteSecurity();
                siteSecurity.AdditionalOwners.AddRange(owners);
                siteSecurity.AdditionalMembers.AddRange(members);
                siteSecurity.AdditionalVisitors.AddRange(visitors);

                var query = from user in web.SiteUsers
                            where user.IsSiteAdmin
                            select user;
                var allUsers = web.Context.LoadQuery(query);

                web.Context.ExecuteQueryRetry();

                var admins = new List<User>();
                foreach (var member in allUsers)
                {
                    admins.Add(new User() { Name = member.LoginName });
                }
                siteSecurity.AdditionalAdministrators.AddRange(admins);

                if (creationInfo.IncludeSiteGroups)
                {
                    web.Context.Load(web.SiteGroups,
                        o => o.IncludeWithDefaultProperties(
                            gr => gr.Title,
                            gr => gr.AllowMembersEditMembership,
                            gr => gr.AutoAcceptRequestToJoinLeave,
                            gr => gr.AllowRequestToJoinLeave,
                            gr => gr.Description,
                            gr => gr.Users.Include(u => u.LoginName),
                            gr => gr.OnlyAllowMembersViewMembership,
                            gr => gr.Owner.LoginName,
                            gr => gr.RequestToJoinLeaveEmailSetting
                            ));

                    web.Context.ExecuteQueryRetry();

                    foreach (var group in web.SiteGroups.AsEnumerable().Where(o => !associatedGroupIds.Contains(o.Id)))
                    {
                        scope.LogDebug("Processing group {0}", group.Title);
                        var siteGroup = new SiteGroup()
                        {
                            Title = group.Title.Replace(web.Title, "{sitename}"),
                            AllowMembersEditMembership = group.AllowMembersEditMembership,
                            AutoAcceptRequestToJoinLeave = group.AutoAcceptRequestToJoinLeave,
                            AllowRequestToJoinLeave = group.AllowRequestToJoinLeave,
                            Description = group.Description,
                            OnlyAllowMembersViewMembership = group.OnlyAllowMembersViewMembership,
                            Owner = ReplaceGroupTokens(web, group.Owner.LoginName),
                            RequestToJoinLeaveEmailSetting = group.RequestToJoinLeaveEmailSetting
                        };

                        foreach (var member in group.Users)
                        {
                            siteGroup.Members.Add(new User() { Name = member.LoginName });
                        }
                        siteSecurity.SiteGroups.Add(siteGroup);
                    }
                }

                var webRoleDefinitions = web.Context.LoadQuery(web.RoleDefinitions.Include(r => r.Name, r => r.Description, r => r.BasePermissions, r => r.RoleTypeKind));
                web.Context.ExecuteQueryRetry();

                if (web.HasUniqueRoleAssignments)
                {
                    var permissionKeys = Enum.GetNames(typeof(PermissionKind));

                    foreach (var webRoleDefinition in webRoleDefinitions)
                    {
                        if (webRoleDefinition.RoleTypeKind == RoleType.None)
                        {
                            scope.LogDebug("Processing custom role definition {0}", webRoleDefinition.Name);
                            var modelRoleDefinitions = new Model.RoleDefinition();

                            modelRoleDefinitions.Description = webRoleDefinition.Description;
                            modelRoleDefinitions.Name = webRoleDefinition.Name;
                            var permissions = new List<PermissionKind>();

                            foreach (var permissionKey in permissionKeys)
                            {
                                var permissionKind = (PermissionKind)Enum.Parse(typeof(PermissionKind), permissionKey);
                                if (webRoleDefinition.BasePermissions.Has(permissionKind))
                                {
                                    modelRoleDefinitions.Permissions.Add(permissionKind);
                                }
                            }
                            siteSecurity.SiteSecurityPermissions.RoleDefinitions.Add(modelRoleDefinitions);
                        }
                        else
                        {
                            scope.LogDebug("Skipping OOTB role definition {0}", webRoleDefinition.Name);
                        }
                    }

                    var webRoleAssignments = web.Context.LoadQuery(web.RoleAssignments.Include(
                        r => r.RoleDefinitionBindings.Include(
                            rd => rd.Name,
                            rd => rd.RoleTypeKind),
                        r => r.Member.LoginName));

                    web.Context.ExecuteQueryRetry();

                    foreach (var webRoleAssignment in webRoleAssignments)
                    {
                        if (webRoleAssignment.Member.LoginName != "Excel Services Viewers")
                        {
                            foreach (var roleDefinition in webRoleAssignment.RoleDefinitionBindings)
                            {
                                if (roleDefinition.RoleTypeKind != RoleType.Guest)
                                {
                                    var modelRoleAssignment = new Model.RoleAssignment();
                                    modelRoleAssignment.RoleDefinition = roleDefinition.Name;
                                    modelRoleAssignment.Principal = ReplaceGroupTokens(web, webRoleAssignment.Member.LoginName);
                                    siteSecurity.SiteSecurityPermissions.RoleAssignments.Add(modelRoleAssignment);
                                }
                            }
                        }
                    }

                    template.Security = siteSecurity;
                }
                // If a base template is specified then use that one to "cleanup" the generated template model
                if (creationInfo.BaseTemplate != null)
                {
                    template = CleanupEntities(template, creationInfo.BaseTemplate);

                }
            }
            return template;
        }
        public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                if (!template.Lists.Any())
                {
                    return(parser);
                }

                web.EnsureProperties(w => w.ServerRelativeUrl);

                web.Context.Load(web.Lists, lc => lc.IncludeWithDefaultProperties(l => l.RootFolder.ServerRelativeUrl));
                web.Context.ExecuteQueryRetry();

                #region DataRows

                foreach (var listInstance in template.Lists)
                {
                    if (listInstance.DataRows != null && listInstance.DataRows.Any())
                    {
                        scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Processing_data_rows_for__0_, listInstance.Title);
                        // Retrieve the target list
                        var list = web.Lists.GetByTitle(parser.ParseString(listInstance.Title));
                        web.Context.Load(list);

                        // Retrieve the fields' types from the list
                        Microsoft.SharePoint.Client.FieldCollection fields = list.Fields;
                        web.Context.Load(fields, fs => fs.Include(f => f.InternalName, f => f.FieldTypeKind, f => f.TypeAsString, f => f.ReadOnlyField, f => f.Title));
                        web.Context.ExecuteQueryRetry();

                        var keyColumnType   = "Text";
                        var parsedKeyColumn = parser.ParseString(listInstance.DataRows.KeyColumn);
                        if (!string.IsNullOrEmpty(parsedKeyColumn))
                        {
                            var keyColumn = fields.FirstOrDefault(f => f.InternalName.Equals(parsedKeyColumn, StringComparison.InvariantCultureIgnoreCase));
                            if (keyColumn != null)
                            {
                                switch (keyColumn.FieldTypeKind)
                                {
                                case FieldType.User:
                                case FieldType.Lookup:
                                    keyColumnType = "Lookup";
                                    break;

                                case FieldType.URL:
                                    keyColumnType = "Url";
                                    break;

                                case FieldType.DateTime:
                                    keyColumnType = "DateTime";
                                    break;

                                case FieldType.Number:
                                case FieldType.Counter:
                                    keyColumnType = "Number";
                                    break;
                                }
                            }
                        }

                        foreach (var dataRow in listInstance.DataRows)
                        {
                            try
                            {
                                scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Creating_list_item__0_, listInstance.DataRows.IndexOf(dataRow) + 1);

                                bool     processItem = true;
                                ListItem listitem    = null;

                                if (!string.IsNullOrEmpty(listInstance.DataRows.KeyColumn))
                                {
                                    // Get value from key column
                                    var dataRowValues = dataRow.Values.Where(v => v.Key == listInstance.DataRows.KeyColumn).ToList();

                                    // if it is empty, skip the check
                                    if (dataRowValues.Any())
                                    {
                                        var query     = $@"<View><Query><Where><Eq><FieldRef Name=""{parsedKeyColumn}""/><Value Type=""{keyColumnType}"">{parser.ParseString(dataRowValues.FirstOrDefault().Value)}</Value></Eq></Where></Query><RowLimit>1</RowLimit></View>";
                                        var camlQuery = new CamlQuery()
                                        {
                                            ViewXml = query
                                        };
                                        var existingItems = list.GetItems(camlQuery);
                                        list.Context.Load(existingItems);
                                        list.Context.ExecuteQueryRetry();
                                        if (existingItems.Count > 0)
                                        {
                                            if (listInstance.DataRows.UpdateBehavior == UpdateBehavior.Skip)
                                            {
                                                processItem = false;
                                            }
                                            else
                                            {
                                                listitem    = existingItems[0];
                                                processItem = true;
                                            }
                                        }
                                    }
                                }

                                if (processItem)
                                {
                                    bool IsNewItem = false;
                                    if (listitem == null)
                                    {
                                        var listitemCI = new ListItemCreationInformation();
                                        listitem  = list.AddItem(listitemCI);
                                        IsNewItem = true;
                                    }

                                    ListItemUtilities.UpdateListItem(listitem, parser, dataRow.Values, ListItemUtilities.ListItemUpdateType.UpdateOverwriteVersion, IsNewItem);

                                    if (dataRow.Security != null && (dataRow.Security.ClearSubscopes || dataRow.Security.CopyRoleAssignments || dataRow.Security.RoleAssignments.Count > 0))
                                    {
                                        listitem.SetSecurity(parser, dataRow.Security);
                                    }

                                    if (dataRow.Attachments != null && dataRow.Attachments.Count > 0)
                                    {
                                        foreach (var attachment in dataRow.Attachments)
                                        {
                                            attachment.Name = parser.ParseString(attachment.Name);
                                            attachment.Src  = parser.ParseString(attachment.Src);
                                            if (!IsNewItem)
                                            {
                                                var overwrite = attachment.Overwrite;
                                                listitem.EnsureProperty(l => l.AttachmentFiles);

                                                Attachment existingItem = null;
                                                if (listitem.AttachmentFiles.Count > 0)
                                                {
                                                    existingItem = listitem.AttachmentFiles.FirstOrDefault(a => a.FileName.Equals(attachment.Name, StringComparison.OrdinalIgnoreCase));
                                                }
                                                if (existingItem != null)
                                                {
                                                    if (overwrite)
                                                    {
                                                        existingItem.DeleteObject();
                                                        web.Context.ExecuteQueryRetry();
                                                        AddAttachment(template, listitem, attachment);
                                                    }
                                                }
                                                else
                                                {
                                                    AddAttachment(template, listitem, attachment);
                                                }
                                            }
                                            else
                                            {
                                                AddAttachment(template, listitem, attachment, IsNewItem);
                                            }
                                        }
                                        if (IsNewItem)
                                        {
                                            listitem.Context.ExecuteQueryRetry();
                                        }
                                    }
                                }
                            }
                            catch (ServerException ex)
                            {
                                if (ex.ServerErrorTypeName.Equals("Microsoft.SharePoint.SPDuplicateValuesFoundException", StringComparison.InvariantCultureIgnoreCase) &&
                                    applyingInformation.IgnoreDuplicateDataRowErrors)
                                {
                                    scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Creating_listitem_duplicate);
                                    continue;
                                }
                                if (ex.ServerErrorTypeName.Equals("Microsoft.SharePoint.SPException", StringComparison.InvariantCultureIgnoreCase) &&
                                    ex.Message.Equals("To add an item to a document library, use SPFileCollection.Add()", StringComparison.InvariantCultureIgnoreCase))
                                {
                                    // somebody tries to add new items to a document library
                                    var warning = string.Format(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Creating_listitem_notsupported_0, listInstance.Title);
                                    scope.LogWarning(warning);
                                    WriteMessage(warning, ProvisioningMessageType.Warning);
                                    continue;
                                }
                            }
                            catch (Exception ex)
                            {
                                scope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Creating_listitem_failed___0_____1_, ex.Message, ex.StackTrace);
                                throw;
                            }
                        }
                    }
                }


                #endregion DataRows
            }


            return(parser);
        }
        public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                var site = (web.Context as ClientContext).Site;

                var webFeatureActive = web.IsFeatureActive(PUBLISHING_FEATURE_WEB);
                var siteFeatureActive = site.IsFeatureActive(PUBLISHING_FEATURE_SITE);
                if (template.Publishing.AutoCheckRequirements == AutoCheckRequirementsOptions.SkipIfNotCompliant && !webFeatureActive)
                {
                    scope.LogDebug("Publishing Feature (Web Scoped) not active. Skipping provisioning of Publishing settings");
                    return parser;
                }
                else if (template.Publishing.AutoCheckRequirements == AutoCheckRequirementsOptions.MakeCompliant)
                {
                    if (!siteFeatureActive)
                    {
                        scope.LogDebug("Making site compliant for publishing");
                        site.ActivateFeature(PUBLISHING_FEATURE_SITE);
                        web.ActivateFeature(PUBLISHING_FEATURE_WEB);
                    }
                    else
                    {
                        if (!web.IsFeatureActive(PUBLISHING_FEATURE_WEB))
                        {
                            scope.LogDebug("Making site compliant for publishing");
                            web.ActivateFeature(PUBLISHING_FEATURE_WEB);
                        }
                    }
                }
                else
                {
                    throw new Exception("Publishing Feature not active. Provisioning failed");
                }

                // Set allowed web templates
                var availableWebTemplates = template.Publishing.AvailableWebTemplates.Select(t => new WebTemplateEntity() { LanguageCode = t.LanguageCode.ToString(), TemplateName = t.TemplateName }).ToList();
                if (availableWebTemplates.Any())
                {
                    web.SetAvailableWebTemplates(availableWebTemplates);
                }

                // Set allowed page layouts
                var availablePageLayouts = template.Publishing.PageLayouts.Select(p => p.Path);
                if (availablePageLayouts.Any())
                {
                    web.SetAvailablePageLayouts(site.RootWeb, availablePageLayouts);
                }

                // Set default page layout, if any
                var defaultPageLayout = template.Publishing.PageLayouts.FirstOrDefault(p => p.IsDefault);
                if (defaultPageLayout != null)
                {
                    web.SetDefaultPageLayoutForSite(site.RootWeb, defaultPageLayout.Path);
                }

                if (template.Publishing.DesignPackage != null)
                {
                    var package = template.Publishing.DesignPackage;

                    var tempFileName = Path.Combine(Path.GetTempPath(), template.Connector.GetFilenamePart(package.DesignPackagePath));
                    scope.LogDebug("Saving {0} to temporary file: {1}", package.DesignPackagePath, tempFileName);
                    using (var stream = template.Connector.GetFileStream(package.DesignPackagePath))
                    {
                        using (var outstream = System.IO.File.Create(tempFileName))
                        {
                            stream.CopyTo(outstream);
                        }
                    }
                    scope.LogDebug("Installing design package");
                    site.InstallSolution(package.PackageGuid, tempFileName, package.MajorVersion, package.MinorVersion);
                    System.IO.File.Delete(tempFileName);
                }
                return parser;
            }
        }
        public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                // Check if this is not a noscript site as we're not allowed to write to the web property bag is that one
                bool isNoScriptSite = web.IsNoScriptSite();
                web.EnsureProperties(w => w.ServerRelativeUrl, w => w.Url);

                // Build on the fly the list of additional files coming from the Directories
                var directoryFiles = new List <Model.File>();
                foreach (var directory in template.Directories)
                {
                    var metadataProperties = directory.GetMetadataProperties();
                    directoryFiles.AddRange(directory.GetDirectoryFiles(metadataProperties));
                }

                var filesToProcess = template.Files.Union(directoryFiles).ToArray();

                var siteAssetsFiles = filesToProcess.Where(f => f.Folder.ToLower().Contains("siteassets")).FirstOrDefault();
                if (siteAssetsFiles != null)
                {
                    // Need this so that we dont have access denied error during the first time upload, especially for modern sites
                    web.Lists.EnsureSiteAssetsLibrary();
                    web.Context.ExecuteQueryRetry();
                }

                var currentFileIndex = 0;
                var originalWeb      = web; // Used to store and re-store context in case files are deployed to masterpage gallery
                foreach (var file in filesToProcess)
                {
                    file.Src = parser.ParseString(file.Src);
                    var targetFileName = parser.ParseString(
                        !String.IsNullOrEmpty(file.TargetFileName) ? file.TargetFileName : template.Connector.GetFilenamePart(file.Src)
                        );

                    currentFileIndex++;
                    WriteSubProgress("File", targetFileName, currentFileIndex, filesToProcess.Length);
                    var folderName = parser.ParseString(file.Folder);

                    if (folderName.ToLower().Contains("/_catalogs/"))
                    {
                        // Edge case where you have files in the template which should be provisioned to the site collection
                        // master page gallery and not to a connected subsite
                        web = web.Context.GetSiteCollectionContext().Web;
                        web.EnsureProperties(w => w.ServerRelativeUrl, w => w.Url);
                    }

                    if (folderName.ToLower().StartsWith((web.ServerRelativeUrl.ToLower())))
                    {
                        folderName = folderName.Substring(web.ServerRelativeUrl.Length);
                    }

                    if (SkipFile(isNoScriptSite, targetFileName, folderName))
                    {
                        // add log message
                        scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_Files_SkipFileUpload, targetFileName, folderName);
                        continue;
                    }

                    var folder = web.EnsureFolderPath(folderName);

                    var checkedOut = false;

                    var targetFile = folder.GetFile(template.Connector.GetFilenamePart(targetFileName));

                    if (targetFile != null)
                    {
                        if (file.Overwrite)
                        {
                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Files_Uploading_and_overwriting_existing_file__0_, targetFileName);
                            checkedOut = CheckOutIfNeeded(web, targetFile);

                            using (var stream = FileUtilities.GetFileStream(template, file))
                            {
                                targetFile = UploadFile(folder, stream, targetFileName, file.Overwrite);
                            }
                        }
                        else
                        {
                            checkedOut = CheckOutIfNeeded(web, targetFile);
                        }
                    }
                    else
                    {
                        using (var stream = FileUtilities.GetFileStream(template, file))
                        {
                            if (stream == null)
                            {
                                throw new FileNotFoundException($"File {file.Src} does not exist");
                            }
                            else
                            {
                                scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Files_Uploading_file__0_, targetFileName);
                                targetFile = UploadFile(folder, stream, targetFileName, file.Overwrite);
                            }
                        }

                        checkedOut = CheckOutIfNeeded(web, targetFile);
                    }

                    if (targetFile != null)
                    {
                        // Add the fileuniqueid tokens
                        targetFile.EnsureProperties(p => p.UniqueId, p => p.ServerRelativeUrl);
                        parser.AddToken(new FileUniqueIdToken(web, targetFile.ServerRelativeUrl.Substring(web.ServerRelativeUrl.Length).TrimStart("/".ToCharArray()), targetFile.UniqueId));
                        parser.AddToken(new FileUniqueIdEncodedToken(web, targetFile.ServerRelativeUrl.Substring(web.ServerRelativeUrl.Length).TrimStart("/".ToCharArray()), targetFile.UniqueId));

                        bool webPartsNeedLocalization = false;
                        if (file.WebParts != null && file.WebParts.Any())
                        {
                            targetFile.EnsureProperties(f => f.ServerRelativeUrl);

                            var existingWebParts = web.GetWebParts(targetFile.ServerRelativeUrl).ToList();
                            foreach (var webPart in file.WebParts)
                            {
                                // check if the webpart is already set on the page
                                if (existingWebParts.FirstOrDefault(w => w.WebPart.Title == parser.ParseString(webPart.Title)) == null)
                                {
                                    scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Files_Adding_webpart___0___to_page, webPart.Title);
                                    var wpEntity = new WebPartEntity
                                    {
                                        WebPartTitle = parser.ParseString(webPart.Title),
                                        WebPartXml   = parser.ParseXmlString(webPart.Contents).Trim(new[] { '\n', ' ' }),
                                        WebPartZone  = webPart.Zone,
                                        WebPartIndex = (int)webPart.Order
                                    };
                                    var wpd = web.AddWebPartToWebPartPage(targetFile.ServerRelativeUrl, wpEntity);
                                    if (webPart.Title.ContainsResourceToken())
                                    {
                                        // update data based on where it was added - needed in order to localize wp title
                                        wpd.EnsureProperties(w => w.ZoneId, w => w.WebPart, w => w.WebPart.Properties);
                                        webPart.Zone             = wpd.ZoneId;
                                        webPart.Order            = (uint)wpd.WebPart.ZoneIndex;
                                        webPartsNeedLocalization = true;
                                    }
                                }
                            }
                        }

                        if (webPartsNeedLocalization)
                        {
                            file.LocalizeWebParts(web, parser, targetFile, scope);
                        }

                        //Set Properties before Checkin
                        if (file.Properties != null && file.Properties.Any())
                        {
                            Dictionary <string, string> transformedProperties = file.Properties.ToDictionary(property => property.Key, property => parser.ParseString(property.Value));
                            SetFileProperties(targetFile, transformedProperties, parser, false);
                        }

                        switch (file.Level)
                        {
                        case Model.FileLevel.Published:
                        {
                            targetFile.PublishFileToLevel(Microsoft.SharePoint.Client.FileLevel.Published);
                            break;
                        }

                        case Model.FileLevel.Draft:
                        {
                            targetFile.PublishFileToLevel(Microsoft.SharePoint.Client.FileLevel.Draft);
                            break;
                        }

                        default:
                        {
                            if (checkedOut)
                            {
                                targetFile.CheckIn("", CheckinType.MajorCheckIn);
                                web.Context.ExecuteQueryRetry();
                            }
                            break;
                        }
                        }

                        // Don't set security when nothing is defined. This otherwise breaks on files set outside of a list
                        if (file.Security != null &&
                            (file.Security.ClearSubscopes == true || file.Security.CopyRoleAssignments == true || file.Security.RoleAssignments.Count > 0))
                        {
                            targetFile.ListItemAllFields.SetSecurity(parser, file.Security, WriteMessage);
                        }
                    }

                    web = originalWeb; // restore context in case files are provisioned to the master page gallery #1059
                }
            }
            WriteMessage("Done processing files", ProvisioningMessageType.Completed);
            return(parser);
        }
Example #53
0
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                // if this is a sub site then we're not creating field entities.
                if (web.IsSubSite())
                {
                    scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Fields_Context_web_is_subweb__skipping_site_columns);
                    return template;
                }

                var existingFields = web.Fields;
                web.Context.Load(web, w => w.ServerRelativeUrl);
                web.Context.Load(existingFields, fs => fs.Include(f => f.Id, f => f.SchemaXml, f => f.TypeAsString));
                web.Context.ExecuteQueryRetry();

                var taxTextFieldsToRemove = new List<Guid>();

                foreach (var field in existingFields)
                {
                    if (!BuiltInFieldId.Contains(field.Id))
                    {
                        var fieldXml = field.SchemaXml;
                        XElement element = XElement.Parse(fieldXml);

                        // Check if the field contains a reference to a list. If by Guid, rewrite the value of the attribute to use web relative paths
                        var listIdentifier = element.Attribute("List") != null ? element.Attribute("List").Value : null;
                        if (!string.IsNullOrEmpty(listIdentifier))
                        {
                            var listGuid = Guid.Empty;
                            if (Guid.TryParse(listIdentifier, out listGuid))
                            {
                                var list = web.Lists.GetById(listGuid);
                                web.Context.Load(list, l => l.RootFolder.ServerRelativeUrl);
                                web.Context.ExecuteQueryRetry();

                                var listUrl = list.RootFolder.ServerRelativeUrl.Substring(web.ServerRelativeUrl.Length).TrimStart('/');
                                element.Attribute("List").SetValue(listUrl);
                                fieldXml = element.ToString();
                            }
                        }
                        // Check if the field is of type TaxonomyField
                        if (field.TypeAsString.StartsWith("TaxonomyField"))
                        {
                            var taxField = (TaxonomyField)field;
                            web.Context.Load(taxField, tf => tf.TextField, tf => tf.Id);
                            web.Context.ExecuteQueryRetry();
                            taxTextFieldsToRemove.Add(taxField.TextField);
                        }
                        // Check if we have version attribute. Remove if exists
                        if (element.Attribute("Version") != null)
                        {
                            element.Attributes("Version").Remove();
                            fieldXml = element.ToString();
                        }
                        template.SiteFields.Add(new Field() { SchemaXml = fieldXml });
                    }
                }
                // Remove hidden taxonomy text fields
                foreach (var textFieldId in taxTextFieldsToRemove)
                {
                    template.SiteFields.RemoveAll(f => Guid.Parse(f.SchemaXml.ElementAttributeValue("ID")).Equals(textFieldId));
                }
                // If a base template is specified then use that one to "cleanup" the generated template model
                if (creationInfo.BaseTemplate != null)
                {
                    template = CleanupEntities(template, creationInfo.BaseTemplate);
                }
            }
            return template;
        }
Example #54
0
        public void Provision(ClientContext ctx, ProvisioningTemplate template, ProvisioningTemplateApplyingInformation applyingInformation, TokenParser tokenParser, PnPMonitoredScope scope, string configurationData)
        {
            Log.Info(
                this.logSource,
                "ProcessRequest. Template: {0}. Config: {1}",
                template.Id,
                configurationData);

            Web         web;
            TokenParser parser       = tokenParser;
            var         usingRootWeb = false;

            if (ctx.Web.IsSubSite())
            {
                // This extension only works on sub webs with unique permissions!
                ctx.Web.Context.Load(ctx.Web, o => o.HasUniqueRoleAssignments);
                ctx.Web.Context.ExecuteQueryRetry();

                if (!ctx.Web.HasUniqueRoleAssignments)
                {
                    scope.LogDebug("Sub web does not have unique permissions, skipping Security provisioning on it!");
                    return;
                }
                else
                {
                    web          = ctx.GetSiteCollectionContext().Site.RootWeb;
                    usingRootWeb = true;
                }
            }
            else
            {
                // Business as usual
                web = ctx.Web;
            }

            var siteSecurity = template.Security;

            var ownerGroup   = web.AssociatedOwnerGroup;
            var memberGroup  = web.AssociatedMemberGroup;
            var visitorGroup = web.AssociatedVisitorGroup;


            web.Context.Load(ownerGroup, o => o.Title, o => o.Users);
            web.Context.Load(memberGroup, o => o.Title, o => o.Users);
            web.Context.Load(visitorGroup, o => o.Title, o => o.Users);

            web.Context.ExecuteQueryRetry();

            if (!ownerGroup.ServerObjectIsNull.Value)
            {
                AddUserToGroup(web, ownerGroup, siteSecurity.AdditionalOwners, scope);
            }
            if (!memberGroup.ServerObjectIsNull.Value)
            {
                AddUserToGroup(web, memberGroup, siteSecurity.AdditionalMembers, scope);
            }
            if (!visitorGroup.ServerObjectIsNull.Value)
            {
                AddUserToGroup(web, visitorGroup, siteSecurity.AdditionalVisitors, scope);
            }

            foreach (var siteGroup in siteSecurity.SiteGroups)
            {
                Group group     = null;
                var   allGroups = web.Context.LoadQuery(web.SiteGroups.Include(gr => gr.LoginName));
                web.Context.ExecuteQueryRetry();

                string parsedGroupTitle       = parser.ParseString(siteGroup.Title);
                string parsedGroupOwner       = parser.ParseString(siteGroup.Owner);
                string parsedGroupDescription = parser.ParseString(siteGroup.Description);

                if (!web.GroupExists(parsedGroupTitle))
                {
                    scope.LogDebug("Creating group {0}", parsedGroupTitle);
                    group = web.AddGroup(
                        parsedGroupTitle,
                        parsedGroupDescription,
                        parsedGroupTitle == parsedGroupOwner);
                    group.AllowMembersEditMembership   = siteGroup.AllowMembersEditMembership;
                    group.AllowRequestToJoinLeave      = siteGroup.AllowRequestToJoinLeave;
                    group.AutoAcceptRequestToJoinLeave = siteGroup.AutoAcceptRequestToJoinLeave;

                    if (parsedGroupTitle != parsedGroupOwner)
                    {
                        Principal ownerPrincipal = allGroups.FirstOrDefault(gr => gr.LoginName == parsedGroupOwner);
                        if (ownerPrincipal == null)
                        {
                            ownerPrincipal = web.EnsureUser(parsedGroupOwner);
                        }
                        group.Owner = ownerPrincipal;
                    }
                    group.Update();
                    web.Context.ExecuteQueryRetry();
                }
                else
                {
                    group = web.SiteGroups.GetByName(parsedGroupTitle);
                    web.Context.Load(group,
                                     g => g.Title,
                                     g => g.Description,
                                     g => g.AllowMembersEditMembership,
                                     g => g.AllowRequestToJoinLeave,
                                     g => g.AutoAcceptRequestToJoinLeave,
                                     g => g.Owner.LoginName);
                    web.Context.ExecuteQueryRetry();
                    var isDirty = false;
                    if (!String.IsNullOrEmpty(group.Description) && group.Description != parsedGroupDescription)
                    {
                        group.Description = parsedGroupDescription;
                        isDirty           = true;
                    }
                    if (group.AllowMembersEditMembership != siteGroup.AllowMembersEditMembership)
                    {
                        group.AllowMembersEditMembership = siteGroup.AllowMembersEditMembership;
                        isDirty = true;
                    }
                    if (group.AllowRequestToJoinLeave != siteGroup.AllowRequestToJoinLeave)
                    {
                        group.AllowRequestToJoinLeave = siteGroup.AllowRequestToJoinLeave;
                        isDirty = true;
                    }
                    if (group.AutoAcceptRequestToJoinLeave != siteGroup.AutoAcceptRequestToJoinLeave)
                    {
                        group.AutoAcceptRequestToJoinLeave = siteGroup.AutoAcceptRequestToJoinLeave;
                        isDirty = true;
                    }
                    if (group.Owner.LoginName != parsedGroupOwner)
                    {
                        if (parsedGroupTitle != parsedGroupOwner)
                        {
                            Principal ownerPrincipal = allGroups.FirstOrDefault(gr => gr.LoginName == parsedGroupOwner);
                            if (ownerPrincipal == null)
                            {
                                ownerPrincipal = web.EnsureUser(parsedGroupOwner);
                            }
                            group.Owner = ownerPrincipal;
                        }
                        else
                        {
                            group.Owner = group;
                        }
                        isDirty = true;
                    }
                    if (isDirty)
                    {
                        scope.LogDebug("Updating existing group {0}", group.Title);
                        group.Update();
                        web.Context.ExecuteQueryRetry();
                    }
                }
                if (group != null && siteGroup.Members.Any())
                {
                    AddUserToGroup(web, group, siteGroup.Members, scope);
                }
            }

            foreach (var admin in siteSecurity.AdditionalAdministrators)
            {
                var user = web.EnsureUser(admin.Name);
                user.IsSiteAdmin = true;
                user.Update();
                web.Context.ExecuteQueryRetry();
            }

            if (siteSecurity.SiteSecurityPermissions != null)
            {
                var existingRoleDefinitions = web.Context.LoadQuery(web.RoleDefinitions.Include(wr => wr.Name, wr => wr.BasePermissions, wr => wr.Description));
                web.Context.ExecuteQueryRetry();

                if (siteSecurity.SiteSecurityPermissions.RoleDefinitions.Any())
                {
                    foreach (var templateRoleDefinition in siteSecurity.SiteSecurityPermissions.RoleDefinitions)
                    {
                        var siteRoleDefinition = existingRoleDefinitions.FirstOrDefault(erd => erd.Name == parser.ParseString(templateRoleDefinition.Name));
                        if (siteRoleDefinition == null)
                        {
                            scope.LogDebug("Creation role definition {0}", parser.ParseString(templateRoleDefinition.Name));
                            var roleDefinitionCI = new RoleDefinitionCreationInformation();
                            roleDefinitionCI.Name        = parser.ParseString(templateRoleDefinition.Name);
                            roleDefinitionCI.Description = parser.ParseString(templateRoleDefinition.Description);
                            BasePermissions basePermissions = new BasePermissions();

                            foreach (var permission in templateRoleDefinition.Permissions)
                            {
                                basePermissions.Set(permission);
                            }

                            roleDefinitionCI.BasePermissions = basePermissions;

                            web.RoleDefinitions.Add(roleDefinitionCI);
                            web.Context.ExecuteQueryRetry();
                        }
                        else
                        {
                            var isDirty = false;
                            if (siteRoleDefinition.Description != parser.ParseString(templateRoleDefinition.Description))
                            {
                                siteRoleDefinition.Description = parser.ParseString(templateRoleDefinition.Description);
                                isDirty = true;
                            }
                            var templateBasePermissions = new BasePermissions();
                            templateRoleDefinition.Permissions.ForEach(p => templateBasePermissions.Set(p));
                            if (siteRoleDefinition.BasePermissions != templateBasePermissions)
                            {
                                isDirty = true;
                                foreach (var permission in templateRoleDefinition.Permissions)
                                {
                                    siteRoleDefinition.BasePermissions.Set(permission);
                                }
                            }
                            if (isDirty)
                            {
                                scope.LogDebug("Updating role definition {0}", parser.ParseString(templateRoleDefinition.Name));
                                siteRoleDefinition.Update();
                                web.Context.ExecuteQueryRetry();
                            }
                        }
                    }
                }

                if (usingRootWeb)
                {
                    web = ctx.Web;
                }
                var webRoleDefinitions = web.Context.LoadQuery(web.RoleDefinitions);
                var groups             = web.Context.LoadQuery(web.SiteGroups.Include(g => g.LoginName));
                web.Context.ExecuteQueryRetry();

                if (siteSecurity.SiteSecurityPermissions.RoleAssignments.Any())
                {
                    foreach (var roleAssignment in siteSecurity.SiteSecurityPermissions.RoleAssignments)
                    {
                        Principal principal = groups.FirstOrDefault(g => g.LoginName == parser.ParseString(roleAssignment.Principal));
                        if (principal == null)
                        {
                            principal = web.EnsureUser(parser.ParseString(roleAssignment.Principal));
                        }

                        var roleDefinitionBindingCollection = new RoleDefinitionBindingCollection(web.Context);

                        var roleDefinition = webRoleDefinitions.FirstOrDefault(r => r.Name == parser.ParseString(roleAssignment.RoleDefinition));

                        if (roleDefinition != null)
                        {
                            roleDefinitionBindingCollection.Add(roleDefinition);
                        }
                        web.RoleAssignments.Add(principal, roleDefinitionBindingCollection);
                        web.Context.ExecuteQueryRetry();
                    }
                }
            }
        }
Example #55
0
        public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
        {
            using (var scope = new PnPMonitoredScope(CoreResources.Provisioning_ObjectHandlers_Pages))
            {

                var context = web.Context as ClientContext;

                if (!web.IsPropertyAvailable("ServerRelativeUrl"))
                {
                    context.Load(web, w => w.ServerRelativeUrl);
                    context.ExecuteQueryRetry();
                }

                foreach (var page in template.Pages)
                {
                    var url = parser.ParseString(page.Url);

                    if (!url.ToLower().StartsWith(web.ServerRelativeUrl.ToLower()))
                    {
                        url = UrlUtility.Combine(web.ServerRelativeUrl, url);
                    }

                    var exists = true;
                    Microsoft.SharePoint.Client.File file = null;
                    try
                    {
                        file = web.GetFileByServerRelativeUrl(url);
                        web.Context.Load(file);
                        web.Context.ExecuteQuery();
                    }
                    catch (ServerException ex)
                    {
                        if (ex.ServerErrorTypeName == "System.IO.FileNotFoundException")
                        {
                            exists = false;
                        }
                    }
                    if (exists)
                    {
                        if (page.Overwrite)
                        {
                            try
                            {
                                scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Pages_Overwriting_existing_page__0_, url);
                                file.DeleteObject();
                                web.Context.ExecuteQueryRetry();
                                web.AddWikiPageByUrl(url);
                                web.AddLayoutToWikiPage(page.Layout, url);
                            }
                            catch (Exception ex)
                            {
                                scope.LogError(CoreResources.Provisioning_ObjectHandlers_Pages_Overwriting_existing_page__0__failed___1_____2_,url,ex.Message,ex.StackTrace);
                            }
                        }
                    }
                    else
                    {
                        try
                        {

                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Pages_Creating_new_page__0_, url);

                            web.AddWikiPageByUrl(url);
                            web.AddLayoutToWikiPage(page.Layout, url);
                        }
                        catch (Exception ex)
                        {
                            scope.LogError(CoreResources.Provisioning_ObjectHandlers_Pages_Creating_new_page__0__failed___1_____2_,url, ex.Message,ex.StackTrace);
                        }
                    }

                    if (page.WelcomePage)
                    {
                        if (!web.IsPropertyAvailable("RootFolder"))
                        {
                            web.Context.Load(web.RootFolder);
                            web.Context.ExecuteQueryRetry();
                        }

                        var rootFolderRelativeUrl = url.Substring(web.RootFolder.ServerRelativeUrl.Length);
                        web.SetHomePage(rootFolderRelativeUrl);
                    }

                    if (page.WebParts != null & page.WebParts.Any())
                    {
                        var existingWebParts = web.GetWebParts(url);

                        foreach (var webpart in page.WebParts)
                        {
                            if (existingWebParts.FirstOrDefault(w => w.WebPart.Title == webpart.Title) == null)
                            {
                                WebPartEntity wpEntity = new WebPartEntity();
                                wpEntity.WebPartTitle = webpart.Title;
                                wpEntity.WebPartXml = parser.ParseString(webpart.Contents).Trim(new[] {'\n', ' '});
                                web.AddWebPartToWikiPage(url, wpEntity, (int) webpart.Row, (int) webpart.Column, false);
                            }
                        }
                    }
                }
            }
            return parser;
        }
Example #56
0
        /// <summary>
        /// Actual implementation of extracting configuration from existing site.
        /// </summary>
        /// <param name="web"></param>
        /// <param name="creationInfo"></param>
        /// <returns></returns>
        internal ProvisioningTemplate GetRemoteTemplate(Web web, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(CoreResources.Provisioning_ObjectHandlers_Extraction))
            {
                ProvisioningProgressDelegate progressDelegate = null;
                ProvisioningMessagesDelegate messagesDelegate = null;
                if (creationInfo != null)
                {
                    if (creationInfo.BaseTemplate != null)
                    {
                        scope.LogDebug(CoreResources.SiteToTemplateConversion_Base_template_available___0_, creationInfo.BaseTemplate.Id);
                    }
                    progressDelegate = creationInfo.ProgressDelegate;
                    if (creationInfo.ProgressDelegate != null)
                    {
                        scope.LogDebug(CoreResources.SiteToTemplateConversion_ProgressDelegate_registered);
                    }
                    messagesDelegate = creationInfo.MessagesDelegate;
                    if (creationInfo.MessagesDelegate != null)
                    {
                        scope.LogDebug(CoreResources.SiteToTemplateConversion_MessagesDelegate_registered);
                    }
                    if (creationInfo.IncludeAllTermGroups)
                    {
                        scope.LogDebug(CoreResources.SiteToTemplateConversion_IncludeAllTermGroups_is_set_to_true);
                    }
                    if (creationInfo.IncludeSiteCollectionTermGroup)
                    {
                        scope.LogDebug(CoreResources.SiteToTemplateConversion_IncludeSiteCollectionTermGroup_is_set_to_true);
                    }
                    if (creationInfo.PersistBrandingFiles)
                    {
                        scope.LogDebug(CoreResources.SiteToTemplateConversion_PersistBrandingFiles_is_set_to_true);
                    }
                }
                else
                {
                    // When no provisioning info was passed then we want to execute all handlers
                    creationInfo = new ProvisioningTemplateCreationInformation(web);
                    creationInfo.HandlersToProcess = Handlers.All;
                }

                // Create empty object
                ProvisioningTemplate template = new ProvisioningTemplate();

                // Hookup connector, is handy when the generated template object is used to apply to another site
                template.Connector = creationInfo.FileConnector;

                List <ObjectHandlerBase> objectHandlers = new List <ObjectHandlerBase>();

                if (creationInfo.HandlersToProcess.HasFlag(Handlers.RegionalSettings))
                {
                    objectHandlers.Add(new ObjectRegionalSettings());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.SupportedUILanguages))
                {
                    objectHandlers.Add(new ObjectSupportedUILanguages());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.AuditSettings))
                {
                    objectHandlers.Add(new ObjectAuditSettings());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.SitePolicy))
                {
                    objectHandlers.Add(new ObjectSitePolicy());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.SiteSecurity))
                {
                    objectHandlers.Add(new ObjectSiteSecurity());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.TermGroups))
                {
                    objectHandlers.Add(new ObjectTermGroups());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.Fields))
                {
                    objectHandlers.Add(new ObjectField());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.ContentTypes))
                {
                    objectHandlers.Add(new ObjectContentType());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.Lists))
                {
                    objectHandlers.Add(new ObjectListInstance());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.CustomActions))
                {
                    objectHandlers.Add(new ObjectCustomActions());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.Features))
                {
                    objectHandlers.Add(new ObjectFeatures());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.ComposedLook))
                {
                    objectHandlers.Add(new ObjectComposedLook());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.SearchSettings))
                {
                    objectHandlers.Add(new ObjectSearchSettings());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.Publishing))
                {
                    objectHandlers.Add(new ObjectPublishing());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.Files))
                {
                    objectHandlers.Add(new ObjectFiles());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.Pages))
                {
                    objectHandlers.Add(new ObjectPages());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.PageContents))
                {
                    objectHandlers.Add(new ObjectPageContents());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.PropertyBagEntries))
                {
                    objectHandlers.Add(new ObjectPropertyBagEntry());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.Workflows))
                {
                    objectHandlers.Add(new ObjectWorkflows());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.WebSettings))
                {
                    objectHandlers.Add(new ObjectWebSettings());
                }
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.Navigation))
                {
                    objectHandlers.Add(new ObjectNavigation());
                }
                objectHandlers.Add(new ObjectLocalization()); // Always add this one, check is done in the handler
                if (creationInfo.HandlersToProcess.HasFlag(Handlers.ExtensibilityProviders))
                {
                    objectHandlers.Add(new ObjectExtensibilityHandlers());
                }

                objectHandlers.Add(new ObjectRetrieveTemplateInfo());

                int step = 1;

                var count = objectHandlers.Count(o => o.ReportProgress && o.WillExtract(web, template, creationInfo));

                web.EnsureProperty(w => w.Url);

                foreach (var handler in objectHandlers)
                {
                    if (handler.WillExtract(web, template, creationInfo))
                    {
                        if (messagesDelegate != null)
                        {
                            handler.MessagesDelegate = messagesDelegate;
                        }
                        if (handler.ReportProgress && progressDelegate != null)
                        {
                            progressDelegate(handler.Name, step, count);
                            step++;
                        }

                        using (var handlerContext = web.Context.Clone(web.Url))
                        {
                            template = handler.ExtractObjects(handlerContext.Web, template, creationInfo);
                        }
                    }
                }

                //if (creationInfo.PersistMultiLanguageResources)
                //{
                //    template = UserResourceExtensions.SaveResourceValues(template, creationInfo);
                //}

                return(template);
            }
        }
        private void CreateView(Web web, View view, Microsoft.SharePoint.Client.ViewCollection existingViews, List createdList, PnPMonitoredScope monitoredScope)
        {
            try
            {

                var viewElement = XElement.Parse(view.SchemaXml);
                var displayNameElement = viewElement.Attribute("DisplayName");
                if (displayNameElement == null)
                {
                    throw new ApplicationException("Invalid View element, missing a valid value for the attribute DisplayName.");
                }

                monitoredScope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Creating_view__0_, displayNameElement.Value);
                var existingView = existingViews.FirstOrDefault(v => v.Title == displayNameElement.Value);

                if (existingView != null)
                {
                    existingView.DeleteObject();
                    web.Context.ExecuteQueryRetry();
                }

                var viewTitle = displayNameElement.Value;

                // Type
                var viewTypeString = viewElement.Attribute("Type") != null ? viewElement.Attribute("Type").Value : "None";
                viewTypeString = viewTypeString[0].ToString().ToUpper() + viewTypeString.Substring(1).ToLower();
                var viewType = (ViewType)Enum.Parse(typeof(ViewType), viewTypeString);

                // Fields
                string[] viewFields = null;
                var viewFieldsElement = viewElement.Descendants("ViewFields").FirstOrDefault();
                if (viewFieldsElement != null)
                {
                    viewFields = (from field in viewElement.Descendants("ViewFields").Descendants("FieldRef") select field.Attribute("Name").Value).ToArray();
                }

                // Default view
                var viewDefault = viewElement.Attribute("DefaultView") != null && Boolean.Parse(viewElement.Attribute("DefaultView").Value);

                // Row limit
                var viewPaged = true;
                uint viewRowLimit = 30;
                var rowLimitElement = viewElement.Descendants("RowLimit").FirstOrDefault();
                if (rowLimitElement != null)
                {
                    if (rowLimitElement.Attribute("Paged") != null)
                    {
                        viewPaged = bool.Parse(rowLimitElement.Attribute("Paged").Value);
                    }
                    viewRowLimit = uint.Parse(rowLimitElement.Value);
                }

                // Query
                var viewQuery = new StringBuilder();
                foreach (var queryElement in viewElement.Descendants("Query").Elements())
                {
                    viewQuery.Append(queryElement.ToString());
                }

                var viewCI = new ViewCreationInformation
                {
                    ViewFields = viewFields,
                    RowLimit = viewRowLimit,
                    Paged = viewPaged,
                    Title = viewTitle,
                    Query = viewQuery.ToString(),
                    ViewTypeKind = viewType,
                    PersonalView = false,
                    SetAsDefaultView = viewDefault,
                };

                // Allow to specify a custom view url. View url is taken from title, so we first set title to the view url value we need,
                // create the view and then set title back to the original value
                var urlAttribute = viewElement.Attribute("Url");
                var urlHasValue = urlAttribute != null && !string.IsNullOrEmpty(urlAttribute.Value);
                if (urlHasValue)
                {
                    //set Title to be equal to url (in order to generate desired url)
                    viewCI.Title = Path.GetFileNameWithoutExtension(urlAttribute.Value);
                }

                var createdView = createdList.Views.Add(viewCI);
                web.Context.Load(createdView, v => v.Scope, v => v.JSLink, v => v.Title);
                web.Context.ExecuteQueryRetry();

                if (urlHasValue)
                {
                    //restore original title
                    createdView.Title = viewTitle;
                    createdView.Update();
                }

                // ContentTypeID
                var contentTypeID = viewElement.Attribute("ContentTypeID") != null ? viewElement.Attribute("ContentTypeID").Value : null;
                if (!string.IsNullOrEmpty(contentTypeID) && (contentTypeID != BuiltInContentTypeId.System))
                {
                    ContentTypeId childContentTypeId = null;
                    if (contentTypeID == BuiltInContentTypeId.RootOfList)
                    {
                        var childContentType = web.GetContentTypeById(contentTypeID);
                        childContentTypeId = childContentType != null ? childContentType.Id : null;
                    }
                    else
                    {
                        childContentTypeId = createdList.ContentTypes.BestMatch(contentTypeID);
                    }
                    if (childContentTypeId != null)
                    {
                        createdView.ContentTypeId = childContentTypeId;
                        createdView.Update();
                    }
                }

                // Default for content type
                bool parsedDefaultViewForContentType;
                var defaultViewForContentType = viewElement.Attribute("DefaultViewForContentType") != null ? viewElement.Attribute("DefaultViewForContentType").Value : null;
                if (!string.IsNullOrEmpty(defaultViewForContentType) && bool.TryParse(defaultViewForContentType, out parsedDefaultViewForContentType))
                {
                    createdView.DefaultViewForContentType = parsedDefaultViewForContentType;
                    createdView.Update();
                }

                // Scope
                var scope = viewElement.Attribute("Scope") != null ? viewElement.Attribute("Scope").Value : null;
                ViewScope parsedScope = ViewScope.DefaultValue;
                if (!string.IsNullOrEmpty(scope) && Enum.TryParse<ViewScope>(scope, out parsedScope))
                {
                    createdView.Scope = parsedScope;
                    createdView.Update();
                }

                // JSLink
                var jslinkElement = viewElement.Descendants("JSLink").FirstOrDefault();
                if (jslinkElement != null)
                {
                    var jslink = jslinkElement.Value;
                    if (createdView.JSLink != jslink)
                    {
                        createdView.JSLink = jslink;
                        createdView.Update();
                    }
                }

                createdList.Update();
                web.Context.ExecuteQueryRetry();
            }
            catch (Exception ex)
            {
                monitoredScope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstances_Creating_view_failed___0_____1_, ex.Message, ex.StackTrace);
                throw;
            }
        }
        private static void UpdateContentType(Web web, Microsoft.SharePoint.Client.ContentType existingContentType, ContentType templateContentType, TokenParser parser, PnPMonitoredScope scope, bool isNoScriptSite = false)
        {
            var isDirty = false;

            if (existingContentType.Hidden != templateContentType.Hidden)
            {
                scope.LogPropertyUpdate("Hidden");
                existingContentType.Hidden = templateContentType.Hidden;
                isDirty = true;
            }
            if (existingContentType.ReadOnly != templateContentType.ReadOnly)
            {
                scope.LogPropertyUpdate("ReadOnly");
                existingContentType.ReadOnly = templateContentType.ReadOnly;
                isDirty = true;
            }
            if (existingContentType.Sealed != templateContentType.Sealed)
            {
                scope.LogPropertyUpdate("Sealed");
                existingContentType.Sealed = templateContentType.Sealed;
                isDirty = true;
            }
            if (templateContentType.Description != null && existingContentType.Description != parser.ParseString(templateContentType.Description))
            {
                scope.LogPropertyUpdate("Description");
                existingContentType.Description = parser.ParseString(templateContentType.Description);
                isDirty = true;
            }
            if (templateContentType.DocumentTemplate != null && existingContentType.DocumentTemplate != parser.ParseString(templateContentType.DocumentTemplate))
            {
                scope.LogPropertyUpdate("DocumentTemplate");
                existingContentType.DocumentTemplate = parser.ParseString(templateContentType.DocumentTemplate);
                isDirty = true;
            }
            if (existingContentType.Name != parser.ParseString(templateContentType.Name))
            {
                scope.LogPropertyUpdate("Name");
                existingContentType.Name = parser.ParseString(templateContentType.Name);
                isDirty = true;
                // CT is being renamed, add an extra token to the tokenparser
                parser.AddToken(new ContentTypeIdToken(web, existingContentType.Name, existingContentType.StringId));
            }
            if (templateContentType.Group != null && existingContentType.Group != parser.ParseString(templateContentType.Group))
            {
                scope.LogPropertyUpdate("Group");
                existingContentType.Group = parser.ParseString(templateContentType.Group);
                isDirty = true;
            }
            if (!isNoScriptSite)
            {
                if (templateContentType.DisplayFormUrl != null && existingContentType.DisplayFormUrl != parser.ParseString(templateContentType.DisplayFormUrl))
                {
                    scope.LogPropertyUpdate("DisplayFormUrl");
                    existingContentType.DisplayFormUrl = parser.ParseString(templateContentType.DisplayFormUrl);
                    isDirty = true;
                }
                if (templateContentType.EditFormUrl != null && existingContentType.EditFormUrl != parser.ParseString(templateContentType.EditFormUrl))
                {
                    scope.LogPropertyUpdate("EditFormUrl");
                    existingContentType.EditFormUrl = parser.ParseString(templateContentType.EditFormUrl);
                    isDirty = true;
                }
                if (templateContentType.NewFormUrl != null && existingContentType.NewFormUrl != parser.ParseString(templateContentType.NewFormUrl))
                {
                    scope.LogPropertyUpdate("NewFormUrl");
                    existingContentType.NewFormUrl = parser.ParseString(templateContentType.NewFormUrl);
                    isDirty = true;
                }
            }
            else
            {
                if (!String.IsNullOrEmpty(parser.ParseString(templateContentType.DisplayFormUrl)) ||
                    !String.IsNullOrEmpty(parser.ParseString(templateContentType.EditFormUrl)) ||
                    !String.IsNullOrEmpty(parser.ParseString(templateContentType.NewFormUrl)))
                {
                    // log message
                    scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_ContentTypes_SkipCustomFormUrls, existingContentType.Name);
                }
            }

#if !SP2013
            if (templateContentType.Name.ContainsResourceToken())
            {
                existingContentType.NameResource.SetUserResourceValue(templateContentType.Name, parser);
                isDirty = true;
            }
            if (templateContentType.Description.ContainsResourceToken())
            {
                existingContentType.DescriptionResource.SetUserResourceValue(templateContentType.Description, parser);
                isDirty = true;
            }
#endif
            if (isDirty)
            {
                existingContentType.Update(true);
                web.Context.ExecuteQueryRetry();
            }
            // Delta handling
            existingContentType.EnsureProperty(c => c.FieldLinks);
            List <Guid> targetIds = existingContentType.FieldLinks.AsEnumerable().Select(c1 => c1.Id).ToList();
            List <Guid> sourceIds = templateContentType.FieldRefs.Select(c1 => c1.Id).ToList();

            var fieldsNotPresentInTarget = sourceIds.Except(targetIds).ToArray();

            if (fieldsNotPresentInTarget.Any())
            {
                foreach (var fieldId in fieldsNotPresentInTarget)
                {
                    var fieldRef = templateContentType.FieldRefs.Find(fr => fr.Id == fieldId);
                    var field    = web.Fields.GetById(fieldId);
                    scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ContentTypes_Adding_field__0__to_content_type, fieldId);
                    web.AddFieldToContentType(existingContentType, field, fieldRef.Required, fieldRef.Hidden);
                }
            }

            isDirty = false;
            foreach (var fieldId in targetIds.Intersect(sourceIds))
            {
                var fieldLink = existingContentType.FieldLinks.FirstOrDefault(fl => fl.Id == fieldId);
                var fieldRef  = templateContentType.FieldRefs.Find(fr => fr.Id == fieldId);
                if (fieldRef != null)
                {
                    scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ContentTypes_Field__0__exists_in_content_type, fieldId);
                    if (fieldLink.Required != fieldRef.Required)
                    {
                        scope.LogPropertyUpdate("Required");
                        fieldLink.Required = fieldRef.Required;
                        isDirty            = true;
                    }
                    if (fieldLink.Hidden != fieldRef.Hidden)
                    {
                        scope.LogPropertyUpdate("Hidden");
                        fieldLink.Hidden = fieldRef.Hidden;
                        isDirty          = true;
                    }
                }
            }

            // The new CT is a DocumentSet, and the target should be, as well
            if (templateContentType.DocumentSetTemplate != null)
            {
                if (!Microsoft.SharePoint.Client.DocumentSet.DocumentSetTemplate.IsChildOfDocumentSetContentType(web.Context, existingContentType).Value)
                {
                    scope.LogError(CoreResources.Provisioning_ObjectHandlers_ContentTypes_InvalidDocumentSet_Update_Request, existingContentType.Id, existingContentType.Name);
                }
                else
                {
                    Microsoft.SharePoint.Client.DocumentSet.DocumentSetTemplate templateToUpdate =
                        Microsoft.SharePoint.Client.DocumentSet.DocumentSetTemplate.GetDocumentSetTemplate(web.Context, existingContentType);

                    // TODO: Implement Delta Handling
                    scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_ContentTypes_DocumentSet_DeltaHandling_OnHold, existingContentType.Id, existingContentType.Name);
                }
            }

            if (isDirty)
            {
                existingContentType.Update(true);
                web.Context.ExecuteQueryRetry();
            }
        }
        public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                web.EnsureProperties(w => w.ServerRelativeUrl, w => w.Url);

                var serverRelativeUrl = web.ServerRelativeUrl;

                // For each list in the site
                var lists = web.Lists;

                web.Context.Load(lists,
                    lc => lc.IncludeWithDefaultProperties(
                        l => l.ContentTypes,
                        l => l.Views,
                        l => l.EnableModeration,
                        l => l.ForceCheckout,
                        l => l.BaseTemplate,
                        l => l.OnQuickLaunch,
                        l => l.RootFolder.ServerRelativeUrl,
                        l => l.UserCustomActions,
                        l => l.MajorVersionLimit,
                        l => l.MajorWithMinorVersionsLimit,
                        l => l.DraftVersionVisibility,
                        l => l.DocumentTemplateUrl,
                        l => l.Fields.IncludeWithDefaultProperties(
                            f => f.Id,
                            f => f.Title,
                            f => f.Hidden,
                            f => f.InternalName,
                            f => f.DefaultValue,
                            f => f.Required)));

                web.Context.ExecuteQueryRetry();

                var allLists = new List<List>();

                if (web.IsSubSite())
                {
                    // If current web is subweb then include the lists in the rootweb for lookup column support
                    var rootWeb = (web.Context as ClientContext).Site.RootWeb;
                    rootWeb.Context.Load(rootWeb.Lists, lsts => lsts.Include(l => l.Id, l => l.Title));
                    rootWeb.Context.ExecuteQueryRetry();
                    foreach (var rootList in rootWeb.Lists)
                    {
                        allLists.Add(rootList);
                    }
                }

                foreach (var list in lists)
                {
                    allLists.Add(list);
                }
                // Let's see if there are workflow subscriptions
                Microsoft.SharePoint.Client.WorkflowServices.WorkflowSubscription[] workflowSubscriptions = null;
                try
                {
                    workflowSubscriptions = web.GetWorkflowSubscriptions();
                }
                catch (ServerException)
                {
                    // If there is no workflow service present in the farm this method will throw an error.
                    // Swallow the exception
                }

                // Retrieve all not hidden lists and the Workflow History Lists, just in case there are active workflow subscriptions
                foreach (var siteList in lists.AsEnumerable().Where(l => (l.Hidden == false || ((workflowSubscriptions != null && workflowSubscriptions.Length > 0) && l.BaseTemplate == 140))))
                {
                    ListInstance baseTemplateList = null;
                    if (creationInfo.BaseTemplate != null)
                    {
                        // Check if we need to skip this list...if so let's do it before we gather all the other information for this list...improves performance
                        var index = creationInfo.BaseTemplate.Lists.FindIndex(f => f.Url.Equals(siteList.RootFolder.ServerRelativeUrl.Substring(serverRelativeUrl.Length + 1)) &&
                                                                                   f.TemplateType.Equals(siteList.BaseTemplate));
                        if (index != -1)
                        {
                            baseTemplateList = creationInfo.BaseTemplate.Lists[index];
                        }
                    }

                    var contentTypeFields = new List<FieldRef>();
                    var list = new ListInstance
                    {
                        Description = siteList.Description,
                        EnableVersioning = siteList.EnableVersioning,
                        TemplateType = siteList.BaseTemplate,
                        Title = siteList.Title,
                        Hidden = siteList.Hidden,
                        EnableFolderCreation = siteList.EnableFolderCreation,
                        DocumentTemplate = Tokenize(siteList.DocumentTemplateUrl, web.Url),
                        ContentTypesEnabled = siteList.ContentTypesEnabled,
                        Url = siteList.RootFolder.ServerRelativeUrl.Substring(serverRelativeUrl.Length).TrimStart('/'),
                        TemplateFeatureID = siteList.TemplateFeatureId,
                        EnableAttachments = siteList.EnableAttachments,
                        OnQuickLaunch = siteList.OnQuickLaunch,
                        EnableModeration = siteList.EnableModeration,
                        MaxVersionLimit =
                            siteList.IsPropertyAvailable("MajorVersionLimit") ? siteList.MajorVersionLimit : 0,
                        EnableMinorVersions = siteList.EnableMinorVersions,
                        MinorVersionLimit =
                            siteList.IsPropertyAvailable("MajorWithMinorVersionsLimit")
                                ? siteList.MajorWithMinorVersionsLimit
                                : 0,
                        ForceCheckout = siteList.IsPropertyAvailable("ForceCheckout") ?
                            siteList.ForceCheckout : false,
                        DraftVersionVisibility = siteList.IsPropertyAvailable("DraftVersionVisibility") ? (int)siteList.DraftVersionVisibility : 0,
                    };

                    if (creationInfo.PersistMultiLanguageResources)
                    {
            #if !SP2013
                        if (UserResourceExtensions.PersistResourceValue(siteList.TitleResource, string.Format("List_{0}_Title", siteList.Title.Replace(" ", "_")), template, creationInfo))
                        {
                            list.Title = string.Format("{{res:List_{0}_Title}}", siteList.Title.Replace(" ", "_"));
                        }
                        if (UserResourceExtensions.PersistResourceValue(siteList.DescriptionResource, string.Format("List_{0}_Description", siteList.Title.Replace(" ", "_")), template, creationInfo))
                        {
                            list.Description = string.Format("{{res:List_{0}_Description}}", siteList.Title.Replace(" ", "_"));
                        }
            #endif
                    }

                    list = ExtractContentTypes(web, siteList, contentTypeFields, list);

                    list = ExtractViews(siteList, list);

                    list = ExtractFields(web, siteList, contentTypeFields, list, allLists, creationInfo, template);

                    list = ExtractUserCustomActions(web, siteList, list, creationInfo, template);

                    list.Security = siteList.GetSecurity();

                    var logCTWarning = false;
                    if (baseTemplateList != null)
                    {
                        if (!baseTemplateList.Equals(list))
                        {
                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Adding_list___0_____1_, list.Title, list.Url);
                            template.Lists.Add(list);
                            if (list.ContentTypesEnabled && list.ContentTypeBindings.Any() && web.IsSubSite())
                            {
                                logCTWarning = true;
                            }
                        }
                    }
                    else
                    {
                        scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Adding_list___0_____1_, list.Title, list.Url);
                        template.Lists.Add(list);
                        if (list.ContentTypesEnabled && list.ContentTypeBindings.Any() && web.IsSubSite())
                        {
                            logCTWarning = true;
                        }

                    }
                    if (logCTWarning)
                    {
                        scope.LogWarning("You are extracting a template from a subweb. List '{0}' refers to content types. Content types are not exported when extracting a template from a subweb", siteList.Title);
                        WriteWarning(string.Format("You are extracting a template from a subweb. List '{0}' refers to content types. Content types are not exported when extracting a template from a subweb", siteList.Title), ProvisioningMessageType.Warning);
                    }
                }

            }
            return template;
        }
Example #60
0
        public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation)
        {
            using (var scope = new PnPMonitoredScope(this.Name))
            {
                // Changed by Paolo Pialorsi to embrace the new sub-site attributes to break role inheritance and copy role assignments
                // if this is a sub site then we're not provisioning security as by default security is inherited from the root site
                //if (web.IsSubSite() && !template.Security.BreakRoleInheritance)
                //{
                //    scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_SiteSecurity_Context_web_is_subweb__skipping_site_security_provisioning);
                //    return parser;
                //}

                if (web.IsSubSite() && template.Security.BreakRoleInheritance)
                {
                    web.BreakRoleInheritance(template.Security.CopyRoleAssignments, template.Security.ClearSubscopes);
                    web.Update();
                    web.Context.Load(web, w => w.HasUniqueRoleAssignments);
                    web.Context.ExecuteQueryRetry();
                }

                var siteSecurity = template.Security;

                if (web.EnsureProperty(w => w.HasUniqueRoleAssignments))
                {
                    string parsedAssociatedOwnerGroupName   = parser.ParseString(template.Security.AssociatedOwnerGroup);
                    string parsedAssociatedMemberGroupName  = parser.ParseString(template.Security.AssociatedMemberGroup);
                    string parsedAssociatedVisitorGroupName = parser.ParseString(template.Security.AssociatedVisitorGroup);

                    bool webNeedsUpdate = false;

                    if (parsedAssociatedOwnerGroupName != null)
                    {
                        if (string.IsNullOrEmpty(parsedAssociatedOwnerGroupName))
                        {
                            web.AssociatedOwnerGroup = null;
                        }
                        else
                        {
                            web.AssociatedOwnerGroup = EnsureGroup(web, parsedAssociatedOwnerGroupName);
                        }

                        webNeedsUpdate = true;
                    }

                    if (parsedAssociatedMemberGroupName != null)
                    {
                        if (string.IsNullOrEmpty(parsedAssociatedMemberGroupName))
                        {
                            web.AssociatedMemberGroup = null;
                        }
                        else
                        {
                            web.AssociatedMemberGroup = EnsureGroup(web, parsedAssociatedMemberGroupName);
                        }

                        webNeedsUpdate = true;
                    }

                    if (parsedAssociatedVisitorGroupName != null)
                    {
                        if (string.IsNullOrEmpty(parsedAssociatedVisitorGroupName))
                        {
                            web.AssociatedVisitorGroup = null;
                        }
                        else
                        {
                            web.AssociatedVisitorGroup = EnsureGroup(web, parsedAssociatedVisitorGroupName);
                        }

                        webNeedsUpdate = true;
                    }

                    if (webNeedsUpdate)
                    {
                        // Trigger the creation and setting of the associated groups
                        web.Update();
                        web.Context.ExecuteQueryRetry();
                    }
                }

                var ownerGroup   = web.AssociatedOwnerGroup;
                var memberGroup  = web.AssociatedMemberGroup;
                var visitorGroup = web.AssociatedVisitorGroup;

                if (!ownerGroup.ServerObjectIsNull())
                {
                    web.Context.Load(ownerGroup, o => o.Title, o => o.Users);
                }
                if (!memberGroup.ServerObjectIsNull())
                {
                    web.Context.Load(memberGroup, o => o.Title, o => o.Users);
                }
                if (!visitorGroup.ServerObjectIsNull())
                {
                    web.Context.Load(visitorGroup, o => o.Title, o => o.Users);
                }

                web.Context.Load(web.SiteUsers);

                web.Context.ExecuteQueryRetry();

                IEnumerable <AssociatedGroupToken> associatedGroupTokens = parser.Tokens.Where(t => t.GetType() == typeof(AssociatedGroupToken)).Cast <AssociatedGroupToken>();
                foreach (AssociatedGroupToken associatedGroupToken in associatedGroupTokens)
                {
                    associatedGroupToken.ClearCache();
                }

                if (!ownerGroup.ServerObjectIsNull())
                {
                    AddUserToGroup(web, ownerGroup, siteSecurity.AdditionalOwners, scope, parser);
                }
                if (!memberGroup.ServerObjectIsNull())
                {
                    AddUserToGroup(web, memberGroup, siteSecurity.AdditionalMembers, scope, parser);
                }
                if (!visitorGroup.ServerObjectIsNull())
                {
                    AddUserToGroup(web, visitorGroup, siteSecurity.AdditionalVisitors, scope, parser);
                }

                foreach (var siteGroup in siteSecurity.SiteGroups
                         .Sort <SiteGroup>(
                             _grp => {
                    string groupOwner = _grp.Owner;
                    if (string.IsNullOrWhiteSpace(groupOwner) ||
                        "SHAREPOINT\\system".Equals(groupOwner, StringComparison.OrdinalIgnoreCase) ||
                        _grp.Title.Equals(groupOwner, StringComparison.OrdinalIgnoreCase) ||
                        (groupOwner.StartsWith("{{associated") && groupOwner.EndsWith("group}}")))
                    {
                        return(Enumerable.Empty <SiteGroup>());
                    }
                    return(siteSecurity.SiteGroups.Where(_item => _item.Title.Equals(groupOwner, StringComparison.OrdinalIgnoreCase)));
                }
                             ))
                {
                    Group group;
                    var   allGroups = web.Context.LoadQuery(web.SiteGroups.Include(gr => gr.LoginName));
                    web.Context.ExecuteQueryRetry();

                    string parsedGroupTitle       = parser.ParseString(siteGroup.Title);
                    string parsedGroupOwner       = parser.ParseString(siteGroup.Owner);
                    string parsedGroupDescription = parser.ParseString(siteGroup.Description);

                    if (!web.GroupExists(parsedGroupTitle))
                    {
                        scope.LogDebug("Creating group {0}", parsedGroupTitle);
                        group = web.AddGroup(
                            parsedGroupTitle,
                            //If the description is more than 512 characters long a server exception will be thrown.
                            PnPHttpUtility.ConvertSimpleHtmlToText(parsedGroupDescription, int.MaxValue),
                            parsedGroupTitle == parsedGroupOwner);
                        group.AllowMembersEditMembership     = siteGroup.AllowMembersEditMembership;
                        group.AllowRequestToJoinLeave        = siteGroup.AllowRequestToJoinLeave;
                        group.AutoAcceptRequestToJoinLeave   = siteGroup.AutoAcceptRequestToJoinLeave;
                        group.OnlyAllowMembersViewMembership = siteGroup.OnlyAllowMembersViewMembership;
                        group.RequestToJoinLeaveEmailSetting = siteGroup.RequestToJoinLeaveEmailSetting;

                        if (parsedGroupOwner != null && (parsedGroupTitle != parsedGroupOwner))
                        {
                            Principal ownerPrincipal = allGroups.FirstOrDefault(gr => gr.LoginName.Equals(parsedGroupOwner, StringComparison.OrdinalIgnoreCase));
                            if (ownerPrincipal == null)
                            {
                                ownerPrincipal = web.EnsureUser(parsedGroupOwner);
                            }
                            group.Owner = ownerPrincipal;
                        }

                        group.Update();
                        web.Context.Load(group, g => g.Id, g => g.Title);
                        web.Context.ExecuteQueryRetry();
                        parser.AddToken(new GroupIdToken(web, group.Title, group.Id));

                        var groupItem = web.SiteUserInfoList.GetItemById(group.Id);
                        groupItem["Notes"] = parsedGroupDescription;
                        groupItem.Update();
                        web.Context.ExecuteQueryRetry();
                    }
                    else
                    {
                        group = web.SiteGroups.GetByName(parsedGroupTitle);
                        web.Context.Load(group,
                                         g => g.Id,
                                         g => g.Title,
                                         g => g.Description,
                                         g => g.AllowMembersEditMembership,
                                         g => g.AllowRequestToJoinLeave,
                                         g => g.AutoAcceptRequestToJoinLeave,
                                         g => g.OnlyAllowMembersViewMembership,
                                         g => g.RequestToJoinLeaveEmailSetting,
                                         g => g.Owner.LoginName);
                        web.Context.ExecuteQueryRetry();

                        var groupNeedsUpdate = false;
                        var executeQuery     = false;

                        if (parsedGroupDescription != null)
                        {
                            var groupItem = web.SiteUserInfoList.GetItemById(group.Id);
                            web.Context.Load(groupItem, g => g["Notes"]);
                            web.Context.ExecuteQueryRetry();
                            var description = groupItem["Notes"]?.ToString();

                            if (description != parsedGroupDescription)
                            {
                                groupItem["Notes"] = parsedGroupDescription;
                                groupItem.Update();
                                executeQuery = true;
                            }

                            var plainTextDescription = PnPHttpUtility.ConvertSimpleHtmlToText(parsedGroupDescription, int.MaxValue);
                            if (group.Description != plainTextDescription)
                            {
                                //If the description is more than 512 characters long a server exception will be thrown.
                                group.Description = plainTextDescription;
                                groupNeedsUpdate  = true;
                            }
                        }

                        if (group.AllowMembersEditMembership != siteGroup.AllowMembersEditMembership)
                        {
                            group.AllowMembersEditMembership = siteGroup.AllowMembersEditMembership;
                            groupNeedsUpdate = true;
                        }
                        if (group.AllowRequestToJoinLeave != siteGroup.AllowRequestToJoinLeave)
                        {
                            group.AllowRequestToJoinLeave = siteGroup.AllowRequestToJoinLeave;
                            groupNeedsUpdate = true;
                        }
                        if (group.AutoAcceptRequestToJoinLeave != siteGroup.AutoAcceptRequestToJoinLeave)
                        {
                            group.AutoAcceptRequestToJoinLeave = siteGroup.AutoAcceptRequestToJoinLeave;
                            groupNeedsUpdate = true;
                        }
                        if (group.OnlyAllowMembersViewMembership != siteGroup.OnlyAllowMembersViewMembership)
                        {
                            group.OnlyAllowMembersViewMembership = siteGroup.OnlyAllowMembersViewMembership;
                            groupNeedsUpdate = true;
                        }
                        if (!String.IsNullOrEmpty(group.RequestToJoinLeaveEmailSetting) && group.RequestToJoinLeaveEmailSetting != siteGroup.RequestToJoinLeaveEmailSetting)
                        {
                            group.RequestToJoinLeaveEmailSetting = siteGroup.RequestToJoinLeaveEmailSetting;
                            groupNeedsUpdate = true;
                        }
                        if (parsedGroupOwner != null && group.Owner.LoginName != parsedGroupOwner)
                        {
                            if (parsedGroupTitle != parsedGroupOwner)
                            {
                                Principal ownerPrincipal = allGroups.FirstOrDefault(gr => gr.LoginName.Equals(parsedGroupOwner, StringComparison.OrdinalIgnoreCase));
                                if (ownerPrincipal == null)
                                {
                                    ownerPrincipal = web.EnsureUser(parsedGroupOwner);
                                }
                                group.Owner = ownerPrincipal;
                            }
                            else
                            {
                                group.Owner = group;
                            }
                            groupNeedsUpdate = true;
                        }
                        if (groupNeedsUpdate)
                        {
                            scope.LogDebug("Updating existing group {0}", group.Title);
                            group.Update();
                            executeQuery = true;
                        }
                        if (executeQuery)
                        {
                            web.Context.ExecuteQueryRetry();
                        }
                    }
                    if (group != null && siteGroup.Members.Any())
                    {
                        AddUserToGroup(web, group, siteGroup.Members, scope, parser);
                    }
                }

                foreach (var admin in siteSecurity.AdditionalAdministrators)
                {
                    var parsedAdminName = parser.ParseString(admin.Name);
                    try
                    {
                        var user = web.EnsureUser(parsedAdminName);
                        user.IsSiteAdmin = true;
                        user.Update();
                        web.Context.ExecuteQueryRetry();
                    }
                    catch (Exception ex)
                    {
                        scope.LogWarning(ex, "Failed to add AdditionalAdministrator {0}", parsedAdminName);
                    }
                }

                // With the change from october, manage permission levels on subsites as well
                if (siteSecurity.SiteSecurityPermissions != null)
                {
                    var existingRoleDefinitions = web.Context.LoadQuery(web.RoleDefinitions.Include(wr => wr.Name, wr => wr.BasePermissions, wr => wr.Description));
                    web.Context.ExecuteQueryRetry();

                    if (siteSecurity.SiteSecurityPermissions.RoleDefinitions.Any())
                    {
                        foreach (var templateRoleDefinition in siteSecurity.SiteSecurityPermissions.RoleDefinitions)
                        {
                            var roleDefinitions                  = existingRoleDefinitions as RoleDefinition[] ?? existingRoleDefinitions.ToArray();
                            var parsedRoleDefinitionName         = parser.ParseString(templateRoleDefinition.Name);
                            var parsedTemplateRoleDefinitionDesc = parser.ParseString(templateRoleDefinition.Description);
                            var siteRoleDefinition               = roleDefinitions.FirstOrDefault(erd => erd.Name == parsedRoleDefinitionName);
                            if (siteRoleDefinition == null)
                            {
                                scope.LogDebug("Creating role definition {0}", parsedRoleDefinitionName);
                                var roleDefinitionCI = new RoleDefinitionCreationInformation();
                                roleDefinitionCI.Name        = parsedRoleDefinitionName;
                                roleDefinitionCI.Description = parsedTemplateRoleDefinitionDesc;
                                BasePermissions basePermissions = new BasePermissions();

                                foreach (var permission in templateRoleDefinition.Permissions)
                                {
                                    basePermissions.Set(permission);
                                }

                                roleDefinitionCI.BasePermissions = basePermissions;

                                var newRoleDefinition = web.RoleDefinitions.Add(roleDefinitionCI);
                                web.Context.Load(newRoleDefinition, nrd => nrd.Name, nrd => nrd.Id);
                                web.Context.ExecuteQueryRetry();
                                parser.AddToken(new RoleDefinitionIdToken(web, newRoleDefinition.Name, newRoleDefinition.Id));
                            }
                            else
                            {
                                var isDirty = false;
                                if (siteRoleDefinition.Description != parsedTemplateRoleDefinitionDesc)
                                {
                                    siteRoleDefinition.Description = parsedTemplateRoleDefinitionDesc;
                                    isDirty = true;
                                }
                                var templateBasePermissions = new BasePermissions();

                                // iterate over all possible PermissionKind values and set them on the new object
                                foreach (PermissionKind pk in Enum.GetValues(typeof(PermissionKind)))
                                {
                                    if (siteRoleDefinition.BasePermissions.Has(pk))
                                    {
                                        templateBasePermissions.Set(pk);
                                    }
                                }

                                // add the permissions that were specified in the template
                                templateRoleDefinition.Permissions.ForEach(p => templateBasePermissions.Set(p));

                                if (siteRoleDefinition.BasePermissions != templateBasePermissions)
                                {
                                    isDirty = true;
                                    siteRoleDefinition.BasePermissions = templateBasePermissions;
                                }

                                if (isDirty)
                                {
                                    scope.LogDebug("Updating role definition {0}", parsedRoleDefinitionName);
                                    siteRoleDefinition.Update();
                                    web.Context.ExecuteQueryRetry();
                                }
                            }
                        }
                    }

                    var webRoleDefinitions = web.Context.LoadQuery(web.RoleDefinitions);
                    var webRoleAssignments = web.Context.LoadQuery(web.RoleAssignments);
                    var groups             = web.Context.LoadQuery(web.SiteGroups.Include(g => g.LoginName));
                    web.Context.ExecuteQueryRetry();

                    if (siteSecurity.SiteSecurityPermissions.RoleAssignments.Any())
                    {
                        foreach (var roleAssignment in siteSecurity.SiteSecurityPermissions.RoleAssignments)
                        {
                            var parsedRoleDefinition = parser.ParseString(roleAssignment.RoleDefinition);
                            if (!roleAssignment.Remove)
                            {
                                var roleDefinition = webRoleDefinitions.FirstOrDefault(r => r.Name == parsedRoleDefinition);
                                if (roleDefinition != null)
                                {
                                    Principal principal = GetPrincipal(web, parser, scope, groups, roleAssignment);

                                    if (principal != null)
                                    {
                                        var roleDefinitionBindingCollection = new RoleDefinitionBindingCollection(web.Context);
                                        roleDefinitionBindingCollection.Add(roleDefinition);
                                        web.RoleAssignments.Add(principal, roleDefinitionBindingCollection);
                                        web.Context.ExecuteQueryRetry();
                                    }
                                }
                                else
                                {
                                    scope.LogWarning("Role assignment {0} not found in web", roleAssignment.RoleDefinition);
                                }
                            }
                            else
                            {
                                var principal = GetPrincipal(web, parser, scope, groups, roleAssignment);

                                if (principal != null)
                                {
                                    var assignmentsForPrincipal = webRoleAssignments.Where(t => t.PrincipalId == principal.Id);
                                    foreach (var assignmentForPrincipal in assignmentsForPrincipal)
                                    {
                                        var binding = assignmentForPrincipal.EnsureProperty(r => r.RoleDefinitionBindings).FirstOrDefault(b => b.Name == parsedRoleDefinition);
                                        if (binding != null)
                                        {
                                            assignmentForPrincipal.DeleteObject();
                                            web.Context.ExecuteQueryRetry();
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return(parser);
        }