public static string GetPeoplePickerSearchData()
 {
     using (var context = PnPPartnerPackContextProvider.GetAppOnlyClientContext(PnPPartnerPackSettings.InfrastructureSiteUrl))
     {
         return(GetPeoplePickerSearchData(context));
     }
 }
Пример #2
0
        public ActionResult GetTemplateImagePreviewFromPnP(String imagePreviewUri)
        {
            if (String.IsNullOrEmpty(imagePreviewUri))
            {
                throw new ArgumentNullException("imagePreviewUri");
            }

            // Recover the original protocol moniker
            var sourceUrl        = imagePreviewUri.Replace("pnps://", "https://").Replace("pnp://", "http://");
            var imagePreviewFile = sourceUrl.Substring(sourceUrl.LastIndexOf("/") + 1);
            var pnpFileUrl       = sourceUrl.Substring(0, sourceUrl.LastIndexOf("/"));
            var pnpFileName      = pnpFileUrl.Substring(pnpFileUrl.LastIndexOf("/") + 1);
            var sourceSiteUrl    = PnPPartnerPackUtilities.GetSiteCollectionRootUrl(pnpFileUrl);
            var sourceSiteFolder = pnpFileUrl.Substring(sourceSiteUrl.Length + 1, pnpFileUrl.LastIndexOf("/") - sourceSiteUrl.Length - 1);

            using (var repositoryContext = PnPPartnerPackContextProvider.GetAppOnlyClientContext(sourceSiteUrl))
            {
                var repositoryWeb = repositoryContext.Web;
                repositoryWeb.EnsureProperty(w => w.Url);

                XMLTemplateProvider provider = new XMLOpenXMLTemplateProvider(pnpFileName,
                                                                              new SharePointConnector(repositoryContext, repositoryWeb.Url, sourceSiteFolder));

                var imageFileStream = provider.Connector.GetFileStream(imagePreviewFile);

                return(base.File(imageFileStream, "image/png"));
            }
        }
Пример #3
0
        public ActionResult Index()
        {
            IndexViewModel model = new IndexViewModel();

            using (var ctx = PnPPartnerPackContextProvider.GetAppOnlyClientContext(PnPPartnerPackSettings.InfrastructureSiteUrl))
            {
                // Track usage of the PnP Partner Pack
                ctx.ClientTag = "SPDev:PartnerPack";

                Web web = ctx.Web;
                ctx.Load(web, w => w.Title, w => w.Url);
                ctx.ExecuteQuery();

                model.InfrastructuralSiteUrl = web.Url;
            }

            var currentUser = UserUtility.GetCurrentUser();

            if (currentUser != null)
            {
                model.CurrentUserPrincipalName = currentUser.UserPrincipalName;
            }
            else
            {
                model.CurrentUserPrincipalName = ClaimsPrincipal.Current.Identity.Name;
            }

            return(View(model));
        }
        private void UpdateTemplates(RefreshSitesJob job)
        {
            // For each Site Collection in the tenant
            using (var adminContext = PnPPartnerPackContextProvider.GetAppOnlyTenantLevelClientContext())
            {
                var tenant = new Tenant(adminContext);

                var siteCollections = tenant.GetSiteProperties(0, true);
                adminContext.Load(siteCollections);
                adminContext.ExecuteQueryRetry();

                foreach (var site in siteCollections)
                {
                    // Exclude Microsoft NextGen Portals
                    if (!site.Url.ToLower().Contains("/portals/") 
                        && !site.Url.ToLower().Contains("-public.sharepoint.com") 
                        && !site.Url.ToLower().Contains("-my.sharepoint.com"))
                    {
                        using (var siteContext = PnPPartnerPackContextProvider.GetAppOnlyClientContext(site.Url))
                        {
                            // Get a reference to the target web
                            var targetWeb = siteContext.Site.RootWeb;

                            // Update the root web of the site collection
                            RefreshSitesJobHandler.UpdateTemplateOnWeb(targetWeb, job);
                        }
                    }
                }
            }
        }
 /// <summary>
 /// Saves a Provisioning Template into the target Global repository
 /// </summary>
 /// <param name="job">The Provisioning Template to save</param>
 public void SaveGlobalProvisioningTemplate(GetProvisioningTemplateJob job)
 {
     // Connect to the Infrastructural Site Collection
     using (var context = PnPPartnerPackContextProvider.GetAppOnlyClientContext(job.SourceSiteUrl))
     {
         SaveProvisioningTemplateInternal(context, job, true);
     }
 }
 /// <summary>
 /// Saves a Provisioning Template into the target Local repository
 /// </summary>
 /// <param name="siteUrl">The local Site Collection to save to</param>
 /// <param name="template">The Provisioning Template to save</param>
 public void SaveLocalProvisioningTemplate(string siteUrl, GetProvisioningTemplateJob job)
 {
     // Connect to the Local Site Collection
     using (var context = PnPPartnerPackContextProvider.GetAppOnlyClientContext(siteUrl))
     {
         PnPPartnerPackUtilities.EnablePartnerPackInfrastructureOnSite(siteUrl);
         SaveProvisioningTemplateInternal(context, job, false);
     }
 }
Пример #7
0
        public ActionResult SaveSiteAsTemplate(SaveTemplateViewModel model, HttpPostedFileBase templateImageFile)
        {
            AntiForgery.Validate();
            if (ModelState.IsValid)
            {
                // Prepare the Job to store the Provisioning Template
                GetProvisioningTemplateJob job = new GetProvisioningTemplateJob();

                // Store the local location for the Provisioning Template, if any
                String storageLocationUrl = null;

                // Determine the Scope of the Provisioning Template
                using (var ctx = PnPPartnerPackContextProvider.GetAppOnlyClientContext(model.SourceSiteUrl))
                {
                    Web web     = ctx.Web;
                    Web rootWeb = ctx.Site.RootWeb;
                    ctx.Load(web, w => w.Id);
                    ctx.Load(rootWeb, w => w.Url, w => w.Id);
                    ctx.ExecuteQueryRetry();

                    if (web.Id == rootWeb.Id)
                    {
                        // We are in the Root Site of the Site Collection
                        job.Scope          = TemplateScope.Site;
                        storageLocationUrl = rootWeb.Url;
                    }
                    else
                    {
                        // Otherwise we are in a Sub Site of the Site Collection
                        job.Scope = TemplateScope.Web;
                    }
                }

                // Prepare all the other information about the Provisioning Job
                job.Owner                          = ClaimsPrincipal.Current.Identity.Name;
                job.FileName                       = model.FileName;
                job.IncludeAllTermGroups           = model.IncludeAllTermGroups;
                job.IncludeSearchConfiguration     = model.IncludeSearchConfiguration;
                job.IncludeSiteCollectionTermGroup = model.IncludeSiteCollectionTermGroup;
                job.IncludeSiteGroups              = model.IncludeSiteGroups;
                job.PersistComposedLookFiles       = model.PersistComposedLookFiles;
                job.SourceSiteUrl                  = model.SourceSiteUrl;
                job.Title                          = model.Title;
                job.Description                    = model.Description;
                job.Location                       = (ProvisioningTemplateLocation)Enum.Parse(typeof(ProvisioningTemplateLocation), model.Location, true);
                job.StorageSiteLocationUrl         = storageLocationUrl;
                if (templateImageFile != null && templateImageFile.ContentLength > 0)
                {
                    job.TemplateImageFile     = templateImageFile.InputStream.FixedSizeImageStream(320, 180).ToByteArray();
                    job.TemplateImageFileName = templateImageFile.FileName;
                }

                model.JobId = ProvisioningRepositoryFactory.Current.EnqueueProvisioningJob(job);
            }

            return(View(model));
        }
        public void UpdateProvisioningJob(Guid jobId, ProvisioningJobStatus status, String errorMessage = null)
        {
            // Connect to the Infrastructural Site Collection
            using (var context = PnPPartnerPackContextProvider.GetAppOnlyClientContext(PnPPartnerPackSettings.InfrastructureSiteUrl))
            {
                // Get a reference to the target library
                Web  web  = context.Web;
                List list = web.Lists.GetByTitle(PnPPartnerPackConstants.PnPProvisioningJobs);
                context.Load(list, l => l.RootFolder);

                CamlQuery query = new CamlQuery();
                query.ViewXml =
                    @"<View>
                        <Query>
                            <Where>
                                <Eq>
                                    <FieldRef Name='FileLeafRef' />
                                    <Value Type='Text'>" + jobId + @".job</Value>
                                </Eq>
                            </Where>
                        </Query>
                    </View>";

                ListItemCollection items = list.GetItems(query);
                context.Load(items,
                             includes => includes.IncludeWithDefaultProperties(
                                 j => j[PnPPartnerPackConstants.PnPProvisioningJobStatus],
                                 j => j[PnPPartnerPackConstants.PnPProvisioningJobError],
                                 j => j[PnPPartnerPackConstants.PnPProvisioningJobType]),
                             includes => includes.Include(j => j.File));
                context.ExecuteQueryRetry();

                if (items.Count > 0)
                {
                    ListItem jobItem = items[0];

                    // Update the ProvisioningJob object internal status
                    ProvisioningJob job = GetProvisioningJobStreamFromSharePoint(context, jobItem)
                                          .FromJsonStream((String)jobItem[PnPPartnerPackConstants.PnPProvisioningJobType]);

                    job.Status       = status;
                    job.ErrorMessage = errorMessage;

                    // Update the SharePoint ListItem behind the Provisioning Job item
                    // jobItem[PnPPartnerPackConstants.ContentTypeIdField] = PnPPartnerPackConstants.PnPProvisioningJobContentTypeId;
                    jobItem[PnPPartnerPackConstants.PnPProvisioningJobStatus] = status.ToString();
                    jobItem[PnPPartnerPackConstants.PnPProvisioningJobError]  = errorMessage;

                    jobItem.Update();
                    context.ExecuteQueryRetry();

                    // Update the file
                    list.RootFolder.UploadFile(jobItem.File.Name, job.ToJsonStream(), true);
                }
            }
        }
Пример #9
0
        private void UpdateTemplates(RefreshSingleSiteJob job)
        {
            using (var siteContext = PnPPartnerPackContextProvider.GetAppOnlyClientContext(job.TargetSiteUrl))
            {
                // Get a reference to the target web
                var targetWeb = siteContext.Site.RootWeb;

                // Update the root web of the site collection
                RefreshSitesJobHandler.UpdateTemplateOnWeb(targetWeb);
            }
        }
Пример #10
0
        public ActionResult Index()
        {
            IndexViewModel model = new IndexViewModel();

            model.CurrentUserPrincipalName = ClaimsPrincipal.Current.Identity.Name;

            using (var ctx = PnPPartnerPackContextProvider.GetAppOnlyClientContext(PnPPartnerPackSettings.InfrastructureSiteUrl))
            {
                Web web = ctx.Web;
                ctx.Load(web, w => w.Title, w => w.Url);
                ctx.ExecuteQueryRetry();

                model.InfrastructuralSiteUrl = web.Url;
            }

            return(View(model));
        }
        public virtual ProvisioningTemplate GetProvisioningTemplate(string templateUri)
        {
            // Connect to the target Templates Site Collection
            using (var context = PnPPartnerPackContextProvider.GetAppOnlyClientContext(TemplatesSiteUrl))
            {
                // Get a reference to the target library
                Web web = context.Web;

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

                var templateRelativePath = templateUri.Substring(templateUri.LastIndexOf("/") + 1);

                // Configure the SharePoint Connector
                var sharepointConnector = new SharePointConnector(context, web.Url,
                                                                  PnPPartnerPackConstants.PnPProvisioningTemplates);

                TemplateProviderBase provider = null;
                // If the target is a .PNP Open XML template
                if (templateRelativePath.ToLower().EndsWith(".pnp"))
                {
                    // Configure the Open XML provider for SharePoint
                    provider =
                        new XMLOpenXMLTemplateProvider(
                            new OpenXMLConnector(templateRelativePath, sharepointConnector));
                }
                else
                {
                    // Otherwise use the .XML template provider for SharePoint
                    provider =
                        new XMLSharePointTemplateProvider(context, web.Url,
                                                          PnPPartnerPackConstants.PnPProvisioningTemplates);
                }

                // Determine the name of the XML file inside the PNP Open XML file, if any
                var xmlTemplateFile = templateRelativePath.ToLower().Replace(".pnp", ".xml");

                // Get the template
                ProvisioningTemplate template = provider.GetTemplate(xmlTemplateFile);
                template.Connector = provider.Connector;

                return(template);
            }
        }
Пример #12
0
        private void ApplyBranding(BrandingJob job)
        {
            // Use the infrastructural site collection to temporary store the template with color palette and font files
            using (var repositoryContext = PnPPartnerPackContextProvider.GetAppOnlyClientContext(
                       PnPPartnerPackSettings.InfrastructureSiteUrl))
            {
                var brandingSettings          = PnPPartnerPackUtilities.GetTenantBrandingSettings();
                ProvisioningTemplate template = PrepareBrandingTemplate(repositoryContext, brandingSettings);

                // For each Site Collection in the tenant
                using (var adminContext = PnPPartnerPackContextProvider.GetAppOnlyTenantLevelClientContext())
                {
                    var tenant = new Tenant(adminContext);

                    var siteCollections = tenant.GetSiteProperties(0, true);
                    adminContext.Load(siteCollections);
                    adminContext.ExecuteQueryRetry();

                    foreach (var site in siteCollections)
                    {
                        if (!site.Url.ToLower().Contains("/portals/") &&
                            !site.Url.ToLower().Contains("-public.sharepoint.com") &&
                            !site.Url.ToLower().Contains("-my.sharepoint.com"))
                        {
                            // Clean-up the template
                            template.WebSettings.MasterPageUrl = null;

                            using (var siteContext = PnPPartnerPackContextProvider.GetAppOnlyClientContext(site.Url))
                            {
                                // Get a reference to the target web
                                var targetWeb = siteContext.Site.RootWeb;

                                // Update the root web of the site collection
                                ApplyBrandingOnWeb(targetWeb, brandingSettings, template);
                            }
                        }
                    }
                }
            }
        }
        public ProvisioningJobInformation GetProvisioningJob(Guid jobId, Boolean includeStream = false)
        {
            // Connect to the Infrastructural Site Collection
            using (var context = PnPPartnerPackContextProvider.GetAppOnlyClientContext(PnPPartnerPackSettings.InfrastructureSiteUrl))
            {
                // Get a reference to the target library
                Web  web  = context.Web;
                List list = web.Lists.GetByTitle(PnPPartnerPackConstants.PnPProvisioningJobs);

                CamlQuery query = new CamlQuery();
                query.ViewXml =
                    @"<View>
                        <Query>
                            <Where>
                                <Eq>
                                    <FieldRef Name='FileLeafRef' />
                                    <Value Type='Text'>" + jobId.ToString("D") + @".job</Value>
                                </Eq>
                            </Where>
                        </Query>
                    </View>";

                ListItemCollection items = list.GetItems(query);
                context.Load(items);
                context.ExecuteQueryRetry();

                if (items.Count > 0)
                {
                    ListItem jobItem = items[0];
                    return(PrepareJobInformationFromSharePoint(context, jobItem, includeStream));
                }
                else
                {
                    return(null);
                }
            }
        }
Пример #14
0
        public ActionResult Settings()
        {
            SettingsViewModel model = new SettingsViewModel();

            using (var adminContext = PnPPartnerPackContextProvider.GetAppOnlyTenantLevelClientContext())
            {
                var tenant = new Tenant(adminContext);

                // TODO: Here we could add paging capabilities
                var siteCollections = tenant.GetSiteProperties(0, true);
                adminContext.Load(siteCollections);
                adminContext.ExecuteQueryRetry();

                model.SiteCollections =
                    (from site in siteCollections
                     select new SiteCollectionSettings {
                    Title = site.Title,
                    Url = site.Url,
                    PnPPartnerPackEnabled = false,      // PnPPartnerPackUtilities.IsPartnerPackEnabledOnSite(site.Url),
                }).ToArray();
            }

            return(View(model));
        }
Пример #15
0
        private void CreateSiteCollection(SiteCollectionProvisioningJob job)
        {
            Console.WriteLine("Creating Site Collection \"{0}\".", job.RelativeUrl);

            // Define the full Site Collection URL
            String siteUrl = String.Format("{0}{1}",
                                           PnPPartnerPackSettings.InfrastructureSiteUrl.Substring(0, PnPPartnerPackSettings.InfrastructureSiteUrl.IndexOf("sharepoint.com/") + 14),
                                           job.RelativeUrl);

            using (var adminContext = PnPPartnerPackContextProvider.GetAppOnlyTenantLevelClientContext())
            {
                adminContext.RequestTimeout = Timeout.Infinite;

                // Configure the Site Collection properties
                SiteEntity newSite = new SiteEntity();
                newSite.Description          = job.Description;
                newSite.Lcid                 = (uint)job.Language;
                newSite.Title                = job.SiteTitle;
                newSite.Url                  = siteUrl;
                newSite.SiteOwnerLogin       = job.PrimarySiteCollectionAdmin;
                newSite.StorageMaximumLevel  = job.StorageMaximumLevel;
                newSite.StorageWarningLevel  = job.StorageWarningLevel;
                newSite.Template             = PnPPartnerPackSettings.DefaultSiteTemplate;
                newSite.TimeZoneId           = job.TimeZone;
                newSite.UserCodeMaximumLevel = job.UserCodeMaximumLevel;
                newSite.UserCodeWarningLevel = job.UserCodeWarningLevel;

                // Create the Site Collection and wait for its creation (we're asynchronous)
                var tenant = new Tenant(adminContext);
                tenant.CreateSiteCollection(newSite, true, true); // TODO: Do we want to empty Recycle Bin?

                Site site = tenant.GetSiteByUrl(siteUrl);
                Web  web  = site.RootWeb;

                adminContext.Load(site, s => s.Url);
                adminContext.Load(web, w => w.Url);
                adminContext.ExecuteQueryRetry();

                // Enable Secondary Site Collection Administrator
                if (!String.IsNullOrEmpty(job.SecondarySiteCollectionAdmin))
                {
                    Microsoft.SharePoint.Client.User secondaryOwner = web.EnsureUser(job.SecondarySiteCollectionAdmin);
                    secondaryOwner.IsSiteAdmin = true;
                    secondaryOwner.Update();

                    web.SiteUsers.AddUser(secondaryOwner);
                    adminContext.ExecuteQueryRetry();
                }

                Console.WriteLine("Site \"{0}\" created.", site.Url);

                // Check if external sharing has to be enabled
                if (job.ExternalSharingEnabled)
                {
                    EnableExternalSharing(tenant, site);

                    // Enable External Sharing
                    Console.WriteLine("Enabled External Sharing for site \"{0}\".",
                                      site.Url);
                }
            }

            // Move to the context of the created Site Collection
            using (ClientContext clientContext = PnPPartnerPackContextProvider.GetAppOnlyClientContext(siteUrl))
            {
                Site site = clientContext.Site;
                Web  web  = site.RootWeb;

                clientContext.Load(site, s => s.Url);
                clientContext.Load(web, w => w.Url);
                clientContext.ExecuteQueryRetry();

                // Check if we need to enable PnP Partner Pack overrides
                if (job.PartnerPackExtensionsEnabled)
                {
                    // Enable Responsive Design
                    PnPPartnerPackUtilities.EnablePartnerPackOnSite(site.Url);

                    Console.WriteLine("Enabled PnP Partner Pack Overrides on site \"{0}\".",
                                      site.Url);
                }

                // Check if the site has to be responsive
                if (job.ResponsiveDesignEnabled)
                {
                    // Enable Responsive Design
                    PnPPartnerPackUtilities.EnableResponsiveDesignOnSite(site.Url);

                    Console.WriteLine("Enabled Responsive Design Template to site \"{0}\".",
                                      site.Url);
                }

                // Apply the Provisioning Template
                Console.WriteLine("Applying Provisioning Template \"{0}\" to site.",
                                  job.ProvisioningTemplateUrl);

                // Determine the reference URLs and file names
                String templatesSiteUrl = PnPPartnerPackUtilities.GetSiteCollectionRootUrl(job.ProvisioningTemplateUrl);
                String templateFileName = job.ProvisioningTemplateUrl.Substring(job.ProvisioningTemplateUrl.LastIndexOf("/") + 1);

                using (ClientContext repositoryContext = PnPPartnerPackContextProvider.GetAppOnlyClientContext(templatesSiteUrl))
                {
                    // Configure the XML file system provider
                    XMLTemplateProvider provider =
                        new XMLSharePointTemplateProvider(
                            repositoryContext,
                            templatesSiteUrl,
                            PnPPartnerPackConstants.PnPProvisioningTemplates);

                    // Load the template from the XML stored copy
                    ProvisioningTemplate template = provider.GetTemplate(templateFileName);
                    template.Connector = provider.Connector;

                    // We do intentionally remove taxonomies, which are not supported
                    // in the AppOnly Authorization model
                    // For further details, see the PnP Partner Pack documentation
                    ProvisioningTemplateApplyingInformation ptai =
                        new ProvisioningTemplateApplyingInformation();

                    // Write provisioning steps on console log
                    ptai.MessagesDelegate += delegate(string message, ProvisioningMessageType messageType) {
                        Console.WriteLine("{0} - {1}", messageType, messageType);
                    };
                    ptai.ProgressDelegate += delegate(string message, int step, int total) {
                        Console.WriteLine("{0:00}/{1:00} - {2}", step, total, message);
                    };

                    ptai.HandlersToProcess ^=
                        OfficeDevPnP.Core.Framework.Provisioning.Model.Handlers.TermGroups;

                    // Configure template parameters
                    if (job.TemplateParameters != null)
                    {
                        foreach (var key in job.TemplateParameters.Keys)
                        {
                            if (job.TemplateParameters.ContainsKey(key))
                            {
                                template.Parameters[key] = job.TemplateParameters[key];
                            }
                        }
                    }

                    web.ApplyProvisioningTemplate(template, ptai);
                }

                Console.WriteLine("Applyed Provisioning Template \"{0}\" to site.",
                                  job.ProvisioningTemplateUrl);
            }
        }
Пример #16
0
        public ActionResult CreateSubSite(CreateSubSiteViewModel model)
        {
            PnPPartnerPackSettings.ParentSiteUrl = model.ParentSiteUrl;

            if (model.Step == CreateSiteStep.SiteInformation)
            {
                ModelState.Clear();

                // If it is the first time that we are here
                if (String.IsNullOrEmpty(model.Title))
                {
                    model.InheritPermissions = true;
                    using (var ctx = PnPPartnerPackContextProvider.GetAppOnlyClientContext(model.ParentSiteUrl))
                    {
                        Web web = ctx.Web;
                        ctx.Load(web, w => w.Language, w => w.RegionalSettings.TimeZone);
                        ctx.ExecuteQueryRetry();

                        model.Language = (Int32)web.Language;
                        model.TimeZone = web.RegionalSettings.TimeZone.Id;
                    }
                }
            }
            if (model.Step == CreateSiteStep.TemplateParameters)
            {
                if (!ModelState.IsValid)
                {
                    model.Step = CreateSiteStep.SiteInformation;
                }
                else
                {
                    if (!String.IsNullOrEmpty(model.ProvisioningTemplateUrl) &&
                        !String.IsNullOrEmpty(model.TemplatesProviderTypeName))
                    {
                        var templatesProvider = PnPPartnerPackSettings.TemplatesProviders[model.TemplatesProviderTypeName];
                        if (templatesProvider != null)
                        {
                            var template = templatesProvider.GetProvisioningTemplate(model.ProvisioningTemplateUrl);
                            model.TemplateParameters = template.Parameters;
                        }

                        if (model.TemplateParameters == null || model.TemplateParameters.Count == 0)
                        {
                            model.Step = CreateSiteStep.SiteCreated;
                        }
                    }
                }
            }
            if (model.Step == CreateSiteStep.SiteCreated)
            {
                AntiForgery.Validate();
                if (ModelState.IsValid)
                {
                    // Prepare the Job to provision the Sub Site
                    SubSiteProvisioningJob job = new SubSiteProvisioningJob();

                    // Prepare all the other information about the Provisioning Job
                    job.SiteTitle           = model.Title;
                    job.Description         = model.Description;
                    job.Language            = model.Language;
                    job.TimeZone            = model.TimeZone;
                    job.ParentSiteUrl       = model.ParentSiteUrl;
                    job.RelativeUrl         = model.RelativeUrl;
                    job.SitePolicy          = model.SitePolicy;
                    job.Owner               = ClaimsPrincipal.Current.Identity.Name;
                    job.ApplyTenantBranding = model.ApplyTenantBranding;

                    job.ProvisioningTemplateUrl   = model.ProvisioningTemplateUrl;
                    job.TemplatesProviderTypeName = model.TemplatesProviderTypeName;
                    job.InheritPermissions        = model.InheritPermissions;
                    job.Title = String.Format("Provisioning of Sub Site \"{1}\" with Template \"{0}\" by {2}",
                                              job.ProvisioningTemplateUrl,
                                              job.RelativeUrl,
                                              job.Owner);

                    job.TemplateParameters = model.TemplateParameters;

                    model.JobId = ProvisioningRepositoryFactory.Current.EnqueueProvisioningJob(job);
                }
            }

            return(PartialView(model.Step.ToString(), model));
        }
        public ProvisioningTemplateInformation[] GetLocalProvisioningTemplates(string siteUrl, TemplateScope scope)
        {
            List <ProvisioningTemplateInformation> result =
                new List <ProvisioningTemplateInformation>();

            // Retrieve the Root Site Collection URL
            siteUrl = PnPPartnerPackUtilities.GetSiteCollectionRootUrl(siteUrl);

            // Connect to the Infrastructural Site Collection
            using (var context = PnPPartnerPackContextProvider.GetAppOnlyClientContext(siteUrl))
            {
                // Get a reference to the target library
                Web web = context.Web;

                try
                {
                    List list = web.Lists.GetByTitle(PnPPartnerPackConstants.PnPProvisioningTemplates);

                    // Get only Provisioning Templates documents with the specified Scope
                    CamlQuery query = new CamlQuery();
                    query.ViewXml =
                        @"<View>
                        <Query>
                            <Where>
                                <And>
                                    <Eq>
                                        <FieldRef Name='PnPProvisioningTemplateScope' />
                                        <Value Type='Choice'>" + scope.ToString() + @"</Value>
                                    </Eq>
                                    <Eq>
                                        <FieldRef Name='ContentType' />
                                        <Value Type=''Computed''>PnPProvisioningTemplate</Value>
                                    </Eq>
                                </And>
                            </Where>
                        </Query>
                        <ViewFields>
                            <FieldRef Name='Title' />
                            <FieldRef Name='PnPProvisioningTemplateScope' />
                            <FieldRef Name='PnPProvisioningTemplateSourceUrl' />
                        </ViewFields>
                    </View>";

                    ListItemCollection items = list.GetItems(query);
                    context.Load(items,
                                 includes => includes.Include(i => i.File,
                                                              i => i[PnPPartnerPackConstants.PnPProvisioningTemplateScope],
                                                              i => i[PnPPartnerPackConstants.PnPProvisioningTemplateSourceUrl]));
                    context.ExecuteQueryRetry();

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

                    foreach (ListItem item in items)
                    {
                        // Configure the XML file system provider
                        XMLTemplateProvider provider =
                            new XMLSharePointTemplateProvider(context, web.Url,
                                                              PnPPartnerPackConstants.PnPProvisioningTemplates);

                        item.File.EnsureProperties(f => f.Name, f => f.ServerRelativeUrl);

                        ProvisioningTemplate template = provider.GetTemplate(item.File.Name);

                        result.Add(new ProvisioningTemplateInformation
                        {
                            Scope             = (TemplateScope)Enum.Parse(typeof(TemplateScope), (String)item[PnPPartnerPackConstants.PnPProvisioningTemplateScope], true),
                            TemplateSourceUrl = item[PnPPartnerPackConstants.PnPProvisioningTemplateSourceUrl] != null ? ((FieldUrlValue)item[PnPPartnerPackConstants.PnPProvisioningTemplateSourceUrl]).Url : null,
                            TemplateFileUri   = String.Format("{0}/{1}/{2}", web.Url, PnPPartnerPackConstants.PnPProvisioningTemplates, item.File.Name),
                            TemplateImageUrl  = template.ImagePreviewUrl,
                            DisplayName       = template.DisplayName,
                            Description       = template.Description,
                        });
                    }
                }
                catch (ServerException ex)
                {
                    // In case of any issue, ignore the local templates
                }
            }

            return(result.ToArray());
        }
        public ProvisioningJobInformation[] GetProvisioningJobs(ProvisioningJobStatus status, String jobType = null, Boolean includeStream = false, string owner = null)
        {
            List <ProvisioningJobInformation> result = new List <ProvisioningJobInformation>();

            // Connect to the Infrastructural Site Collection
            using (var context = PnPPartnerPackContextProvider.GetAppOnlyClientContext(PnPPartnerPackSettings.InfrastructureSiteUrl))
            {
                // Get a reference to the target library
                Web  web  = context.Web;
                List list = web.Lists.GetByTitle(PnPPartnerPackConstants.PnPProvisioningJobs);

                StringBuilder sbCamlWhere = new StringBuilder();

                // Generate the CAML query filter accordingly to the requested statuses
                Boolean openCamlOr       = true;
                Int32   conditionCounter = 0;
                foreach (var statusFlagName in Enum.GetNames(typeof(ProvisioningJobStatus)))
                {
                    var statusFlag = (ProvisioningJobStatus)Enum.Parse(typeof(ProvisioningJobStatus), statusFlagName);
                    if ((statusFlag & status) == statusFlag)
                    {
                        conditionCounter++;
                        if (openCamlOr)
                        {
                            // Add the first <Or /> CAML statement
                            sbCamlWhere.Insert(0, "<Or>");
                            openCamlOr = false;
                        }
                        sbCamlWhere.AppendFormat(
                            @"<Eq>
                                <FieldRef Name='PnPProvisioningJobStatus' />
                                <Value Type='Text'>" + statusFlagName + @"</Value>
                            </Eq>");

                        if (conditionCounter >= 2)
                        {
                            // Close the current <Or /> CAML statement
                            sbCamlWhere.Append("</Or>");
                            openCamlOr = true;
                        }
                    }
                }
                // Remove the first <Or> CAML statement if it is useless
                if (conditionCounter == 1)
                {
                    sbCamlWhere.Remove(0, 4);
                }

                // Add the jobType filter, if any
                if (!String.IsNullOrEmpty(jobType))
                {
                    sbCamlWhere.Insert(0, "<And>");
                    sbCamlWhere.AppendFormat(
                        @"<Eq>
                        <FieldRef Name='PnPProvisioningJobType' />
                        <Value Type='Text'>" + jobType + @"</Value>
                    </Eq>");
                    sbCamlWhere.Append("</And>");
                }

                // Add the owner filter, if any
                if (!String.IsNullOrEmpty(owner))
                {
                    Microsoft.SharePoint.Client.User ownerUser = web.EnsureUser(owner);
                    context.Load(ownerUser, u => u.Id, u => u.Email, u => u.Title);
                    context.ExecuteQueryRetry();

                    sbCamlWhere.Insert(0, "<And>");
                    sbCamlWhere.AppendFormat(
                        @"<Eq>
                        <FieldRef Name='PnPProvisioningJobOwner' />
                        <Value Type='User'>" + ownerUser.Title + @"</Value>
                    </Eq>");
                    sbCamlWhere.Append("</And>");
                }

                CamlQuery query = new CamlQuery();
                query.ViewXml =
                    @"<View>
                        <Query>
                            <Where>" + sbCamlWhere.ToString() + @"
                            </Where>
                        </Query>
                    </View>";

                ListItemCollection items = list.GetItems(query);
                context.Load(items);
                context.ExecuteQueryRetry();

                foreach (var jobItem in items)
                {
                    result.Add(PrepareJobInformationFromSharePoint(context, jobItem, includeStream));
                }
            }
            return(result.ToArray());
        }
Пример #19
0
        public ActionResult CreateSubSite(CreateSubSiteViewModel model)
        {
            switch (model.Step)
            {
            case CreateSiteStep.SiteInformation:
                ModelState.Clear();

                // If it is the first time that we are here
                if (String.IsNullOrEmpty(model.Title))
                {
                    model.InheritPermissions = true;
                    using (var ctx = PnPPartnerPackContextProvider.GetAppOnlyClientContext(model.ParentSiteUrl))
                    {
                        Web web = ctx.Web;
                        ctx.Load(web, w => w.Language, w => w.RegionalSettings.TimeZone);
                        ctx.ExecuteQueryRetry();

                        model.Language = (Int32)web.Language;
                        model.TimeZone = web.RegionalSettings.TimeZone.Id;
                    }
                }
                break;

            case CreateSiteStep.TemplateParameters:
                if (!ModelState.IsValid)
                {
                    model.Step = CreateSiteStep.SiteInformation;
                }
                else
                {
                    if (!String.IsNullOrEmpty(model.ProvisioningTemplateUrl) &&
                        model.ProvisioningTemplateUrl.IndexOf(PnPPartnerPackConstants.PnPProvisioningTemplates) > 0)
                    {
                        String templateSiteUrl  = model.ProvisioningTemplateUrl.Substring(0, model.ProvisioningTemplateUrl.IndexOf(PnPPartnerPackConstants.PnPProvisioningTemplates));
                        String templateFileName = model.ProvisioningTemplateUrl.Substring(model.ProvisioningTemplateUrl.IndexOf(PnPPartnerPackConstants.PnPProvisioningTemplates) + PnPPartnerPackConstants.PnPProvisioningTemplates.Length + 1);
                        String templateFolder   = String.Empty;

                        if (templateFileName.IndexOf("/") > 0)
                        {
                            templateFolder   = templateFileName.Substring(0, templateFileName.LastIndexOf("/") - 1);
                            templateFileName = templateFileName.Substring(templateFolder.Length + 1);
                        }
                        model.TemplateParameters = PnPPartnerPackUtilities.GetProvisioningTemplateParameters(
                            templateSiteUrl,
                            templateFolder,
                            templateFileName);
                    }
                }
                break;

            case CreateSiteStep.SiteCreated:
                AntiForgery.Validate();
                if (ModelState.IsValid)
                {
                    // Prepare the Job to provision the Sub Site
                    SubSiteProvisioningJob job = new SubSiteProvisioningJob();

                    // Prepare all the other information about the Provisioning Job
                    job.SiteTitle               = model.Title;
                    job.Description             = model.Description;
                    job.Language                = model.Language;
                    job.TimeZone                = model.TimeZone;
                    job.ParentSiteUrl           = model.ParentSiteUrl;
                    job.RelativeUrl             = model.RelativeUrl;
                    job.SitePolicy              = model.SitePolicy;
                    job.Owner                   = ClaimsPrincipal.Current.Identity.Name;
                    job.ProvisioningTemplateUrl = model.ProvisioningTemplateUrl;
                    job.InheritPermissions      = model.InheritPermissions;
                    job.Title                   = String.Format("Provisioning of Sub Site \"{1}\" with Template \"{0}\" by {2}",
                                                                job.ProvisioningTemplateUrl,
                                                                job.RelativeUrl,
                                                                job.Owner);

                    job.TemplateParameters = model.TemplateParameters;

                    model.JobId = ProvisioningRepositoryFactory.Current.EnqueueProvisioningJob(job);
                }
                break;

            default:
                break;
            }

            return(PartialView(model.Step.ToString(), model));
        }
        private void CreateSiteCollection(SiteCollectionProvisioningJob job)
        {
            Console.WriteLine("Creating Site Collection \"{0}\".", job.RelativeUrl);

            // Define the full Site Collection URL
            String siteUrl = String.Format("{0}{1}",
                                           PnPPartnerPackSettings.InfrastructureSiteUrl.Substring(0, PnPPartnerPackSettings.InfrastructureSiteUrl.IndexOf("sharepoint.com/") + 14),
                                           job.RelativeUrl);

            // Load the template from the source Templates Provider
            if (!String.IsNullOrEmpty(job.TemplatesProviderTypeName))
            {
                ProvisioningTemplate template = null;

                var templatesProvider = PnPPartnerPackSettings.TemplatesProviders[job.TemplatesProviderTypeName];
                if (templatesProvider != null)
                {
                    template = templatesProvider.GetProvisioningTemplate(job.ProvisioningTemplateUrl);
                }

                if (template != null)
                {
                    using (var adminContext = PnPPartnerPackContextProvider.GetAppOnlyTenantLevelClientContext())
                    {
                        adminContext.RequestTimeout = Timeout.Infinite;

                        // Configure the Site Collection properties
                        SiteEntity newSite = new SiteEntity();
                        newSite.Description         = job.Description;
                        newSite.Lcid                = (uint)job.Language;
                        newSite.Title               = job.SiteTitle;
                        newSite.Url                 = siteUrl;
                        newSite.SiteOwnerLogin      = job.PrimarySiteCollectionAdmin;
                        newSite.StorageMaximumLevel = job.StorageMaximumLevel;
                        newSite.StorageWarningLevel = job.StorageWarningLevel;

                        // Use the BaseSiteTemplate of the template, if any, otherwise
                        // fallback to the pre-configured site template (i.e. STS#0)
                        newSite.Template = !String.IsNullOrEmpty(template.BaseSiteTemplate) ?
                                           template.BaseSiteTemplate :
                                           PnPPartnerPackSettings.DefaultSiteTemplate;

                        newSite.TimeZoneId           = job.TimeZone;
                        newSite.UserCodeMaximumLevel = job.UserCodeMaximumLevel;
                        newSite.UserCodeWarningLevel = job.UserCodeWarningLevel;

                        // Create the Site Collection and wait for its creation (we're asynchronous)
                        var tenant = new Tenant(adminContext);
                        tenant.CreateSiteCollection(newSite, true, true); // TODO: Do we want to empty Recycle Bin?

                        Site site = tenant.GetSiteByUrl(siteUrl);
                        Web  web  = site.RootWeb;

                        adminContext.Load(site, s => s.Url);
                        adminContext.Load(web, w => w.Url);
                        adminContext.ExecuteQueryRetry();

                        // Enable Secondary Site Collection Administrator
                        if (!String.IsNullOrEmpty(job.SecondarySiteCollectionAdmin))
                        {
                            Microsoft.SharePoint.Client.User secondaryOwner = web.EnsureUser(job.SecondarySiteCollectionAdmin);
                            secondaryOwner.IsSiteAdmin = true;
                            secondaryOwner.Update();

                            web.SiteUsers.AddUser(secondaryOwner);
                            adminContext.ExecuteQueryRetry();
                        }

                        Console.WriteLine("Site \"{0}\" created.", site.Url);

                        // Check if external sharing has to be enabled
                        if (job.ExternalSharingEnabled)
                        {
                            EnableExternalSharing(tenant, site);

                            // Enable External Sharing
                            Console.WriteLine("Enabled External Sharing for site \"{0}\".",
                                              site.Url);
                        }
                    }

                    // Move to the context of the created Site Collection
                    using (ClientContext clientContext = PnPPartnerPackContextProvider.GetAppOnlyClientContext(siteUrl))
                    {
                        clientContext.RequestTimeout = Timeout.Infinite;

                        Site site = clientContext.Site;
                        Web  web  = site.RootWeb;

                        clientContext.Load(site, s => s.Url);
                        clientContext.Load(web, w => w.Url);
                        clientContext.ExecuteQueryRetry();

                        // Check if we need to enable PnP Partner Pack overrides
                        if (job.PartnerPackExtensionsEnabled)
                        {
                            // Enable Responsive Design
                            PnPPartnerPackUtilities.EnablePartnerPackOnSite(site.Url);

                            Console.WriteLine("Enabled PnP Partner Pack Overrides on site \"{0}\".",
                                              site.Url);
                        }

                        // Check if the site has to be responsive
                        if (job.ResponsiveDesignEnabled)
                        {
                            // Enable Responsive Design
                            PnPPartnerPackUtilities.EnableResponsiveDesignOnSite(site.Url);

                            Console.WriteLine("Enabled Responsive Design Template to site \"{0}\".",
                                              site.Url);
                        }

                        // Apply the Provisioning Template
                        Console.WriteLine("Applying Provisioning Template \"{0}\" to site.",
                                          job.ProvisioningTemplateUrl);

                        // We do intentionally remove taxonomies, which are not supported
                        // in the AppOnly Authorization model
                        // For further details, see the PnP Partner Pack documentation
                        ProvisioningTemplateApplyingInformation ptai =
                            new ProvisioningTemplateApplyingInformation();

                        // Write provisioning steps on console log
                        ptai.MessagesDelegate += delegate(string message, ProvisioningMessageType messageType)
                        {
                            Console.WriteLine("{0} - {1}", messageType, messageType);
                        };
                        ptai.ProgressDelegate += delegate(string message, int step, int total)
                        {
                            Console.WriteLine("{0:00}/{1:00} - {2}", step, total, message);
                        };

                        // Exclude handlers not supported in App-Only
                        ptai.HandlersToProcess ^=
                            OfficeDevPnP.Core.Framework.Provisioning.Model.Handlers.TermGroups;
                        ptai.HandlersToProcess ^=
                            OfficeDevPnP.Core.Framework.Provisioning.Model.Handlers.SearchSettings;

                        // Configure template parameters
                        if (job.TemplateParameters != null)
                        {
                            foreach (var key in job.TemplateParameters.Keys)
                            {
                                if (job.TemplateParameters.ContainsKey(key))
                                {
                                    template.Parameters[key] = job.TemplateParameters[key];
                                }
                            }
                        }

                        // Fixup Title and Description
                        if (template.WebSettings != null)
                        {
                            template.WebSettings.Title       = job.SiteTitle;
                            template.WebSettings.Description = job.Description;
                        }

                        // Apply the template to the target site
                        web.ApplyProvisioningTemplate(template, ptai);

                        // Save the template information in the target site
                        var info = new SiteTemplateInfo()
                        {
                            TemplateProviderType = job.TemplatesProviderTypeName,
                            TemplateUri          = job.ProvisioningTemplateUrl,
                            TemplateParameters   = template.Parameters,
                            AppliedOn            = DateTime.Now,
                        };
                        var jsonInfo = JsonConvert.SerializeObject(info);
                        web.SetPropertyBagValue(PnPPartnerPackConstants.PropertyBag_TemplateInfo, jsonInfo);

                        // Set site policy template
                        if (!String.IsNullOrEmpty(job.SitePolicy))
                        {
                            web.ApplySitePolicy(job.SitePolicy);
                        }

                        // Apply Tenant Branding, if requested
                        if (job.ApplyTenantBranding)
                        {
                            var brandingSettings = PnPPartnerPackUtilities.GetTenantBrandingSettings();

                            using (var repositoryContext = PnPPartnerPackContextProvider.GetAppOnlyClientContext(
                                       PnPPartnerPackSettings.InfrastructureSiteUrl))
                            {
                                var brandingTemplate = BrandingJobHandler.PrepareBrandingTemplate(repositoryContext, brandingSettings);

                                // Fixup Title and Description
                                if (brandingTemplate != null)
                                {
                                    if (brandingTemplate.WebSettings != null)
                                    {
                                        brandingTemplate.WebSettings.Title       = job.SiteTitle;
                                        brandingTemplate.WebSettings.Description = job.Description;
                                    }

                                    // TO-DO: Need to handle exception here as there are multiple webs inside this where
                                    BrandingJobHandler.ApplyBrandingOnWeb(web, brandingSettings, brandingTemplate);
                                }
                            }
                        }


                        Console.WriteLine("Applied Provisioning Template \"{0}\" to site.",
                                          job.ProvisioningTemplateUrl);
                    }
                }
            }
        }
        private void CreateSubSite(SubSiteProvisioningJob job)
        {
            // Determine the reference URLs and relative paths
            String subSiteUrl        = job.RelativeUrl;
            String siteCollectionUrl = PnPPartnerPackUtilities.GetSiteCollectionRootUrl(job.ParentSiteUrl);
            String parentSiteUrl     = job.ParentSiteUrl;

            Console.WriteLine("Creating Site \"{0}\" as child Site of \"{1}\".", subSiteUrl, parentSiteUrl);

            using (ClientContext context = PnPPartnerPackContextProvider.GetAppOnlyClientContext(parentSiteUrl))
            {
                context.RequestTimeout = Timeout.Infinite;

                // Get a reference to the parent Web
                Web parentWeb = context.Web;

                // Load the template from the source Templates Provider
                if (!String.IsNullOrEmpty(job.TemplatesProviderTypeName))
                {
                    ProvisioningTemplate template = null;

                    var templatesProvider = PnPPartnerPackSettings.TemplatesProviders[job.TemplatesProviderTypeName];
                    if (templatesProvider != null)
                    {
                        template = templatesProvider.GetProvisioningTemplate(job.ProvisioningTemplateUrl);
                    }

                    if (template != null)
                    {
                        // Create the new sub site as a new child Web
                        WebCreationInformation newWeb = new WebCreationInformation();
                        newWeb.Description = job.Description;
                        newWeb.Language    = job.Language;
                        newWeb.Title       = job.SiteTitle;
                        newWeb.Url         = subSiteUrl;
                        newWeb.UseSamePermissionsAsParentSite = job.InheritPermissions;

                        // Use the BaseSiteTemplate of the template, if any, otherwise
                        // fallback to the pre-configured site template (i.e. STS#0)
                        newWeb.WebTemplate = !String.IsNullOrEmpty(template.BaseSiteTemplate) ?
                                             template.BaseSiteTemplate :
                                             PnPPartnerPackSettings.DefaultSiteTemplate;

                        Web web = parentWeb.Webs.Add(newWeb);
                        context.ExecuteQueryRetry();

                        Console.WriteLine("Site \"{0}\" created.", subSiteUrl);

                        // Apply the Provisioning Template
                        Console.WriteLine("Applying Provisioning Template \"{0}\" to site.",
                                          job.ProvisioningTemplateUrl);

                        // We do intentionally remove taxonomies, which are not supported in the AppOnly Authorization model
                        // For further details, see the PnP Partner Pack documentation
                        ProvisioningTemplateApplyingInformation ptai =
                            new ProvisioningTemplateApplyingInformation();

                        // Write provisioning steps on console log
                        ptai.MessagesDelegate += delegate(string message, ProvisioningMessageType messageType) {
                            Console.WriteLine("{0} - {1}", messageType, messageType);
                        };
                        ptai.ProgressDelegate += delegate(string message, int step, int total) {
                            Console.WriteLine("{0:00}/{1:00} - {2}", step, total, message);
                        };

                        // Exclude handlers not supported in App-Only
                        ptai.HandlersToProcess ^=
                            OfficeDevPnP.Core.Framework.Provisioning.Model.Handlers.TermGroups;
                        ptai.HandlersToProcess ^=
                            OfficeDevPnP.Core.Framework.Provisioning.Model.Handlers.SearchSettings;

                        // Configure template parameters
                        foreach (var key in template.Parameters.Keys)
                        {
                            if (job.TemplateParameters.ContainsKey(key))
                            {
                                template.Parameters[key] = job.TemplateParameters[key];
                            }
                        }

                        // Fixup Title and Description
                        template.WebSettings.Title       = job.SiteTitle;
                        template.WebSettings.Description = job.Description;

                        // Apply the template to the target site
                        web.ApplyProvisioningTemplate(template, ptai);

                        // Save the template information in the target site
                        var info = new SiteTemplateInfo()
                        {
                            TemplateProviderType = job.TemplatesProviderTypeName,
                            TemplateUri          = job.ProvisioningTemplateUrl,
                            TemplateParameters   = template.Parameters,
                            AppliedOn            = DateTime.Now,
                        };
                        var jsonInfo = JsonConvert.SerializeObject(info);
                        web.SetPropertyBagValue(PnPPartnerPackConstants.PropertyBag_TemplateInfo, jsonInfo);

                        // Set site policy template
                        if (!String.IsNullOrEmpty(job.SitePolicy))
                        {
                            web.ApplySitePolicy(job.SitePolicy);
                        }

                        // Apply Tenant Branding, if requested
                        if (job.ApplyTenantBranding)
                        {
                            var brandingSettings = PnPPartnerPackUtilities.GetTenantBrandingSettings();

                            using (var repositoryContext = PnPPartnerPackContextProvider.GetAppOnlyClientContext(
                                       PnPPartnerPackSettings.InfrastructureSiteUrl))
                            {
                                var brandingTemplate = BrandingJobHandler.PrepareBrandingTemplate(repositoryContext, brandingSettings);

                                // Fixup Title and Description
                                brandingTemplate.WebSettings.Title       = job.SiteTitle;
                                brandingTemplate.WebSettings.Description = job.Description;

                                BrandingJobHandler.ApplyBrandingOnWeb(web, brandingSettings, brandingTemplate);
                            }
                        }

                        Console.WriteLine("Applyed Provisioning Template \"{0}\" to site.",
                                          job.ProvisioningTemplateUrl);
                    }
                }
            }
        }
        private void CreateSubSite(SubSiteProvisioningJob job)
        {
            // Determine the reference URLs and relative paths
            String subSiteUrl        = job.RelativeUrl;
            String siteCollectionUrl = PnPPartnerPackUtilities.GetSiteCollectionRootUrl(job.ParentSiteUrl);
            String parentSiteUrl     = job.ParentSiteUrl;

            Console.WriteLine("Creating Site \"{0}\" as child Site of \"{1}\".", subSiteUrl, parentSiteUrl);

            using (ClientContext context = PnPPartnerPackContextProvider.GetAppOnlyClientContext(parentSiteUrl))
            {
                // Get a reference to the parent Web
                Web parentWeb = context.Web;

                // Create the new sub site as a new child Web
                WebCreationInformation newWeb = new WebCreationInformation();
                newWeb.Description = job.Description;
                newWeb.Language    = job.Language;
                newWeb.Title       = job.SiteTitle;
                newWeb.Url         = subSiteUrl;
                newWeb.UseSamePermissionsAsParentSite = job.InheritPermissions;
                newWeb.WebTemplate = PnPPartnerPackSettings.DefaultSiteTemplate;

                Web web = parentWeb.Webs.Add(newWeb);
                context.ExecuteQueryRetry();

                Console.WriteLine("Site \"{0}\" created.", subSiteUrl);

                // Apply the Provisioning Template
                Console.WriteLine("Applying Provisioning Template \"{0}\" to site.",
                                  job.ProvisioningTemplateUrl);

                // Determine the reference URLs and file names
                String templatesSiteUrl = job.ProvisioningTemplateUrl.Substring(0,
                                                                                job.ProvisioningTemplateUrl.IndexOf(PnPPartnerPackConstants.PnPProvisioningTemplates));
                String templateFileName = job.ProvisioningTemplateUrl.Substring(job.ProvisioningTemplateUrl.LastIndexOf("/") + 1);

                // Configure the XML file system provider
                XMLTemplateProvider provider =
                    new XMLSharePointTemplateProvider(context, templatesSiteUrl,
                                                      PnPPartnerPackConstants.PnPProvisioningTemplates);

                // Load the template from the XML stored copy
                ProvisioningTemplate template = provider.GetTemplate(templateFileName);
                template.Connector = provider.Connector;

                // We do intentionally remove taxonomies, which are not supported in the AppOnly Authorization model
                // For further details, see the PnP Partner Pack documentation
                ProvisioningTemplateApplyingInformation ptai =
                    new ProvisioningTemplateApplyingInformation();
                ptai.HandlersToProcess ^=
                    OfficeDevPnP.Core.Framework.Provisioning.Model.Handlers.TermGroups;

                // Configure template parameters
                foreach (var key in template.Parameters.Keys)
                {
                    if (job.TemplateParameters.ContainsKey(key))
                    {
                        template.Parameters[key] = job.TemplateParameters[key];
                    }
                }

                // Apply the template to the target site
                web.ApplyProvisioningTemplate(template, ptai);

                Console.WriteLine("Applyed Provisioning Template \"{0}\" to site.",
                                  job.ProvisioningTemplateUrl);
            }
        }
        private void CreateSubSite(SubSiteProvisioningJob job)
        {
            // Determine the reference URLs and relative paths
            String subSiteUrl        = job.RelativeUrl;
            String siteCollectionUrl = PnPPartnerPackUtilities.GetSiteCollectionRootUrl(job.ParentSiteUrl);
            String parentSiteUrl     = job.ParentSiteUrl;

            Console.WriteLine("Creating Site \"{0}\" as child Site of \"{1}\".", subSiteUrl, parentSiteUrl);

            using (ClientContext context = PnPPartnerPackContextProvider.GetAppOnlyClientContext(parentSiteUrl))
            {
                context.RequestTimeout = Timeout.Infinite;

                // Get a reference to the parent Web
                Web parentWeb = context.Web;

                // Load the template from the source Templates Provider
                if (!String.IsNullOrEmpty(job.TemplatesProviderTypeName))
                {
                    ProvisioningTemplate template = null;

                    var templatesProvider = PnPPartnerPackSettings.TemplatesProviders[job.TemplatesProviderTypeName];
                    if (templatesProvider != null)
                    {
                        template = templatesProvider.GetProvisioningTemplate(job.ProvisioningTemplateUrl);
                    }

                    if (template != null)
                    {
                        // Create the new sub site as a new child Web
                        WebCreationInformation newWeb = new WebCreationInformation();
                        newWeb.Description = job.Description;
                        newWeb.Language    = job.Language;
                        newWeb.Title       = job.SiteTitle;
                        newWeb.Url         = subSiteUrl;
                        newWeb.UseSamePermissionsAsParentSite = job.InheritPermissions;

                        // Use the BaseSiteTemplate of the template, if any, otherwise
                        // fallback to the pre-configured site template (i.e. STS#0)
                        newWeb.WebTemplate = !String.IsNullOrEmpty(template.BaseSiteTemplate) ?
                                             template.BaseSiteTemplate :
                                             PnPPartnerPackSettings.DefaultSiteTemplate;

                        Web web = parentWeb.Webs.Add(newWeb);
                        context.ExecuteQueryRetry();

                        if (template.ExtensibilityHandlers.Any())
                        {
                            // Clone Context pointing to Sub Site (needed for calling custom Extensibility Providers from the pnp template passing the right ClientContext)
                            string        newWeburl        = web.EnsureProperty(w => w.Url);
                            ClientContext webClientContext = context.Clone(newWeburl);
                            web = webClientContext.Web;
                        }

                        // Create sub-web unique groups
                        if (!job.InheritPermissions)
                        {
                            web.CreateDefaultAssociatedGroups(string.Empty, string.Empty, string.Empty);
                            context.ExecuteQueryRetry();
                        }

                        Console.WriteLine("Site \"{0}\" created.", subSiteUrl);

                        // Apply the Provisioning Template
                        Console.WriteLine("Applying Provisioning Template \"{0}\" to site.",
                                          job.ProvisioningTemplateUrl);

                        // We do intentionally remove taxonomies, which are not supported in the AppOnly Authorization model
                        // For further details, see the PnP Partner Pack documentation
                        ProvisioningTemplateApplyingInformation ptai =
                            new ProvisioningTemplateApplyingInformation();

                        // Write provisioning steps on console log
                        ptai.MessagesDelegate = (message, type) =>
                        {
                            switch (type)
                            {
                            case ProvisioningMessageType.Warning:
                            {
                                Console.WriteLine("{0} - {1}", type, message);
                                break;
                            }

                            case ProvisioningMessageType.Progress:
                            {
                                var activity = message;
                                if (message.IndexOf("|") > -1)
                                {
                                    var messageSplitted = message.Split('|');
                                    if (messageSplitted.Length == 4)
                                    {
                                        var status            = messageSplitted[0];
                                        var statusDescription = messageSplitted[1];
                                        var current           = double.Parse(messageSplitted[2]);
                                        var total             = double.Parse(messageSplitted[3]);
                                        var percentage        = Convert.ToInt32((100 / total) * current);
                                        Console.WriteLine("{0} - {1} - {2}", percentage, status, statusDescription);
                                    }
                                    else
                                    {
                                        Console.WriteLine(activity);
                                    }
                                }
                                else
                                {
                                    Console.WriteLine(activity);
                                }
                                break;
                            }

                            case ProvisioningMessageType.Completed:
                            {
                                Console.WriteLine(type);
                                break;
                            }
                            }
                        };
                        ptai.ProgressDelegate = (message, step, total) =>
                        {
                            var percentage = Convert.ToInt32((100 / Convert.ToDouble(total)) * Convert.ToDouble(step));
                            Console.WriteLine("{0:00}/{1:00} - {2} - {3}", step, total, percentage, message);
                        };

                        // Exclude handlers not supported in App-Only
                        ptai.HandlersToProcess ^=
                            OfficeDevPnP.Core.Framework.Provisioning.Model.Handlers.TermGroups;
                        ptai.HandlersToProcess ^=
                            OfficeDevPnP.Core.Framework.Provisioning.Model.Handlers.SearchSettings;

                        // Configure template parameters
                        foreach (var key in template.Parameters.Keys)
                        {
                            if (job.TemplateParameters.ContainsKey(key))
                            {
                                template.Parameters[key] = job.TemplateParameters[key];
                            }
                        }

                        // Fixup Title and Description
                        if (template.WebSettings != null)
                        {
                            template.WebSettings.Title       = job.SiteTitle;
                            template.WebSettings.Description = job.Description;
                        }

                        // Replace existing structural navigation on target site
                        if (template.Navigation != null &&
                            template.Navigation.CurrentNavigation != null &&
                            template.Navigation.CurrentNavigation.StructuralNavigation != null &&
                            (template.Navigation.CurrentNavigation.NavigationType == CurrentNavigationType.Structural ||
                             template.Navigation.CurrentNavigation.NavigationType == CurrentNavigationType.StructuralLocal))
                        {
                            template.Navigation.CurrentNavigation.StructuralNavigation.RemoveExistingNodes = true;
                        }

                        // Replace existing Structural Global Navigation on target site
                        if (template.Navigation != null &&
                            template.Navigation.GlobalNavigation != null &&
                            template.Navigation.GlobalNavigation.StructuralNavigation != null &&
                            template.Navigation.GlobalNavigation.NavigationType == GlobalNavigationType.Structural)
                        {
                            template.Navigation.GlobalNavigation.StructuralNavigation.RemoveExistingNodes = true;
                        }

                        // Apply the template to the target site
                        web.ApplyProvisioningTemplate(template, ptai);

                        // Save the template information in the target site
                        var info = new SiteTemplateInfo()
                        {
                            TemplateProviderType = job.TemplatesProviderTypeName,
                            TemplateUri          = job.ProvisioningTemplateUrl,
                            TemplateParameters   = template.Parameters,
                            AppliedOn            = DateTime.Now,
                        };
                        var jsonInfo = JsonConvert.SerializeObject(info);
                        web.SetPropertyBagValue(PnPPartnerPackConstants.PropertyBag_TemplateInfo, jsonInfo);

                        // Set site policy template
                        if (!String.IsNullOrEmpty(job.SitePolicy))
                        {
                            web.ApplySitePolicy(job.SitePolicy);
                        }

                        // Apply Tenant Branding, if requested
                        if (job.ApplyTenantBranding)
                        {
                            var brandingSettings = PnPPartnerPackUtilities.GetTenantBrandingSettings();

                            using (var repositoryContext = PnPPartnerPackContextProvider.GetAppOnlyClientContext(
                                       PnPPartnerPackSettings.InfrastructureSiteUrl))
                            {
                                var brandingTemplate = BrandingJobHandler.PrepareBrandingTemplate(repositoryContext, brandingSettings);

                                BrandingJobHandler.ApplyBrandingOnWeb(web, brandingSettings, brandingTemplate);

                                // Fixup Title and Description
                                if (brandingTemplate != null)
                                {
                                    if (brandingTemplate.WebSettings != null)
                                    {
                                        brandingTemplate.WebSettings.Title       = job.SiteTitle;
                                        brandingTemplate.WebSettings.Description = job.Description;
                                    }

                                    // TO-DO: Need to handle exception here as there are multiple webs inside this where
                                    BrandingJobHandler.ApplyBrandingOnWeb(web, brandingSettings, brandingTemplate);
                                }
                            }
                        }

                        Console.WriteLine("Applied Provisioning Template \"{0}\" to site.",
                                          job.ProvisioningTemplateUrl);
                    }
                }
            }
        }
        private List <ProvisioningTemplateInformation> SearchProvisioningTemplatesInternal(string searchText, TargetPlatform platforms, TargetScope scope, String cacheKey)
        {
            List <ProvisioningTemplateInformation> result = new List <ProvisioningTemplateInformation>();

            // Connect to the target Templates Site Collection
            using (var context = PnPPartnerPackContextProvider.GetAppOnlyClientContext(TemplatesSiteUrl))
            {
                // Get a reference to the target library
                Web web = context.Web;

                String platformsCAMLFilter = null;

                // Build the target Platforms filter
                if (platforms != TargetPlatform.None && platforms != TargetPlatform.All)
                {
                    if ((platforms & TargetPlatform.SharePointOnline) == TargetPlatform.SharePointOnline)
                    {
                        platformsCAMLFilter = @"<Eq>
                                                    <FieldRef Name='PnPProvisioningTemplatePlatform' />
                                                    <Value Type='MultiChoice'>SharePoint Online</Value>
                                                </Eq>";
                    }
                    if ((platforms & TargetPlatform.SharePoint2016) == TargetPlatform.SharePoint2016)
                    {
                        if (!String.IsNullOrEmpty(platformsCAMLFilter))
                        {
                            platformsCAMLFilter = @"<Or>" +
                                                  platformsCAMLFilter + @"
                                                        <Eq>
                                                            <FieldRef Name='PnPProvisioningTemplatePlatform' />
                                                            <Value Type='MultiChoice'>SharePoint 2016</Value>
                                                        </Eq>
                                                    </Or>";
                        }
                        else
                        {
                            platformsCAMLFilter = @"<Eq>
                                                    <FieldRef Name='PnPProvisioningTemplatePlatform' />
                                                    <Value Type='MultiChoice'>SharePoint 2016</Value>
                                                </Eq>";
                        }
                    }
                    if ((platforms & TargetPlatform.SharePoint2013) == TargetPlatform.SharePoint2013)
                    {
                        if (!String.IsNullOrEmpty(platformsCAMLFilter))
                        {
                            platformsCAMLFilter = @"<Or>" +
                                                  platformsCAMLFilter + @"
                                                        <Eq>
                                                            <FieldRef Name='PnPProvisioningTemplatePlatform' />
                                                            <Value Type='MultiChoice'>SharePoint 2013</Value>
                                                        </Eq>
                                                    </Or>";
                        }
                        else
                        {
                            platformsCAMLFilter = @"<Eq>
                                                    <FieldRef Name='PnPProvisioningTemplatePlatform' />
                                                    <Value Type='MultiChoice'>SharePoint 2013</Value>
                                                </Eq>";
                        }
                    }

                    try
                    {
                        List list = web.Lists.GetByTitle(PnPPartnerPackConstants.PnPProvisioningTemplates);

                        // Get only Provisioning Templates documents with the specified Scope
                        CamlQuery query = new CamlQuery();
                        query.ViewXml =
                            @"<View>
                        <Query>
                            <Where>" +
                            (!String.IsNullOrEmpty(platformsCAMLFilter) ? " < And>" : String.Empty) + @"
                                    <And>
                                        <Eq>
                                            <FieldRef Name='PnPProvisioningTemplateScope' />
                                            <Value Type='Choice'>" + scope.ToString() + @"</Value>
                                        </Eq>
                                        <Eq>
                                            <FieldRef Name='ContentType' />
                                            <Value Type=''Computed''>PnPProvisioningTemplate</Value>
                                        </Eq>
                                    </And>" + platformsCAMLFilter +
                            (!String.IsNullOrEmpty(platformsCAMLFilter) ? "</And>" : String.Empty) + @"                                
                            </Where>
                        </Query>
                        <ViewFields>
                            <FieldRef Name='Title' />
                            <FieldRef Name='PnPProvisioningTemplateScope' />
                            <FieldRef Name='PnPProvisioningTemplatePlatform' />
                            <FieldRef Name='PnPProvisioningTemplateSourceUrl' />
                        </ViewFields>
                    </View>";

                        ListItemCollection items = list.GetItems(query);
                        context.Load(items,
                                     includes => includes.Include(i => i.File,
                                                                  i => i[PnPPartnerPackConstants.PnPProvisioningTemplateScope],
                                                                  i => i[PnPPartnerPackConstants.PnPProvisioningTemplatePlatform],
                                                                  i => i[PnPPartnerPackConstants.PnPProvisioningTemplateSourceUrl]));
                        context.ExecuteQueryRetry();

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

                        // Configure the SharePoint Connector
                        var sharepointConnector = new SharePointConnector(context, web.Url,
                                                                          PnPPartnerPackConstants.PnPProvisioningTemplates);

                        foreach (ListItem item in items)
                        {
                            // Get the template file name and server relative URL
                            item.File.EnsureProperties(f => f.Name, f => f.ServerRelativeUrl);

                            TemplateProviderBase provider = null;

                            // If the target is a .PNP Open XML template
                            if (item.File.Name.ToLower().EndsWith(".pnp"))
                            {
                                // Configure the Open XML provider for SharePoint
                                provider =
                                    new XMLOpenXMLTemplateProvider(
                                        new OpenXMLConnector(item.File.Name, sharepointConnector));
                            }
                            else
                            {
                                // Otherwise use the .XML template provider for SharePoint
                                provider =
                                    new XMLSharePointTemplateProvider(context, web.Url,
                                                                      PnPPartnerPackConstants.PnPProvisioningTemplates);
                            }

                            // Determine the name of the XML file inside the PNP Open XML file, if any
                            var xmlTemplateFile = item.File.Name.ToLower().Replace(".pnp", ".xml");

                            // Get the template
                            ProvisioningTemplate template = provider.GetTemplate(xmlTemplateFile);

                            // Prepare the resulting item
                            var templateInformation = new ProvisioningTemplateInformation
                            {
                                // Scope = (TargetScope)Enum.Parse(typeof(TargetScope), (String)item[PnPPartnerPackConstants.PnPProvisioningTemplateScope], true),
                                TemplateSourceUrl = item[PnPPartnerPackConstants.PnPProvisioningTemplateSourceUrl] != null ? ((FieldUrlValue)item[PnPPartnerPackConstants.PnPProvisioningTemplateSourceUrl]).Url : null,
                                TemplateFileUri   = String.Format("{0}/{1}/{2}", web.Url, PnPPartnerPackConstants.PnPProvisioningTemplates, item.File.Name),
                                TemplateImageUrl  = template.ImagePreviewUrl,
                                DisplayName       = template.DisplayName,
                                Description       = template.Description,
                            };

                            #region Determine Scope

                            String targetScope;
                            if (template.Properties.TryGetValue(PnPPartnerPackConstants.TEMPLATE_SCOPE, out targetScope))
                            {
                                if (String.Equals(targetScope, PnPPartnerPackConstants.TEMPLATE_SCOPE_PARTIAL, StringComparison.InvariantCultureIgnoreCase))
                                {
                                    templateInformation.Scope = TargetScope.Partial;
                                }
                                else if (String.Equals(targetScope, PnPPartnerPackConstants.TEMPLATE_SCOPE_WEB, StringComparison.InvariantCultureIgnoreCase))
                                {
                                    templateInformation.Scope = TargetScope.Web;
                                }
                                else if (String.Equals(targetScope, PnPPartnerPackConstants.TEMPLATE_SCOPE_SITE, StringComparison.InvariantCultureIgnoreCase))
                                {
                                    templateInformation.Scope = TargetScope.Site;
                                }
                            }

                            #endregion

                            #region Determine target Platforms

                            String spoPlatform, sp2016Platform, sp2013Platform;
                            if (template.Properties.TryGetValue(PnPPartnerPackConstants.PLATFORM_SPO, out spoPlatform))
                            {
                                if (spoPlatform.Equals(PnPPartnerPackConstants.TRUE_VALUE, StringComparison.InvariantCultureIgnoreCase))
                                {
                                    templateInformation.Platforms |= TargetPlatform.SharePointOnline;
                                }
                            }
                            if (template.Properties.TryGetValue(PnPPartnerPackConstants.PLATFORM_SP2016, out sp2016Platform))
                            {
                                if (sp2016Platform.Equals(PnPPartnerPackConstants.TRUE_VALUE, StringComparison.InvariantCultureIgnoreCase))
                                {
                                    templateInformation.Platforms |= TargetPlatform.SharePoint2016;
                                }
                            }
                            if (template.Properties.TryGetValue(PnPPartnerPackConstants.PLATFORM_SP2013, out sp2013Platform))
                            {
                                if (sp2013Platform.Equals(PnPPartnerPackConstants.TRUE_VALUE, StringComparison.InvariantCultureIgnoreCase))
                                {
                                    templateInformation.Platforms |= TargetPlatform.SharePoint2013;
                                }
                            }

                            #endregion

                            // If we don't have a search text
                            // or we have a search text and it is contained either
                            // in the DisplayName or in the Description of the template
                            if ((!String.IsNullOrEmpty(searchText) &&
                                 ((!String.IsNullOrEmpty(template.DisplayName) && template.DisplayName.ToLower().Contains(searchText.ToLower())) ||
                                  (!String.IsNullOrEmpty(template.Description) && template.Description.ToLower().Contains(searchText.ToLower())))) ||
                                String.IsNullOrEmpty(searchText))
                            {
                                // Add the template to the result
                                result.Add(templateInformation);
                            }
                        }
                    }
                    catch (ServerException)
                    {
                        // In case of any issue, ignore the failing templates
                    }
                }
            }

            CacheItemPolicy policy = new CacheItemPolicy
            {
                Priority           = CacheItemPriority.Default,
                AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(30), // Cache results for 30 minutes
                RemovedCallback    = (args) =>
                {
                    if (args.RemovedReason == CacheEntryRemovedReason.Expired)
                    {
                        var removedKey   = args.CacheItem.Key;
                        var searchInputs = JsonConvert.DeserializeObject <SharePointSearchCacheKey>(removedKey);

                        var newItem = SearchProvisioningTemplatesInternal(
                            searchInputs.SearchText,
                            searchInputs.Platforms,
                            searchInputs.Scope,
                            removedKey);
                    }
                },
            };

            Cache.Set(cacheKey, result, policy);

            return(result);
        }
        private void SaveProvisioningTemplateInternal(ClientContext context, GetProvisioningTemplateJob job, Boolean globalRepository = true)
        {
            // Get a reference to the target web site
            Web web = context.Web;

            context.Load(web, w => w.Url);
            context.ExecuteQueryRetry();

            // Prepare the support variables
            ClientContext repositoryContext = null;
            Web           repositoryWeb     = null;

            // Define whether we need to use the global infrastructural repository or the local one
            if (globalRepository)
            {
                // Get a reference to the global repository web site and context
                repositoryContext = PnPPartnerPackContextProvider.GetAppOnlyClientContext(PnPPartnerPackSettings.InfrastructureSiteUrl);
            }
            else
            {
                // Get a reference to the local repository web site and context
                repositoryContext = web.Context.GetSiteCollectionContext();
            }

            using (repositoryContext)
            {
                repositoryWeb = repositoryContext.Site.RootWeb;
                repositoryContext.Load(repositoryWeb, w => w.Url);
                repositoryContext.ExecuteQueryRetry();

                // Configure the XML SharePoint provider for the Infrastructural Site Collection
                XMLTemplateProvider provider =
                    new XMLSharePointTemplateProvider(repositoryContext, repositoryWeb.Url,
                                                      PnPPartnerPackConstants.PnPProvisioningTemplates);

                ProvisioningTemplateCreationInformation ptci =
                    new ProvisioningTemplateCreationInformation(web);
                ptci.FileConnector                  = provider.Connector;
                ptci.IncludeAllTermGroups           = job.IncludeAllTermGroups;
                ptci.IncludeSearchConfiguration     = job.IncludeSearchConfiguration;
                ptci.IncludeSiteCollectionTermGroup = job.IncludeSiteCollectionTermGroup;
                ptci.IncludeSiteGroups              = job.IncludeSiteGroups;
                ptci.PersistComposedLookFiles       = job.PersistComposedLookFiles;

                // Extract the current template
                ProvisioningTemplate templateToSave = web.GetProvisioningTemplate(ptci);

                templateToSave.Description = job.Description;
                templateToSave.DisplayName = job.Title;

                // Save template image preview in folder
                Folder templatesFolder = repositoryWeb.GetFolderByServerRelativeUrl(PnPPartnerPackConstants.PnPProvisioningTemplates);
                repositoryContext.Load(templatesFolder, f => f.ServerRelativeUrl, f => f.Name);
                repositoryContext.ExecuteQueryRetry();

                // If there is a preview image
                if (job.TemplateImageFile != null)
                {
                    String previewImageFileName = job.FileName.Replace(".xml", "_preview.png");
                    templatesFolder.UploadFile(previewImageFileName,
                                               job.TemplateImageFile.ToStream(), true);

                    // And store URL in the XML file
                    templateToSave.ImagePreviewUrl = String.Format("{0}/{1}/{2}",
                                                                   repositoryWeb.Url, templatesFolder.Name, previewImageFileName);
                }

                // And save it on the file system
                provider.SaveAs(templateToSave, job.FileName);

                Microsoft.SharePoint.Client.File templateFile = templatesFolder.GetFile(job.FileName);
                ListItem item = templateFile.ListItemAllFields;

                item[PnPPartnerPackConstants.ContentTypeIdField]               = PnPPartnerPackConstants.PnPProvisioningTemplateContentTypeId;
                item[PnPPartnerPackConstants.TitleField]                       = job.Title;
                item[PnPPartnerPackConstants.PnPProvisioningTemplateScope]     = job.Scope.ToString();
                item[PnPPartnerPackConstants.PnPProvisioningTemplateSourceUrl] = job.SourceSiteUrl;

                item.Update();

                repositoryContext.ExecuteQueryRetry();
            }
        }
        public Guid EnqueueProvisioningJob(ProvisioningJob job)
        {
            // Prepare the Job ID
            Guid jobId = Guid.NewGuid();

            // Connect to the Infrastructural Site Collection
            using (var context = PnPPartnerPackContextProvider.GetAppOnlyClientContext(PnPPartnerPackSettings.InfrastructureSiteUrl))
            {
                // Set the initial status of the Job
                job.JobId  = jobId;
                job.Status = ProvisioningJobStatus.Pending;

                // Convert the current Provisioning Job into a Stream
                Stream stream = job.ToJsonStream();

                // Get a reference to the target library
                Web  web  = context.Web;
                List list = web.Lists.GetByTitle(PnPPartnerPackConstants.PnPProvisioningJobs);
                Microsoft.SharePoint.Client.File file = list.RootFolder.UploadFile(String.Format("{0}.job", jobId), stream, false);

                Microsoft.SharePoint.Client.User ownerUser = web.EnsureUser(job.Owner);
                context.Load(ownerUser);
                context.ExecuteQueryRetry();

                ListItem item = file.ListItemAllFields;

                item[PnPPartnerPackConstants.ContentTypeIdField]       = PnPPartnerPackConstants.PnPProvisioningJobContentTypeId;
                item[PnPPartnerPackConstants.TitleField]               = job.Title;
                item[PnPPartnerPackConstants.PnPProvisioningJobStatus] = ProvisioningJobStatus.Pending.ToString();
                item[PnPPartnerPackConstants.PnPProvisioningJobError]  = String.Empty;
                item[PnPPartnerPackConstants.PnPProvisioningJobType]   = job.GetType().FullName;

                FieldUserValue ownerUserValue = new FieldUserValue();
                ownerUserValue.LookupId = ownerUser.Id;
                item[PnPPartnerPackConstants.PnPProvisioningJobOwner] = ownerUserValue;

                item.Update();

                context.ExecuteQueryRetry();

                // Check if we need to enqueue a message in the Azure Storage Queue, as well
                // This happens when the Provisioning Job has to be executed in Continous mode
                if (PnPPartnerPackSettings.ContinousJobHandlers.ContainsKey(job.GetType()))
                {
                    // Get the storage account for Azure Storage Queue
                    CloudStorageAccount storageAccount =
                        CloudStorageAccount.Parse(PnPPartnerPackSettings.StorageQueueConnectionString);

                    // Get queue ... and create if it does not exist
                    CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
                    CloudQueue       queue       = queueClient.GetQueueReference(PnPPartnerPackSettings.StorageQueueName);
                    queue.CreateIfNotExists();

                    // Add entry to queue
                    ContinousJobItem content = new ContinousJobItem {
                        JobId = job.JobId
                    };
                    queue.AddMessage(new CloudQueueMessage(JsonConvert.SerializeObject(content)));
                }
            }

            return(jobId);
        }
Пример #27
0
        private void SaveProvisioningTemplateInternal(ClientContext context, GetProvisioningTemplateJob job, Boolean globalRepository = true)
        {
            // Fix the job filename if it is missing the .pnp extension
            if (!job.FileName.ToLower().EndsWith(".pnp"))
            {
                job.FileName += ".pnp";
            }

            // Get the Access Token from the current context
            //var accessToken = "Bearer " + context.GetAccessToken();
            var accessToken = context.GetAccessToken();

            Console.WriteLine("Bearer " + accessToken);

            // Get a reference to the target web site
            Web web = context.Web;

            context.Load(web, w => w.Url, w => w.ServerRelativeUrl);
            context.ExecuteQueryRetry();

            // Prepare the support variables
            ClientContext repositoryContext = null;
            Web           repositoryWeb     = null;

            // Define whether we need to use the global infrastructural repository or the local one
            if (globalRepository)
            {
                // Get a reference to the global repository web site and context
                repositoryContext = PnPPartnerPackContextProvider.GetAppOnlyClientContext(
                    PnPPartnerPackSettings.InfrastructureSiteUrl);
            }
            else
            {
                // Get a reference to the local repository web site and context
                repositoryContext = web.Context.GetSiteCollectionContext();
            }

            using (repositoryContext)
            {
                repositoryWeb = repositoryContext.Site.RootWeb;
                repositoryContext.Load(repositoryWeb, w => w.Url);
                repositoryContext.ExecuteQueryRetry();

                // Configure the XML SharePoint provider for the Infrastructural Site Collection
                XMLTemplateProvider provider = new XMLOpenXMLTemplateProvider(job.FileName,
                                                                              new SharePointConnector(repositoryContext, repositoryWeb.Url,
                                                                                                      PnPPartnerPackConstants.PnPProvisioningTemplates));

                ProvisioningTemplateCreationInformation ptci =
                    new ProvisioningTemplateCreationInformation(web);
                ptci.FileConnector                  = provider.Connector;
                ptci.IncludeAllTermGroups           = job.IncludeAllTermGroups;
                ptci.IncludeSearchConfiguration     = job.IncludeSearchConfiguration;
                ptci.IncludeSiteCollectionTermGroup = job.IncludeSiteCollectionTermGroup;
                ptci.IncludeSiteGroups              = job.IncludeSiteGroups;
                ptci.PersistBrandingFiles           = job.PersistComposedLookFiles;

                // We do intentionally remove taxonomies and search, which are not supported
                // in the AppOnly Authorization model
                // For further details, see the PnP Partner Pack documentation
                ptci.HandlersToProcess ^= Handlers.TermGroups;
                ptci.HandlersToProcess ^= Handlers.SearchSettings;

                // Extract the current template
                ProvisioningTemplate templateToSave = web.GetProvisioningTemplate(ptci);

                templateToSave.Description = job.Description;
                templateToSave.DisplayName = job.Title;

                if (job.PersistComposedLookFiles)
                {
                    // Create Theme Entity object
                    ThemeEntity themeEntity = web.GetCurrentComposedLook();

                    foreach (var p in themeEntity.GetType().GetProperties().Where(p => p.GetGetMethod().GetParameters().Count() == 0))
                    {
                        string propName  = p.Name;
                        string propValue = Convert.ToString(p.GetValue(themeEntity, null));

                        if (propName == "Theme")
                        {
                            propName = "ColorFile";
                        }
                        else if (propName == "Font")
                        {
                            propName = "FontFile";
                        }
                        else if (propName == "BackgroundImage")
                        {
                            propValue = "PlaceHolderValue";
                        }
                        else if (propName == "Name" && String.IsNullOrEmpty(propValue))
                        {
                            propValue = "CustomTheme";
                        }

                        string fileName    = propValue.Substring(propValue.LastIndexOf("/") + 1);
                        string relativeURL = propValue.Substring(0, propValue.LastIndexOf("/") + 1);

                        // Update template Files
                        if (propName != "Name" && propName != "IsCustomComposedLook" && !String.IsNullOrEmpty(propValue))
                        {
                            var property = templateToSave.ComposedLook.GetType().GetProperty(propName);

                            try
                            {
                                string folderPath = "";
                                Stream fileStream = null;

                                if (propName == "BackgroundImage")
                                {
                                    if (job.templateBackgroundImgFile != null)
                                    {
                                        folderPath = "{site}/SiteAssets";
                                        fileName   = job.FileName.ToLower().Replace(".pnp", ".png");
                                        fileStream = job.templateBackgroundImgFile.ToStream();
                                        Console.WriteLine("fileName: " + fileName);
                                        Console.WriteLine("fileStream: " + fileStream);
                                        templateToSave.ComposedLook.BackgroundFile = String.Format("{{sitecollection}}/SiteAssets/{0}", fileName);
                                    }
                                }
                                else if (propName.Contains("MasterPage"))
                                {
                                    folderPath = "{masterpagecatalog}";
                                    var strUrl = String.Format("{0}/_api/web/getfilebyserverrelativeurl('{1}{2}')/$value", web.Url, web.ServerRelativeUrl, propValue);
                                    fileStream = HttpHelper.MakeGetRequestForStream(strUrl, "application/octet-stream", accessToken);
                                    property.SetValue(templateToSave.ComposedLook, String.Format("{{masterpagecatalog}}/{0}", fileName), new object[] { });
                                }
                                else
                                {
                                    folderPath = "{themecatalog}/15";
                                    var strUrl = String.Format("{0}/_api/web/getfilebyserverrelativeurl('{1}{2}')/$value", web.Url, web.ServerRelativeUrl, propValue);
                                    fileStream = HttpHelper.MakeGetRequestForStream(strUrl, "application/octet-stream", accessToken);
                                    property.SetValue(templateToSave.ComposedLook, String.Format("{{themecatalog}}/15/{0}", fileName), new object[] { });
                                }

                                Console.WriteLine("Saving files: {0}, {1}", fileName, fileStream);
                                provider.Connector.SaveFileStream(fileName, fileStream);

                                Console.WriteLine("File Paths: {0}, {1}", fileName, folderPath);
                                templateToSave.Files.Add(new OfficeDevPnP.Core.Framework.Provisioning.Model.File
                                {
                                    Src       = fileName,
                                    Folder    = folderPath,
                                    Overwrite = true,
                                });

                                Console.WriteLine("Files saved: {0}, {1}", fileName, folderPath);
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(ex);
                            }
                        }
                        else if (propName == "Name")
                        {
                            var property = templateToSave.ComposedLook.GetType().GetProperty(propName);

                            property.SetValue(templateToSave.ComposedLook, fileName, new object[] { });
                        }
                    }

                    if (job.templateAltCSSFile != null)
                    {
                        //TODO: Add handling for native Alternate CSS
                        //web.AlternateCssUrl;
                        string folderPath = "{site}/SiteAssets";
                        string fileName   = job.FileName.ToLower().Replace(".pnp", ".css");
                        Stream fileStream = job.templateAltCSSFile.ToStream();

                        provider.Connector.SaveFileStream(fileName, fileStream);

                        templateToSave.WebSettings = new WebSettings
                        {
                            AlternateCSS = String.Format("{{sitecollection}}/SiteAssets/{0}", fileName),
                        };

                        Console.WriteLine("File Paths: {0}, {1}", fileName, folderPath);
                        templateToSave.Files.Add(new OfficeDevPnP.Core.Framework.Provisioning.Model.File
                        {
                            Src       = fileName,
                            Folder    = folderPath,
                            Overwrite = true,
                        });
                    }
                }

                // Save template image preview in folder
                Microsoft.SharePoint.Client.Folder templatesFolder = repositoryWeb.GetFolderByServerRelativeUrl(PnPPartnerPackConstants.PnPProvisioningTemplates);
                repositoryContext.Load(templatesFolder, f => f.ServerRelativeUrl, f => f.Name);
                repositoryContext.ExecuteQueryRetry();

                // If there is a preview image
                if (job.TemplateImageFile != null)
                {
                    // Determine the preview image file name
                    String previewImageFileName = job.FileName.ToLower().Replace(".pnp", "_preview.png");

                    // Save the preview image inside the Open XML package
                    provider.Connector.SaveFileStream(previewImageFileName, job.TemplateImageFile.ToStream());

                    // And store URL in the XML file
                    templateToSave.ImagePreviewUrl = String.Format("{0}{1}/{2}/{3}/{4}",
                                                                   repositoryWeb.Url.ToLower().StartsWith("https") ? "pnps" : "pnp",
                                                                   repositoryWeb.Url.Substring(repositoryWeb.Url.IndexOf("://")),
                                                                   templatesFolder.Name, job.FileName, previewImageFileName);
                }

                // And save it on the file system
                provider.SaveAs(templateToSave, job.FileName.ToLower().Replace(".pnp", ".xml"));

                Microsoft.SharePoint.Client.File templateFile = templatesFolder.GetFile(job.FileName);
                ListItem item = templateFile.ListItemAllFields;

                item[PnPPartnerPackConstants.ContentTypeIdField]               = PnPPartnerPackConstants.PnPProvisioningTemplateContentTypeId;
                item[PnPPartnerPackConstants.TitleField]                       = job.Title;
                item[PnPPartnerPackConstants.PnPProvisioningTemplateScope]     = job.Scope.ToString();
                item[PnPPartnerPackConstants.PnPProvisioningTemplateSourceUrl] = job.SourceSiteUrl;

                item.Update();

                repositoryContext.ExecuteQueryRetry();
            }
        }
        private void SaveProvisioningTemplateInternal(ClientContext context, GetProvisioningTemplateJob job, Boolean globalRepository = true)
        {
            // Fix the job filename if it is missing the .pnp extension
            if (!job.FileName.ToLower().EndsWith(".pnp"))
            {
                job.FileName += ".pnp";
            }

            // Get a reference to the target web site
            Web web = context.Web;

            context.Load(web, w => w.Url);
            context.ExecuteQueryRetry();

            // Prepare the support variables
            ClientContext repositoryContext = null;
            Web           repositoryWeb     = null;

            // Define whether we need to use the global infrastructural repository or the local one
            if (globalRepository)
            {
                // Get a reference to the global repository web site and context
                repositoryContext = PnPPartnerPackContextProvider.GetAppOnlyClientContext(
                    PnPPartnerPackSettings.InfrastructureSiteUrl);
            }
            else
            {
                // Get a reference to the local repository web site and context
                repositoryContext = web.Context.GetSiteCollectionContext();
            }

            using (repositoryContext)
            {
                repositoryWeb = repositoryContext.Site.RootWeb;
                repositoryContext.Load(repositoryWeb, w => w.Url);
                repositoryContext.ExecuteQueryRetry();

                // Configure the XML SharePoint provider for the Infrastructural Site Collection
                XMLTemplateProvider provider = new XMLOpenXMLTemplateProvider(job.FileName,
                                                                              new SharePointConnector(repositoryContext, repositoryWeb.Url,
                                                                                                      PnPPartnerPackConstants.PnPProvisioningTemplates));

                ProvisioningTemplateCreationInformation ptci =
                    new ProvisioningTemplateCreationInformation(web);
                ptci.FileConnector                  = provider.Connector;
                ptci.IncludeAllTermGroups           = job.IncludeAllTermGroups;
                ptci.IncludeSearchConfiguration     = job.IncludeSearchConfiguration;
                ptci.IncludeSiteCollectionTermGroup = job.IncludeSiteCollectionTermGroup;
                ptci.IncludeSiteGroups              = job.IncludeSiteGroups;
                ptci.PersistBrandingFiles           = job.PersistComposedLookFiles;

                // We do intentionally remove taxonomies and search, which are not supported
                // in the AppOnly Authorization model
                // For further details, see the PnP Partner Pack documentation
                ptci.HandlersToProcess ^= Handlers.TermGroups;
                ptci.HandlersToProcess ^= Handlers.SearchSettings;

                // Extract the current template
                ProvisioningTemplate templateToSave = web.GetProvisioningTemplate(ptci);

                templateToSave.Description = job.Description;
                templateToSave.DisplayName = job.Title;

                // Save template image preview in folder
                Microsoft.SharePoint.Client.Folder templatesFolder = repositoryWeb.GetFolderByServerRelativeUrl(PnPPartnerPackConstants.PnPProvisioningTemplates);
                repositoryContext.Load(templatesFolder, f => f.ServerRelativeUrl, f => f.Name);
                repositoryContext.ExecuteQueryRetry();

                // If there is a preview image
                if (job.TemplateImageFile != null)
                {
                    // Determine the preview image file name
                    String previewImageFileName = job.FileName.ToLower().Replace(".pnp", "_preview.png");

                    // Save the preview image inside the Open XML package
                    provider.Connector.SaveFileStream(previewImageFileName, job.TemplateImageFile.ToStream());

                    // And store URL in the XML file
                    templateToSave.ImagePreviewUrl = String.Format("{0}{1}/{2}/{3}/{4}",
                                                                   repositoryWeb.Url.ToLower().StartsWith("https") ? "pnps" : "pnp",
                                                                   repositoryWeb.Url.Substring(repositoryWeb.Url.IndexOf("://")),
                                                                   templatesFolder.Name, job.FileName, previewImageFileName);
                }

                // And save it on the file system
                provider.SaveAs(templateToSave, job.FileName.ToLower().Replace(".pnp", ".xml"));

                Microsoft.SharePoint.Client.File templateFile = templatesFolder.GetFile(job.FileName);
                ListItem item = templateFile.ListItemAllFields;

                item[PnPPartnerPackConstants.ContentTypeIdField]               = PnPPartnerPackConstants.PnPProvisioningTemplateContentTypeId;
                item[PnPPartnerPackConstants.TitleField]                       = job.Title;
                item[PnPPartnerPackConstants.PnPProvisioningTemplateScope]     = job.Scope.ToString();
                item[PnPPartnerPackConstants.PnPProvisioningTemplateSourceUrl] = job.SourceSiteUrl;

                item.Update();

                repositoryContext.ExecuteQueryRetry();
            }
        }