Exemple #1
0
        private void ProcessFiles(string templateFileName, FileConnectorBase fileSystemConnector, FileConnectorBase connector)
        {
            var templateFile = ReadProvisioningTemplate.LoadProvisioningTemplateFromFile(templateFileName, null, (e) =>
            {
                WriteError(new ErrorRecord(e, "TEMPLATENOTVALID", ErrorCategory.SyntaxError, null));
            });

            if (Template.Tenant?.AppCatalog != null)
            {
                foreach (var app in Template.Tenant.AppCatalog.Packages)
                {
                    WriteObject($"Processing {app.Src}");
                    AddFile(app.Src, templateFile, fileSystemConnector, connector);
                }
            }
            if (Template.Tenant?.SiteScripts != null)
            {
                foreach (var siteScript in Template.Tenant.SiteScripts)
                {
                    WriteObject($"Processing {siteScript.JsonFilePath}");
                    AddFile(siteScript.JsonFilePath, templateFile, fileSystemConnector, connector);
                }
            }
            if (Template.Localizations != null && Template.Localizations.Any())
            {
                foreach (var location in Template.Localizations)
                {
                    WriteObject($"Processing {location.ResourceFile}");
                    AddFile(location.ResourceFile, templateFile, fileSystemConnector, connector);
                }
            }

            if (Template.WebSettings != null && !String.IsNullOrEmpty(Template.WebSettings.SiteLogo))
            {
                // is it a file?
                var isFile = false;
                using (var fileStream = fileSystemConnector.GetFileStream(Template.WebSettings.SiteLogo))
                {
                    isFile = fileStream != null;
                }
                if (isFile)
                {
                    WriteObject($"Processing {Template.WebSettings.SiteLogo}");
                    AddFile(Template.WebSettings.SiteLogo, templateFile, fileSystemConnector, connector);
                }
            }
            if (Template.Files.Any())
            {
                foreach (var file in Template.Files)
                {
                    WriteObject($"Processing {file.Src}");
                    AddFile(file.Src, templateFile, fileSystemConnector, connector);
                }
            }

            if (templateFile.Connector is ICommitableFileConnector)
            {
                ((ICommitableFileConnector)templateFile.Connector).Commit();
            }
        }
Exemple #2
0
        /// <summary>
        /// Constructor for ProvisioningTemplate class
        /// </summary>
        public ProvisioningTemplate()
        {
            this.connector = new FileSystemConnector(".", "");

            this._localizations = new LocalizationCollection(this);
            this._siteFields    = new FieldCollection(this);
            this._contentTypes  = new ContentTypeCollection(this);
            this._propertyBags  = new PropertyBagEntryCollection(this);
            this._lists         = new ListInstanceCollection(this);

            this._siteSecurity = new SiteSecurity();
            this._siteSecurity.ParentTemplate = this;

            this._composedLook = new ComposedLook();
            this._composedLook.ParentTemplate = this;
            this._features = new Features();
            this._features.ParentTemplate      = this;
            this._customActions                = new CustomActions();
            this._customActions.ParentTemplate = this;

            this._files                 = new FileCollection(this);
            this._directories           = new DirectoryCollection(this);
            this._providers             = new ProviderCollection(this); // Deprecated
            this._extensibilityHandlers = new ExtensibilityHandlerCollection(this);
            this._pages                 = new PageCollection(this);
            this._termGroups            = new TermGroupCollection(this);

            this._supportedUILanguages = new SupportedUILanguageCollection(this);
            this._addins = new AddInCollection(this);

            this._siteWebhooks    = new SiteWebhookCollection(this);
            this._clientSidePages = new ClientSidePageCollection(this);
        }
Exemple #3
0
        /// <summary>
        /// Returns Connectors
        /// </summary>
        /// <returns></returns>
        private FileConnectorBase GetProvisioningConnector()
        {
            ReflectionHelper  _helper            = new ReflectionHelper();
            FileConnectorBase _connectorInstance = _helper.GetProvisioningConnector(ModuleKeys.PROVISIONINGCONNECTORS_KEY);

            return(_connectorInstance);
        }
Exemple #4
0
 public XMLOpenXMLTemplateProvider(string packageFileName,
                                   FileConnectorBase persistenceConnector,
                                   String author = null,
                                   X509Certificate2 signingCertificate = null) :
     base(new OpenXMLConnector(packageFileName, persistenceConnector,
                               author, signingCertificate))
 {
 }
 private static void SaveFileInPackage(String filePath, String container, FileConnectorBase connector)
 {
     using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
     {
         String fileName = filePath.Substring(filePath.LastIndexOf("\\") + 1);
         connector.SaveFileStream(fileName, container, fs);
     }
 }
        private void ProcessFiles(string templateFileName, FileConnectorBase fileSystemConnector, FileConnectorBase connector)
        {
            var templateFile = ReadTenantTemplate.LoadProvisioningHierarchyFromFile(templateFileName, null);

            if (Template.Tenant?.AppCatalog != null)
            {
                foreach (var app in Template.Tenant.AppCatalog.Packages)
                {
                    WriteObject($"Processing {app.Src}");
                    AddFile(app.Src, templateFile, fileSystemConnector, connector);
                }
            }
            if (Template.Tenant?.SiteScripts != null)
            {
                foreach (var siteScript in Template.Tenant.SiteScripts)
                {
                    WriteObject($"Processing {siteScript.JsonFilePath}");
                    AddFile(siteScript.JsonFilePath, templateFile, fileSystemConnector, connector);
                }
            }
            if (Template.Localizations != null && Template.Localizations.Any())
            {
                foreach (var location in Template.Localizations)
                {
                    WriteObject($"Processing {location.ResourceFile}");
                    AddFile(location.ResourceFile, templateFile, fileSystemConnector, connector);
                }
            }
            foreach (var template in Template.Templates)
            {
                if (template.WebSettings != null && template.WebSettings.SiteLogo != null)
                {
                    // is it a file?
                    var isFile = false;
                    using (var fileStream = fileSystemConnector.GetFileStream(template.WebSettings.SiteLogo))
                    {
                        isFile = fileStream != null;
                    }
                    if (isFile)
                    {
                        WriteObject($"Processing {template.WebSettings.SiteLogo}");
                        AddFile(template.WebSettings.SiteLogo, templateFile, fileSystemConnector, connector);
                    }
                }
                if (template.Files.Any())
                {
                    foreach (var file in template.Files)
                    {
                        WriteObject($"Processing {file.Src}");
                        AddFile(file.Src, templateFile, fileSystemConnector, connector);
                    }
                }
            }
            if (templateFile.Connector is ICommitableFileConnector)
            {
                ((ICommitableFileConnector)templateFile.Connector).Commit();
            }
        }
Exemple #7
0
        public static byte[] GetFileBytes(FileConnectorBase connector, string fileName)
        {
            var container = String.Empty;

            if (fileName.Contains(@"\") || fileName.Contains(@"/"))
            {
                var tempFileName = fileName.Replace(@"/", @"\");
                container = fileName.Substring(0, tempFileName.LastIndexOf(@"\"));
                fileName  = fileName.Substring(tempFileName.LastIndexOf(@"\") + 1);
            }

            // add the default provided container (if any)
            if (!String.IsNullOrEmpty(container))
            {
                if (!String.IsNullOrEmpty(connector.GetContainer()))
                {
                    if (container.StartsWith("/"))
                    {
                        container = container.TrimStart("/".ToCharArray());
                    }

                    container = $@"{connector.GetContainer()}\{container}";
                }
            }
            else
            {
                container = connector.GetContainer();
            }

            var stream = connector.GetFileStream(fileName, container);

            if (stream == null)
            {
                //Decode the URL and try again
                fileName = WebUtility.UrlDecode(fileName);
                stream   = connector.GetFileStream(fileName, container);
            }

            if (stream == null)
            {
                throw new ArgumentException($"The specified filename '{fileName}' cannot be found");
            }

            byte[] returnData;

            using (var memStream = new MemoryStream())
            {
                stream.CopyTo(memStream);
                memStream.Position = 0;
                returnData         = memStream.ToArray();
            }
            if (stream != null)
            {
                stream.Dispose();
            }
            return(returnData);
        }
        public string ReadWorkflowFile(string fileName, FileConnectorBase fileReader)
        {
            //FileSystemConnector connector = new FileSystemConnector(null,workflowFolderName);

            //string fileContents = connector.GetFile(fileName);
            string fileContents = fileReader.GetFile(fileName);

            return(fileContents);
        }
 private void AddFile(string sourceName, ProvisioningHierarchy hierarchy, FileConnectorBase fileSystemConnector, FileConnectorBase connector)
 {
     using (var fs = fileSystemConnector.GetFileStream(sourceName))
     {
         var fileName   = sourceName.IndexOf("\\") > 0 ? sourceName.Substring(sourceName.LastIndexOf("\\") + 1) : sourceName;
         var folderName = sourceName.IndexOf("\\") > 0 ? sourceName.Substring(0, sourceName.LastIndexOf("\\")) : "";
         hierarchy.Connector.SaveFileStream(fileName, folderName, fs);
     }
 }
 protected XMLTemplateProvider(FileConnectorBase connector)
     : base(connector)
 {
 }
Exemple #11
0
        private void DownLoadFile(SharePointConnector reader, SharePointConnector readerRoot, FileConnectorBase writer, string webUrl, string asset)
        {
            // No file passed...leave
            if (String.IsNullOrEmpty(asset))
            {
                return;
            }

            SharePointConnector readerToUse;

            Model.File f = GetComposedLookFile(asset);

            // Strip the /sites/root part from /sites/root/lib/folder structure
            Uri u = new Uri(webUrl);

            if (f.Folder.IndexOf(u.PathAndQuery, StringComparison.InvariantCultureIgnoreCase) > -1)
            {
                f.Folder = f.Folder.Replace(u.PathAndQuery, "");
            }

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

            using (Stream s = readerToUse.GetFileStream(f.Src, f.Folder))
            {
                if (s != null)
                {
                    writer.SaveFileStream(f.Src, s);
                }
            }
        }
        private void DownLoadFile(SharePointConnector reader, SharePointConnector readerRoot, FileConnectorBase writer, string webUrl, string asset, PnPMonitoredScope scope)
        {
            // No file passed...leave
            if (String.IsNullOrEmpty(asset))
            {
                return;
            }

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

            SharePointConnector readerToUse;

            Model.File f = GetComposedLookFile(asset);

            // Strip the /sites/root part from /sites/root/lib/folder structure, special case for root site handling.
            Uri u = new Uri(webUrl);

            if (f.Folder.IndexOf(u.PathAndQuery, StringComparison.InvariantCultureIgnoreCase) > -1 && u.PathAndQuery.Length > 1)
            {
                f.Folder = f.Folder.Replace(u.PathAndQuery, "");
            }

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

            using (Stream s = readerToUse.GetFileStream(f.Src, f.Folder))
            {
                if (s != null)
                {
                    writer.SaveFileStream(f.Src, s);
                }
            }
        }
Exemple #13
0
 /// <summary>
 /// Constructor for ProvisioningTemplate class
 /// </summary>
 /// <param name="connector">FileConnectorBase object</param>
 public ProvisioningTemplate(FileConnectorBase connector) :
     this()
 {
     this.connector = connector;
 }
        private Microsoft.SharePoint.Client.ContentType CreateContentType(
            Web web,
            ProvisioningTemplate template,
            ContentType templateContentType,
            TokenParser parser,
            FileConnectorBase connector,
            PnPMonitoredScope scope,
            List <Microsoft.SharePoint.Client.ContentType> existingCTs = null,
            List <Microsoft.SharePoint.Client.Field> existingFields    = null,
            bool isNoScriptSite = false)
        {
            var name        = parser.ParseString(templateContentType.Name);
            var description = parser.ParseString(templateContentType.Description);
            var id          = parser.ParseString(templateContentType.Id);
            var group       = parser.ParseString(templateContentType.Group);

            var createdCT = web.CreateContentType(name, description, id, group);

            var fieldsRefsToProcess = templateContentType.FieldRefs.Select(fr => new
            {
                FieldRef      = fr,
                TemplateField = template.SiteFields.FirstOrDefault(tf => (Guid)XElement.Parse(parser.ParseString(tf.SchemaXml)).Attribute("ID") == fr.Id)
            }).Where(frData =>
                     frData.TemplateField == null || // Process fields refs if the target is not defined in the current template
                     frData.TemplateField.GetFieldProvisioningStep(parser) == _step // or process field ref only if the current step is matching
                     ).Select(fr => fr.FieldRef).ToArray();


            foreach (var fieldRef in fieldsRefsToProcess)
            {
                Microsoft.SharePoint.Client.Field field = null;
                try
                {
                    field = web.AvailableFields.GetById(fieldRef.Id);
                }
                catch (ArgumentException)
                {
                    if (!string.IsNullOrEmpty(fieldRef.Name))
                    {
                        field = web.AvailableFields.GetByInternalNameOrTitle(fieldRef.Name);
                    }
                }
                // Add it to the target content type
                // Notice that this code will fail if the field does not exist
                web.AddFieldToContentType(createdCT, field, fieldRef.Required, fieldRef.Hidden);
            }

            // Add new CTs
            parser.AddToken(new ContentTypeIdToken(web, name, id));

#if !ONPREMISES
            // Set resources
            if (templateContentType.Name.ContainsResourceToken())
            {
                createdCT.NameResource.SetUserResourceValue(templateContentType.Name, parser);
            }
            if (templateContentType.Description.ContainsResourceToken())
            {
                createdCT.DescriptionResource.SetUserResourceValue(templateContentType.Description, parser);
            }
#endif
            //Reorder the elements so that the new created Content Type has the same order as defined in the
            //template. The order can be different if the new Content Type inherits from another Content Type.
            //In this case the new Content Type has all field of the original Content Type and missing fields
            //will be added at the end. To fix this issue we ordering the fields once more.

            createdCT.FieldLinks.Reorder(templateContentType.FieldRefs.Select(fld => parser.ParseString(fld.Name)).ToArray());

            createdCT.ReadOnly = templateContentType.ReadOnly;
            createdCT.Hidden   = templateContentType.Hidden;
            createdCT.Sealed   = templateContentType.Sealed;

            if (templateContentType.DocumentSetTemplate == null)
            {
                // Only apply a document template when the contenttype is not a document set
                if (!string.IsNullOrEmpty(parser.ParseString(templateContentType.DocumentTemplate)))
                {
                    createdCT.DocumentTemplate = parser.ParseString(templateContentType.DocumentTemplate);
                }
            }

            // Skipping updates of forms as we can't upload forms to noscript sites
            if (!isNoScriptSite)
            {
                if (!string.IsNullOrEmpty(parser.ParseString(templateContentType.NewFormUrl)))
                {
                    createdCT.NewFormUrl = parser.ParseString(templateContentType.NewFormUrl);
                }
                if (!string.IsNullOrEmpty(parser.ParseString(templateContentType.EditFormUrl)))
                {
                    createdCT.EditFormUrl = parser.ParseString(templateContentType.EditFormUrl);
                }
                if (!string.IsNullOrEmpty(parser.ParseString(templateContentType.DisplayFormUrl)))
                {
                    createdCT.DisplayFormUrl = parser.ParseString(templateContentType.DisplayFormUrl);
                }
            }
            else
            {
                if (!string.IsNullOrEmpty(parser.ParseString(templateContentType.DisplayFormUrl)) ||
                    !string.IsNullOrEmpty(parser.ParseString(templateContentType.EditFormUrl)) ||
                    !string.IsNullOrEmpty(parser.ParseString(templateContentType.NewFormUrl)))
                {
                    // log message
                    scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_ContentTypes_SkipCustomFormUrls, name);
                }
            }

            createdCT.Update(true);
            web.Context.ExecuteQueryRetry();

            // If the CT is a DocumentSet
            if (templateContentType.DocumentSetTemplate != null)
            {
                // Retrieve a reference to the DocumentSet Content Type
                Microsoft.SharePoint.Client.DocumentSet.DocumentSetTemplate documentSetTemplate =
                    Microsoft.SharePoint.Client.DocumentSet.DocumentSetTemplate.GetDocumentSetTemplate(web.Context, createdCT);

                // Load the collections to allow for deletion scenarions
                web.Context.Load(documentSetTemplate, d => d.AllowedContentTypes, d => d.DefaultDocuments, d => d.SharedFields, d => d.WelcomePageFields);
                web.Context.ExecuteQueryRetry();

                if (!String.IsNullOrEmpty(templateContentType.DocumentSetTemplate.WelcomePage))
                {
                    // TODO: Customize the WelcomePage of the DocumentSet
                }

                // Add additional content types to the set of allowed content types
                bool hasDefaultDocumentContentTypeInTemplate = false;
                foreach (String ctId in templateContentType.DocumentSetTemplate.AllowedContentTypes)
                {
                    Microsoft.SharePoint.Client.ContentType ct = existingCTs.FirstOrDefault(c => c.StringId == ctId);
                    if (ct != null)
                    {
                        if (ct.Id.StringValue.Equals("0x0101", StringComparison.InvariantCultureIgnoreCase))
                        {
                            hasDefaultDocumentContentTypeInTemplate = true;
                        }

                        documentSetTemplate.AllowedContentTypes.Add(ct.Id);
                    }
                }
                // If the default document content type (0x0101) is not in our definition then remove it
                if (!hasDefaultDocumentContentTypeInTemplate)
                {
                    Microsoft.SharePoint.Client.ContentType ct = existingCTs.FirstOrDefault(c => c.StringId == "0x0101");
                    if (ct != null)
                    {
                        documentSetTemplate.AllowedContentTypes.Remove(ct.Id);
                    }
                }

                if (!isNoScriptSite)
                {
                    foreach (var doc in templateContentType.DocumentSetTemplate.DefaultDocuments)
                    {
                        Microsoft.SharePoint.Client.ContentType ct = existingCTs.FirstOrDefault(c => c.StringId == doc.ContentTypeId);
                        if (ct != null)
                        {
                            using (Stream fileStream = connector.GetFileStream(doc.FileSourcePath))
                            {
                                documentSetTemplate.DefaultDocuments.Add(doc.Name, ct.Id, ReadFullStream(fileStream));
                            }
                        }
                    }
                }
                else
                {
                    if (templateContentType.DocumentSetTemplate.DefaultDocuments.Any())
                    {
                        scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_ContentTypes_SkipDocumentSetDefaultDocuments, name);
                    }
                }

                foreach (var sharedField in templateContentType.DocumentSetTemplate.SharedFields)
                {
                    Microsoft.SharePoint.Client.Field field = existingFields.FirstOrDefault(f => f.Id == sharedField);
                    if (field != null)
                    {
                        documentSetTemplate.SharedFields.Add(field);
                    }
                }

                foreach (var welcomePageField in templateContentType.DocumentSetTemplate.WelcomePageFields)
                {
                    Microsoft.SharePoint.Client.Field field = existingFields.FirstOrDefault(f => f.Id == welcomePageField);
                    if (field != null)
                    {
                        documentSetTemplate.WelcomePageFields.Add(field);
                    }
                }

                documentSetTemplate.Update(true);
                web.Context.ExecuteQueryRetry();
            }
            else if (templateContentType.Id.StartsWith(BuiltInContentTypeId.Workflow2013Task + "00"))
            {
                // If the Workflow Task (SP2013) contains more than one outcomeChoice, the Form UI will not show
                // the buttons associated each to choices, but fallback to classic Save and Cancel buttons.
                // +"00" is used to target only inherited content types and not alter OOB
                var outcomeFields = web.Context.LoadQuery(
                    createdCT.Fields.Where(f => f.TypeAsString == "OutcomeChoice"));
                web.Context.ExecuteQueryRetry();

                if (outcomeFields.Any())
                {
                    // 2 OutcomeChoice specified means the user has certainly push its own.
                    // Let's remove the default outcome field
                    var field = outcomeFields.FirstOrDefault(f => f.StaticName == "TaskOutcome");
                    if (field != null)
                    {
                        var fl = createdCT.FieldLinks.GetById(field.Id);
                        fl.DeleteObject();
                        createdCT.Update(true);
                        web.Context.ExecuteQueryRetry();
                    }
                }
            }

            web.Context.Load(createdCT);
            web.Context.ExecuteQueryRetry();

            return(createdCT);
        }
Exemple #15
0
        /// <summary>
        /// Synchronizes Team's Photo
        /// </summary>
        /// <param name="scope">The PnP Provisioning Scope</param>
        /// <param name="parser">The PnP Token Parser</param>
        /// <param name="connector">The PnP File Connector</param>
        /// <param name="team">The Team settings, including security settings</param>
        /// <param name="teamId">The ID of the target Team</param>
        /// <param name="accessToken">The OAuth 2.0 Access Token</param>
        /// <returns>Whether the Apps have been provisioned or not</returns>
        private static bool SetTeamPhoto(PnPMonitoredScope scope, TokenParser parser, FileConnectorBase connector, Team team, string teamId, string accessToken)
        {
            if (!String.IsNullOrEmpty(team.Photo) && connector != null)
            {
                var photoPath  = parser.ParseString(team.Photo);
                var photoBytes = ConnectorFileHelper.GetFileBytes(connector, team.Photo);

                using (var mem = new MemoryStream())
                {
                    mem.Write(photoBytes, 0, photoBytes.Length);
                    mem.Position = 0;

                    HttpHelper.MakePostRequest(
                        $"{GraphHelper.MicrosoftGraphBaseURI}v1.0/groups/{teamId}/photo/$value",
                        mem, "image/jpeg", accessToken);
                }
            }

            return(true);
        }
Exemple #16
0
        private void AddResourceTokens(Web web, LocalizationCollection localizations, FileConnectorBase connector)
        {
            if (localizations != null && localizations.Any())
            {
                //https://github.com/SharePoint/PnP-Provisioning-Schema/issues/301
                //fixing issue to allow multiple resx files in the template. i.e:
                //<pnp:Localization LCID="1033" Name="core" ResourceFile="core.en-us.resx" />
                //<pnp:Localization LCID="3082" Name="core" ResourceFile="core.es-es.resx" />
                //<pnp:Localization LCID="1033" Name="intranet" ResourceFile="intranet.en-us.resx" />
                //<pnp:Localization LCID="3082" Name="intranet" ResourceFile="intranet.es-es.resx" />
                var resourcesFilesCount = localizations.GroupBy(l => l.Name).Count();

                // Read all resource keys in a list
                List <Tuple <string, uint, string> > resourceEntries = new List <Tuple <string, uint, string> >();
                foreach (var localizationEntry in localizations)
                {
                    var filePath = localizationEntry.ResourceFile;
                    using (var stream = connector.GetFileStream(filePath))
                    {
                        if (stream != null)
                        {
#if !NETSTANDARD2_0
                            using (ResXResourceReader resxReader = new ResXResourceReader(stream))
#else
                            using (ResourceReader resxReader = new ResourceReader(stream))
#endif
                            {
                                foreach (DictionaryEntry entry in resxReader)
                                {
                                    // One can have multiple resource files in a single file, by adding tokens with resource file name and without we allow both scenarios to resolve
                                    resourceEntries.Add(new Tuple <string, uint, string>($"{localizationEntry.Name}:{entry.Key}", (uint)localizationEntry.LCID, entry.Value.ToString().Replace("\"", "&quot;")));
                                    resourceEntries.Add(new Tuple <string, uint, string>(entry.Key.ToString(), (uint)localizationEntry.LCID, entry.Value.ToString().Replace("\"", "&quot;")));
                                }
                            }
                        }
                    }
                }

                var uniqueKeys = resourceEntries.Select(k => k.Item1).Distinct();
                foreach (var key in uniqueKeys)
                {
                    var matches = resourceEntries.Where(k => k.Item1 == key);
                    var entries = matches.Select(k => new ResourceEntry()
                    {
                        LCID = k.Item2, Value = k.Item3
                    }).ToList();
                    LocalizationToken token = new LocalizationToken(web, key, entries);

                    _tokens.Add(token);
                }
            }
        }
Exemple #17
0
 public TemplateProviderBase(FileConnectorBase connector)
 {
     this._connector = connector;
 }
        private static Microsoft.SharePoint.Client.ContentType CreateContentType(Web web, ContentType templateContentType, TokenParser parser, FileConnectorBase connector,
                                                                                 List <Microsoft.SharePoint.Client.ContentType> existingCTs = null, List <Microsoft.SharePoint.Client.Field> existingFields = null)
        {
            var name        = parser.ParseString(templateContentType.Name);
            var description = parser.ParseString(templateContentType.Description);
            var id          = parser.ParseString(templateContentType.Id);
            var group       = parser.ParseString(templateContentType.Group);

            var createdCT = web.CreateContentType(name, description, id, group);

            foreach (var fieldRef in templateContentType.FieldRefs)
            {
                var field = web.Fields.GetById(fieldRef.Id);
                web.AddFieldToContentType(createdCT, field, fieldRef.Required, fieldRef.Hidden);
            }

            //Reorder the elements so that the new created Content Type has the same order as defined in the
            //template. The order can be different if the new Content Type inherits from another Content Type.
            //In this case the new Content Type has all field of the original Content Type and missing fields
            //will be added at the end. To fix this issue we ordering the fields once more.
            createdCT.FieldLinks.Reorder(templateContentType.FieldRefs.Select(fld => fld.Name).ToArray());
            createdCT.Update(true);
            web.Context.ExecuteQueryRetry();

            createdCT.ReadOnly = templateContentType.ReadOnly;
            createdCT.Hidden   = templateContentType.Hidden;
            createdCT.Sealed   = templateContentType.Sealed;
            if (!string.IsNullOrEmpty(parser.ParseString(templateContentType.DocumentTemplate)))
            {
                createdCT.DocumentTemplate = parser.ParseString(templateContentType.DocumentTemplate);
            }
            if (!String.IsNullOrEmpty(templateContentType.NewFormUrl))
            {
                createdCT.NewFormUrl = templateContentType.NewFormUrl;
            }
            if (!String.IsNullOrEmpty(templateContentType.EditFormUrl))
            {
                createdCT.EditFormUrl = templateContentType.EditFormUrl;
            }
            if (!String.IsNullOrEmpty(templateContentType.DisplayFormUrl))
            {
                createdCT.DisplayFormUrl = templateContentType.DisplayFormUrl;
            }

            // If the CT is a DocumentSet
            if (templateContentType.DocumentSetTemplate != null)
            {
                // Retrieve a reference to the DocumentSet Content Type
                Microsoft.SharePoint.Client.DocumentSet.DocumentSetTemplate documentSetTemplate =
                    Microsoft.SharePoint.Client.DocumentSet.DocumentSetTemplate.GetDocumentSetTemplate(web.Context, createdCT);

                if (!String.IsNullOrEmpty(templateContentType.DocumentSetTemplate.WelcomePage))
                {
                    // TODO: Customize the WelcomePage of the DocumentSet
                }

                foreach (String ctId in templateContentType.DocumentSetTemplate.AllowedContentTypes)
                {
                    Microsoft.SharePoint.Client.ContentType ct = existingCTs.FirstOrDefault(c => c.StringId == ctId);
                    if (ct != null)
                    {
                        documentSetTemplate.AllowedContentTypes.Add(ct.Id);
                    }
                }

                foreach (var doc in templateContentType.DocumentSetTemplate.DefaultDocuments)
                {
                    Microsoft.SharePoint.Client.ContentType ct = existingCTs.FirstOrDefault(c => c.StringId == doc.ContentTypeId);
                    if (ct != null)
                    {
                        using (Stream fileStream = connector.GetFileStream(doc.FileSourcePath))
                        {
                            documentSetTemplate.DefaultDocuments.Add(doc.Name, ct.Id, ReadFullStream(fileStream));
                        }
                    }
                }

                foreach (var sharedField in templateContentType.DocumentSetTemplate.SharedFields)
                {
                    Microsoft.SharePoint.Client.Field field = existingFields.FirstOrDefault(f => f.Id == sharedField);
                    if (field != null)
                    {
                        documentSetTemplate.SharedFields.Add(field);
                    }
                }

                foreach (var welcomePageField in templateContentType.DocumentSetTemplate.WelcomePageFields)
                {
                    Microsoft.SharePoint.Client.Field field = existingFields.FirstOrDefault(f => f.Id == welcomePageField);
                    if (field != null)
                    {
                        documentSetTemplate.WelcomePageFields.Add(field);
                    }
                }

                documentSetTemplate.Update(true);
                web.Context.ExecuteQueryRetry();
            }

            web.Context.Load(createdCT);
            web.Context.ExecuteQueryRetry();

            return(createdCT);
        }
        public static byte[] GetFileBytes(FileConnectorBase connector, string fileName)
        {
            var container = String.Empty;

            if (fileName.Contains(@"\") || fileName.Contains(@"/"))
            {
                var tempFileName = fileName.Replace(@"/", @"\");
                container = fileName.Substring(0, tempFileName.LastIndexOf(@"\"));
                fileName  = fileName.Substring(tempFileName.LastIndexOf(@"\") + 1);
            }

            // add the default provided container (if any)
            if (!String.IsNullOrEmpty(container))
            {
                if (!String.IsNullOrEmpty(connector.GetContainer()))
                {
                    if (container.StartsWith("/"))
                    {
                        container = container.TrimStart("/".ToCharArray());
                    }

#if !NETSTANDARD2_0
                    if (connector.GetType() == typeof(Connectors.AzureStorageConnector))
                    {
                        if (connector.GetContainer().EndsWith("/"))
                        {
                            container = $@"{connector.GetContainer()}{container}";
                        }
                        else
                        {
                            container = $@"{connector.GetContainer()}/{container}";
                        }
                    }
                    else
                    {
                        container = $@"{connector.GetContainer()}\{container}";
                    }
#else
                    container = $@"{connector.GetContainer()}\{container}";
#endif
                }
            }
            else
            {
                container = connector.GetContainer();
            }

            var stream = connector.GetFileStream(fileName, container);
            if (stream == null)
            {
                //Decode the URL and try again
                fileName = WebUtility.UrlDecode(fileName);
                stream   = connector.GetFileStream(fileName, container);
            }
            byte[] returnData;

            using (var memStream = new MemoryStream())
            {
                stream.CopyTo(memStream);
                memStream.Position = 0;
                returnData         = memStream.ToArray();
            }
            if (stream != null)
            {
                stream.Dispose();
            }
            return(returnData);
        }
        private static Microsoft.SharePoint.Client.ContentType CreateContentType(Web web, ContentType templateContentType, TokenParser parser, FileConnectorBase connector, PnPMonitoredScope scope,
                                                                                 List <Microsoft.SharePoint.Client.ContentType> existingCTs = null, List <Microsoft.SharePoint.Client.Field> existingFields = null, bool isNoScriptSite = false)
        {
            var name        = parser.ParseString(templateContentType.Name);
            var description = parser.ParseString(templateContentType.Description);
            var id          = parser.ParseString(templateContentType.Id);
            var group       = parser.ParseString(templateContentType.Group);

            var createdCT = web.CreateContentType(name, description, id, group);

            foreach (var fieldRef in templateContentType.FieldRefs)
            {
                Microsoft.SharePoint.Client.Field field = null;
                try
                {
                    field = web.AvailableFields.GetById(fieldRef.Id);
                }
                catch (ArgumentException)
                {
                    if (!string.IsNullOrEmpty(fieldRef.Name))
                    {
                        field = web.AvailableFields.GetByInternalNameOrTitle(fieldRef.Name);
                    }
                }
                // Add it to the target content type
                // Notice that this code will fail if the field does not exist
                web.AddFieldToContentType(createdCT, field, fieldRef.Required, fieldRef.Hidden);
            }

            // Add new CTs
            parser.AddToken(new ContentTypeIdToken(web, name, id));

#if !ONPREMISES
            // Set resources
            if (templateContentType.Name.ContainsResourceToken())
            {
                createdCT.NameResource.SetUserResourceValue(templateContentType.Name, parser);
            }
            if (templateContentType.Description.ContainsResourceToken())
            {
                createdCT.DescriptionResource.SetUserResourceValue(templateContentType.Description, parser);
            }
#endif
            //Reorder the elements so that the new created Content Type has the same order as defined in the
            //template. The order can be different if the new Content Type inherits from another Content Type.
            //In this case the new Content Type has all field of the original Content Type and missing fields
            //will be added at the end. To fix this issue we ordering the fields once more.

            createdCT.FieldLinks.Reorder(templateContentType.FieldRefs.Select(fld => parser.ParseString(fld.Name)).ToArray());

            createdCT.ReadOnly = templateContentType.ReadOnly;
            createdCT.Hidden   = templateContentType.Hidden;
            createdCT.Sealed   = templateContentType.Sealed;

            if (templateContentType.DocumentSetTemplate == null)
            {
                // Only apply a document template when the contenttype is not a document set
                if (!string.IsNullOrEmpty(parser.ParseString(templateContentType.DocumentTemplate)))
                {
                    createdCT.DocumentTemplate = parser.ParseString(templateContentType.DocumentTemplate);
                }
            }

            // Skipping updates of forms as we can't upload forms to noscript sites
            if (!isNoScriptSite)
            {
                if (!string.IsNullOrEmpty(parser.ParseString(templateContentType.NewFormUrl)))
                {
                    createdCT.NewFormUrl = parser.ParseString(templateContentType.NewFormUrl);
                }
                if (!string.IsNullOrEmpty(parser.ParseString(templateContentType.EditFormUrl)))
                {
                    createdCT.EditFormUrl = parser.ParseString(templateContentType.EditFormUrl);
                }
                if (!string.IsNullOrEmpty(parser.ParseString(templateContentType.DisplayFormUrl)))
                {
                    createdCT.DisplayFormUrl = parser.ParseString(templateContentType.DisplayFormUrl);
                }
            }
            else
            {
                if (!string.IsNullOrEmpty(parser.ParseString(templateContentType.DisplayFormUrl)) ||
                    !string.IsNullOrEmpty(parser.ParseString(templateContentType.EditFormUrl)) ||
                    !string.IsNullOrEmpty(parser.ParseString(templateContentType.NewFormUrl)))
                {
                    // log message
                    scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_ContentTypes_SkipCustomFormUrls, name);
                }
            }

            createdCT.Update(true);
            web.Context.ExecuteQueryRetry();

            // If the CT is a DocumentSet
            if (templateContentType.DocumentSetTemplate != null)
            {
                // Retrieve a reference to the DocumentSet Content Type
                Microsoft.SharePoint.Client.DocumentSet.DocumentSetTemplate documentSetTemplate =
                    Microsoft.SharePoint.Client.DocumentSet.DocumentSetTemplate.GetDocumentSetTemplate(web.Context, createdCT);

                // Load the collections to allow for deletion scenarions
                web.Context.Load(documentSetTemplate, d => d.AllowedContentTypes, d => d.DefaultDocuments, d => d.SharedFields, d => d.WelcomePageFields);
                web.Context.ExecuteQueryRetry();

                if (!String.IsNullOrEmpty(templateContentType.DocumentSetTemplate.WelcomePage))
                {
                    // TODO: Customize the WelcomePage of the DocumentSet
                }

                // Add additional content types to the set of allowed content types
                bool hasDefaultDocumentContentTypeInTemplate = false;
                foreach (String ctId in templateContentType.DocumentSetTemplate.AllowedContentTypes)
                {
                    Microsoft.SharePoint.Client.ContentType ct = existingCTs.FirstOrDefault(c => c.StringId == ctId);
                    if (ct != null)
                    {
                        if (ct.Id.StringValue.Equals("0x0101", StringComparison.InvariantCultureIgnoreCase))
                        {
                            hasDefaultDocumentContentTypeInTemplate = true;
                        }

                        documentSetTemplate.AllowedContentTypes.Add(ct.Id);
                    }
                }
                // If the default document content type (0x0101) is not in our definition then remove it
                if (!hasDefaultDocumentContentTypeInTemplate)
                {
                    Microsoft.SharePoint.Client.ContentType ct = existingCTs.FirstOrDefault(c => c.StringId == "0x0101");
                    if (ct != null)
                    {
                        documentSetTemplate.AllowedContentTypes.Remove(ct.Id);
                    }
                }

                if (!isNoScriptSite)
                {
                    foreach (var doc in templateContentType.DocumentSetTemplate.DefaultDocuments)
                    {
                        Microsoft.SharePoint.Client.ContentType ct = existingCTs.FirstOrDefault(c => c.StringId == doc.ContentTypeId);
                        if (ct != null)
                        {
                            using (Stream fileStream = connector.GetFileStream(doc.FileSourcePath))
                            {
                                documentSetTemplate.DefaultDocuments.Add(doc.Name, ct.Id, ReadFullStream(fileStream));
                            }
                        }
                    }
                }
                else
                {
                    if (templateContentType.DocumentSetTemplate.DefaultDocuments.Any())
                    {
                        scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_ContentTypes_SkipDocumentSetDefaultDocuments, name);
                    }
                }

                foreach (var sharedField in templateContentType.DocumentSetTemplate.SharedFields)
                {
                    Microsoft.SharePoint.Client.Field field = existingFields.FirstOrDefault(f => f.Id == sharedField);
                    if (field != null)
                    {
                        documentSetTemplate.SharedFields.Add(field);
                    }
                }

                foreach (var welcomePageField in templateContentType.DocumentSetTemplate.WelcomePageFields)
                {
                    Microsoft.SharePoint.Client.Field field = existingFields.FirstOrDefault(f => f.Id == welcomePageField);
                    if (field != null)
                    {
                        documentSetTemplate.WelcomePageFields.Add(field);
                    }
                }

                documentSetTemplate.Update(true);
                web.Context.ExecuteQueryRetry();
            }

            web.Context.Load(createdCT);
            web.Context.ExecuteQueryRetry();

            return(createdCT);
        }
Exemple #21
0
        /// <summary>
        /// Creates a new Team from a PnP Provisioning Schema definition
        /// </summary>
        /// <param name="scope">The PnP Provisioning Scope</param>
        /// <param name="parser">The PnP Token Parser</param>
        /// <param name="connector">The PnP File connector</param>
        /// <param name="team">The Team to provision</param>
        /// <param name="accessToken">The OAuth 2.0 Access Token</param>
        /// <returns>The provisioned Team as a JSON object</returns>
        private static JToken CreateTeamFromProvisioningSchema(PnPMonitoredScope scope, TokenParser parser, FileConnectorBase connector, Team team, string accessToken)
        {
            String teamId = null;

            // If we have to Clone an existing Team
            if (!String.IsNullOrWhiteSpace(team.CloneFrom))
            {
                teamId = CloneTeam(scope, team, parser, accessToken);
            }
            // If we start from an already existing Group
            else if (!String.IsNullOrEmpty(team.GroupId))
            {
                // We need to parse the GroupId, if it is a token
                var parsedGroupId = parser.ParseString(team.GroupId);

                // Check if the Group exists
                if (GroupExistsById(scope, parsedGroupId, accessToken))
                {
                    // Then promote the Group into a Team or update it, if it already exists. Patching a team doesn't return an ID, so use the parsedGroupId directly (teamId and groupId are the same).
                    teamId = CreateOrUpdateTeamFromGroup(scope, team, parser, parsedGroupId, accessToken) ?? parsedGroupId;
                }
                else
                {
                    // Log the exception and return NULL (i.e. cancel)
                    scope.LogError(CoreResources.Provisioning_ObjectHandlers_Teams_Team_GroupDoesNotExists, parsedGroupId);
                    return(null);
                }
            }
            // Otherwise create a Team from scratch
            else
            {
                teamId = CreateOrUpdateTeam(scope, team, parser, accessToken);
            }

            if (!String.IsNullOrEmpty(teamId))
            {
                // Wait to be sure that the Team is ready before configuring it
                WaitForTeamToBeReady(accessToken, teamId);

                // And now we configure security, channels, and apps
                if (!SetGroupSecurity(scope, team, teamId, accessToken))
                {
                    return(null);
                }
                if (!SetTeamChannels(scope, parser, team, teamId, accessToken))
                {
                    return(null);
                }
                if (!SetTeamApps(scope, team, teamId, accessToken))
                {
                    return(null);
                }

                // So far the Team's photo cannot be set if we don't have an already existing mailbox
                // if (!SetTeamPhoto(scope, parser, connector, team, teamId, accessToken)) return null;

                // Call Archive or Unarchive for the current Team
                ArchiveTeam(scope, teamId, team.Archived, accessToken);

                try
                {
                    // Get the whole Team that we just created and return it back as the method result
                    return(JToken.Parse(HttpHelper.MakeGetRequestForString($"{GraphHelper.MicrosoftGraphBaseURI}v1.0/teams/{teamId}", accessToken)));
                }
                catch (Exception ex)
                {
                    scope.LogError(CoreResources.Provisioning_ObjectHandlers_Teams_Team_FetchingError, ex.Message);
                }
            }

            return(null);
        }
Exemple #22
0
 public ProvisioningTemplate()
 {
     this.connector = new FileSystemConnector(".", "");
 }
        /// <summary>
        /// Synchronizes User's Photo
        /// </summary>
        /// <param name="scope">The PnP Provisioning Scope</param>
        /// <param name="parser">The PnP Token Parser</param>
        /// <param name="connector">The PnP file connector</param>
        /// <param name="user">The target User</param>
        /// <param name="userId">The ID of the target User</param>
        /// <param name="accessToken">The OAuth 2.0 Access Token</param>
        /// <returns>Whether the Photo has been updated or not</returns>
        private static bool SetUserPhoto(PnPMonitoredScope scope, TokenParser parser, FileConnectorBase connector, Model.AzureActiveDirectory.User user, string userId, string accessToken)
        {
            Boolean result = false;

            if (!String.IsNullOrEmpty(user.ProfilePhoto) && connector != null)
            {
                var photoPath  = parser.ParseString(user.ProfilePhoto);
                var photoBytes = ConnectorFileHelper.GetFileBytes(connector, user.ProfilePhoto);

                using (var mem = new MemoryStream())
                {
                    mem.Write(photoBytes, 0, photoBytes.Length);
                    mem.Position = 0;

                    HttpHelper.MakePostRequest(
                        $"{GraphHelper.MicrosoftGraphBaseURI}v1.0/users/{userId}/photo/$value",
                        mem, "image/jpeg", accessToken);
                }
            }

            return(result);
        }
        internal static TokenParser ProcessSiteScripts(Tenant tenant, ProvisioningTenant provisioningTenant, FileConnectorBase connector, TokenParser parser, PnPMonitoredScope scope, ProvisioningMessagesDelegate messagesDelegate)
        {
            if (provisioningTenant.SiteScripts != null && provisioningTenant.SiteScripts.Any())
            {
                var existingScripts = tenant.GetSiteScripts();
                tenant.Context.Load(existingScripts);
                tenant.Context.ExecuteQueryRetry();

                foreach (var siteScript in provisioningTenant.SiteScripts)
                {
                    var parsedTitle       = parser.ParseString(siteScript.Title);
                    var parsedDescription = parser.ParseString(siteScript.Description);
                    var parsedContent     = parser.ParseString(System.Text.Encoding.UTF8.GetString(ConnectorFileHelper.GetFileBytes(connector, parser.ParseString(siteScript.JsonFilePath))));
                    var existingScript    = existingScripts.FirstOrDefault(s => s.Title == parsedTitle);

                    messagesDelegate?.Invoke($"Processing site script {parsedTitle}", ProvisioningMessageType.Progress);

                    if (existingScript == null)
                    {
                        TenantSiteScriptCreationInfo siteScriptCreationInfo = new TenantSiteScriptCreationInfo
                        {
                            Title       = parsedTitle,
                            Description = parsedDescription,
                            Content     = parsedContent
                        };
                        var script = tenant.CreateSiteScript(siteScriptCreationInfo);
                        tenant.Context.Load(script);
                        tenant.Context.ExecuteQueryRetry();
                        parser.AddToken(new SiteScriptIdToken(null, parsedTitle, script.Id));
                    }
                    else
                    {
                        if (siteScript.Overwrite)
                        {
                            var existingId = existingScript.Id;
                            existingScript = Tenant.GetSiteScript(tenant.Context, existingId);
                            tenant.Context.ExecuteQueryRetry();

                            existingScript.Content     = parsedContent;
                            existingScript.Title       = parsedTitle;
                            existingScript.Description = parsedDescription;
                            tenant.UpdateSiteScript(existingScript);
                            tenant.Context.ExecuteQueryRetry();
                            var existingToken = parser.Tokens.OfType <SiteScriptIdToken>().FirstOrDefault(t => t.GetReplaceValue() == existingId.ToString());
                            if (existingToken != null)
                            {
                                parser.Tokens.Remove(existingToken);
                            }
                            parser.AddToken(new SiteScriptIdToken(null, parsedTitle, existingId));
                        }
                    }
                }
            }
            return(parser);
        }
        private void AddResourceTokens(Web web, LocalizationCollection localizations, FileConnectorBase connector)
        {
            if (localizations != null && localizations.Any())
            {
                // Read all resource keys in a list
                List <Tuple <string, uint, string> > resourceEntries = new List <Tuple <string, uint, string> >();
                foreach (var localizationEntry in localizations)
                {
                    var filePath = localizationEntry.ResourceFile;
                    using (var stream = connector.GetFileStream(filePath))
                    {
                        if (stream != null)
                        {
#if !NETSTANDARD2_0
                            using (ResXResourceReader resxReader = new ResXResourceReader(stream))
#else
                            using (ResourceReader resxReader = new ResourceReader(stream))
#endif
                            {
                                foreach (DictionaryEntry entry in resxReader)
                                {
                                    resourceEntries.Add(new Tuple <string, uint, string>(entry.Key.ToString(), (uint)localizationEntry.LCID, entry.Value.ToString().Replace("\"", "&quot;")));
                                }
                            }
                        }
                    }
                }

                var uniqueKeys = resourceEntries.Select(k => k.Item1).Distinct();
                foreach (var key in uniqueKeys)
                {
                    var matches = resourceEntries.Where(k => k.Item1 == key);
                    var entries = matches.Select(k => new ResourceEntry()
                    {
                        LCID = k.Item2, Value = k.Item3
                    }).ToList();
                    LocalizationToken token = new LocalizationToken(web, key, entries);

                    _tokens.Add(token);
                }
            }
        }
        private static Microsoft.SharePoint.Client.ContentType CreateContentType(Web web, ContentType templateContentType, TokenParser parser, FileConnectorBase connector,
                                                                                 List <Microsoft.SharePoint.Client.ContentType> existingCTs = null, List <Microsoft.SharePoint.Client.Field> existingFields = null)
        {
            var name        = parser.ParseString(templateContentType.Name);
            var description = parser.ParseString(templateContentType.Description);
            var id          = parser.ParseString(templateContentType.Id);
            var group       = parser.ParseString(templateContentType.Group);

            var createdCT = web.CreateContentType(name, description, id, group);

            foreach (var fieldRef in templateContentType.FieldRefs)
            {
                var field = web.Fields.GetById(fieldRef.Id);
                web.AddFieldToContentType(createdCT, field, fieldRef.Required, fieldRef.Hidden);
            }

            createdCT.ReadOnly = templateContentType.ReadOnly;
            createdCT.Hidden   = templateContentType.Hidden;
            createdCT.Sealed   = templateContentType.Sealed;
            if (!string.IsNullOrEmpty(parser.ParseString(templateContentType.DocumentTemplate)))
            {
                createdCT.DocumentTemplate = parser.ParseString(templateContentType.DocumentTemplate);
            }
            if (!String.IsNullOrEmpty(templateContentType.NewFormUrl))
            {
                createdCT.NewFormUrl = templateContentType.NewFormUrl;
            }
            if (!String.IsNullOrEmpty(templateContentType.EditFormUrl))
            {
                createdCT.EditFormUrl = templateContentType.EditFormUrl;
            }
            if (!String.IsNullOrEmpty(templateContentType.DisplayFormUrl))
            {
                createdCT.DisplayFormUrl = templateContentType.DisplayFormUrl;
            }

            // If the CT is a DocumentSet
            if (templateContentType.DocumentSetTemplate != null)
            {
                // Retrieve a reference to the DocumentSet Content Type
                Microsoft.SharePoint.Client.DocumentSet.DocumentSetTemplate documentSetTemplate =
                    Microsoft.SharePoint.Client.DocumentSet.DocumentSetTemplate.GetDocumentSetTemplate(web.Context, createdCT);

                if (!String.IsNullOrEmpty(templateContentType.DocumentSetTemplate.WelcomePage))
                {
                    // TODO: Customize the WelcomePage of the DocumentSet
                }

                foreach (String ctId in templateContentType.DocumentSetTemplate.AllowedContentTypes)
                {
                    Microsoft.SharePoint.Client.ContentType ct = existingCTs.FirstOrDefault(c => c.StringId == ctId);
                    if (ct != null)
                    {
                        documentSetTemplate.AllowedContentTypes.Add(ct.Id);
                    }
                }

                foreach (var doc in templateContentType.DocumentSetTemplate.DefaultDocuments)
                {
                    Microsoft.SharePoint.Client.ContentType ct = existingCTs.FirstOrDefault(c => c.StringId == doc.ContentTypeId);
                    if (ct != null)
                    {
                        using (Stream fileStream = connector.GetFileStream(doc.FileSourcePath))
                        {
                            documentSetTemplate.DefaultDocuments.Add(doc.Name, ct.Id, ReadFullStream(fileStream));
                        }
                    }
                }

                foreach (var sharedField in templateContentType.DocumentSetTemplate.SharedFields)
                {
                    Microsoft.SharePoint.Client.Field field = existingFields.FirstOrDefault(f => f.Id == sharedField);
                    if (field != null)
                    {
                        documentSetTemplate.SharedFields.Add(field);
                    }
                }

                foreach (var welcomePageField in templateContentType.DocumentSetTemplate.WelcomePageFields)
                {
                    Microsoft.SharePoint.Client.Field field = existingFields.FirstOrDefault(f => f.Id == welcomePageField);
                    if (field != null)
                    {
                        documentSetTemplate.WelcomePageFields.Add(field);
                    }
                }

                documentSetTemplate.Update(true);
                web.Context.ExecuteQueryRetry();
            }

            web.Context.Load(createdCT);
            web.Context.ExecuteQueryRetry();

            return(createdCT);
        }
Exemple #27
0
        internal static void ProcessFiles(ProvisioningHierarchy tenantTemplate, string templateFileName, FileConnectorBase fileSystemConnector, FileConnectorBase connector, Action <string> progress)
        {
            var templateFile = ReadTenantTemplate.LoadProvisioningHierarchyFromFile(templateFileName, null, null);

            if (tenantTemplate.Tenant?.AppCatalog != null)
            {
                foreach (var app in tenantTemplate.Tenant.AppCatalog.Packages)
                {
                    progress($"Processing {app.Src}");
                    AddFile(app.Src, templateFile, fileSystemConnector, connector);
                }
            }
            if (tenantTemplate.Tenant?.SiteScripts != null)
            {
                foreach (var siteScript in tenantTemplate.Tenant.SiteScripts)
                {
                    progress($"Processing {siteScript.JsonFilePath}");
                    AddFile(siteScript.JsonFilePath, templateFile, fileSystemConnector, connector);
                }
            }
            if (tenantTemplate.Localizations != null && tenantTemplate.Localizations.Any())
            {
                foreach (var location in tenantTemplate.Localizations)
                {
                    progress($"Processing {location.ResourceFile}");
                    AddFile(location.ResourceFile, templateFile, fileSystemConnector, connector);
                }
            }
            foreach (var template in tenantTemplate.Templates)
            {
                if (template.WebSettings != null && !String.IsNullOrEmpty(template.WebSettings.SiteLogo))
                {
                    // is it a file?
                    var isFile = false;
                    try
                    {
                        using (var fileStream = fileSystemConnector.GetFileStream(template.WebSettings.SiteLogo))
                        {
                            isFile = fileStream != null;
                        }
                    }
                    catch { }
                    if (isFile)
                    {
                        progress($"Processing {template.WebSettings.SiteLogo}");
                        AddFile(template.WebSettings.SiteLogo, templateFile, fileSystemConnector, connector);
                    }
                }
                if (template.Files.Any())
                {
                    foreach (var file in template.Files)
                    {
                        progress($"Processing {file.Src}");
                        AddFile(file.Src, templateFile, fileSystemConnector, connector);
                    }
                }
                if (template.Lists.Any())
                {
                    foreach (var list in template.Lists)
                    {
                        if (list.DataRows.Any())
                        {
                            foreach (var dataRow in list.DataRows)
                            {
                                if (dataRow.Attachments.Any())
                                {
                                    progress("List attachments");
                                    foreach (var attachment in dataRow.Attachments)
                                    {
                                        AddFile(attachment.Src, templateFile, fileSystemConnector, connector);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (templateFile.Connector is ICommitableFileConnector)
            {
                ((ICommitableFileConnector)templateFile.Connector).Commit();
            }
        }
Exemple #28
0
        /// <summary>
        /// Creates a new Team from a PnP Provisioning Schema definition
        /// </summary>
        /// <param name="scope">The PnP Provisioning Scope</param>
        /// <param name="parser">The PnP Token Parser</param>
        /// <param name="connector">The PnP File connector</param>
        /// <param name="team">The Team to provision</param>
        /// <param name="accessToken">The OAuth 2.0 Access Token</param>
        /// <returns>The provisioned Team as a JSON object</returns>
        private static JToken CreateTeamFromProvisioningSchema(PnPMonitoredScope scope, TokenParser parser, FileConnectorBase connector, Team team, string accessToken)
        {
            String teamId = null;

            // If we have to Clone an existing Team
            if (!String.IsNullOrWhiteSpace(team.CloneFrom))
            {
                teamId = CloneTeam(scope, team, parser, accessToken);
            }
            // If we start from an already existing Group
            else if (!String.IsNullOrEmpty(team.GroupId))
            {
                // We need to parse the GroupId, if it is a token
                var parsedGroupId = parser.ParseString(team.GroupId);

                // Check if the Group exists
                if (GroupExistsById(scope, parsedGroupId, accessToken))
                {
                    // Then promote the Group into a Team or update it, if it already exists
                    teamId = CreateOrUpdateTeamFromGroup(scope, team, parser, parsedGroupId, accessToken);
                }
                else
                {
                    // Log the exception and return NULL (i.e. cancel)
                    scope.LogError(CoreResources.Provisioning_ObjectHandlers_Teams_Team_GroupDoesNotExists, parsedGroupId);
                    return(null);
                }
            }
            // Otherwise create a Team from scratch
            else
            {
                teamId = CreateOrUpdateTeam(scope, team, parser, accessToken);
            }

            if (!String.IsNullOrEmpty(teamId))
            {
                // Wait for the Team to be ready
                Boolean wait       = true;
                Int32   iterations = 0;
                while (wait)
                {
                    iterations++;

                    try
                    {
                        var jsonOwners = HttpHelper.MakeGetRequestForString($"{GraphHelper.MicrosoftGraphBaseURI}v1.0/groups/{teamId}/owners?$select=id", accessToken);
                        if (!String.IsNullOrEmpty(jsonOwners))
                        {
                            wait = false;
                        }
                    }
                    catch (Exception)
                    {
                        // In case of exception wait for 5 secs
                        System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5));
                    }

                    // Don't wait more than 1 minute
                    if (iterations > 12)
                    {
                        wait = false;
                    }
                }

                // And now we configure security, channels, and apps
                if (!SetGroupSecurity(scope, team, teamId, accessToken))
                {
                    return(null);
                }
                if (!SetTeamChannels(scope, parser, team, teamId, accessToken))
                {
                    return(null);
                }
                if (!SetTeamApps(scope, team, teamId, accessToken))
                {
                    return(null);
                }

                // So far the Team's photo cannot be set if we don't have an already existing mailbox
                // if (!SetTeamPhoto(scope, parser, connector, team, teamId, accessToken)) return null;

                // Call Archive or Unarchive for the current Team
                ArchiveTeam(scope, teamId, team.Archived, accessToken);

                try
                {
                    // Get the whole Team that we just created and return it back as the method result
                    return(JToken.Parse(HttpHelper.MakeGetRequestForString($"{GraphHelper.MicrosoftGraphBaseURI}v1.0/teams/{teamId}", accessToken)));
                }
                catch (Exception ex)
                {
                    scope.LogError(CoreResources.Provisioning_ObjectHandlers_Teams_Team_FetchingError, ex.Message);
                }
            }

            return(null);
        }
        public static TokenParser ProcessApps(Tenant tenant, ProvisioningTenant provisioningTenant, FileConnectorBase connector, TokenParser parser, PnPMonitoredScope scope, ProvisioningTemplateApplyingInformation applyingInformation, ProvisioningMessagesDelegate messagesDelegate)
        {
            if (provisioningTenant.AppCatalog != null && provisioningTenant.AppCatalog.Packages.Count > 0)
            {
                var rootSiteUrl = tenant.GetRootSiteUrl();
                tenant.Context.ExecuteQueryRetry();
                using (var context = ((ClientContext)tenant.Context).Clone(rootSiteUrl.Value, applyingInformation.AccessTokens))
                {
                    var web = context.Web;

                    Uri appCatalogUri = null;

                    try
                    {
                        appCatalogUri = web.GetAppCatalog();
                    }
                    catch (System.Net.WebException ex)
                    {
                        if (ex.Response != null)
                        {
                            var httpResponse = ex.Response as System.Net.HttpWebResponse;
                            if (httpResponse != null && httpResponse.StatusCode == HttpStatusCode.Unauthorized)
                            {
                                // Ignore any security exception and simply keep
                                // the AppCatalog URI null
                            }
                            else
                            {
                                throw ex;
                            }
                        }
                        else
                        {
                            throw ex;
                        }
                    }

                    if (appCatalogUri != null)
                    {
                        var manager = new AppManager(context);

                        foreach (var app in provisioningTenant.AppCatalog.Packages)
                        {
                            AppMetadata appMetadata = null;

                            if (app.Action == PackageAction.Upload || app.Action == PackageAction.UploadAndPublish)
                            {
                                var appSrc   = parser.ParseString(app.Src);
                                var appBytes = ConnectorFileHelper.GetFileBytes(connector, appSrc);

                                var hash = string.Empty;
                                using (var memoryStream = new MemoryStream(appBytes))
                                {
                                    hash = CalculateHash(memoryStream);
                                }

                                var exists = false;
                                var appId  = Guid.Empty;

                                using (var appCatalogContext = ((ClientContext)tenant.Context).Clone(appCatalogUri, applyingInformation.AccessTokens))
                                {
                                    // check if the app already is present
                                    var appList   = appCatalogContext.Web.GetListByUrl("AppCatalog");
                                    var camlQuery = new CamlQuery
                                    {
                                        ViewXml = string.Format(appExistsQuery, hash)
                                    };
                                    var items = appList.GetItems(camlQuery);
                                    appCatalogContext.Load(items, i => i.IncludeWithDefaultProperties());
                                    appCatalogContext.ExecuteQueryRetry();
                                    if (items.Count > 0)
                                    {
                                        exists = true;
                                        appId  = Guid.Parse(items[0].FieldValues["UniqueId"].ToString());
                                    }
                                }
                                var appFilename = appSrc.Substring(appSrc.LastIndexOf('\\') + 1);

                                if (!exists)
                                {
                                    messagesDelegate?.Invoke($"Processing solution {app.Src}", ProvisioningMessageType.Progress);
                                    appMetadata = manager.Add(appBytes, appFilename, app.Overwrite, timeoutSeconds: 500);
                                }
                                else
                                {
                                    messagesDelegate?.Invoke($"Skipping existing solution {app.Src}", ProvisioningMessageType.Progress);
                                    appMetadata = manager.GetAvailable().FirstOrDefault(a => a.Id == appId);
                                }
                                if (appMetadata != null)
                                {
                                    parser.AddToken(new AppPackageIdToken(web, appFilename, appMetadata.Id));
                                    parser.AddToken(new AppPackageIdToken(web, appMetadata.Title, appMetadata.Id));
                                }
                            }

                            if (app.Action == PackageAction.Publish || app.Action == PackageAction.UploadAndPublish)
                            {
                                if (appMetadata == null)
                                {
                                    appMetadata = manager.GetAvailable()
                                                  .FirstOrDefault(a => a.Id == Guid.Parse(parser.ParseString(app.PackageId)));
                                }
                                if (appMetadata != null)
                                {
                                    manager.Deploy(appMetadata, app.SkipFeatureDeployment);
                                }
                                else
                                {
                                    scope.LogError("Referenced App Package {0} not available", app.PackageId);
                                    throw new Exception($"Referenced App Package {app.PackageId} not available");
                                }
                            }

                            if (app.Action == PackageAction.Remove)
                            {
                                var appId = Guid.Parse(parser.ParseString(app.PackageId));

                                // Get the apps already installed in the site
                                var appExists = manager.GetAvailable()?.Any(a => a.Id == appId);

                                if (appExists.HasValue && appExists.Value)
                                {
                                    manager.Remove(appId);
                                }
                                else
                                {
                                    messagesDelegate?.Invoke($"App Package with ID {appId} does not exist in the AppCatalog and cannot be removed!", ProvisioningMessageType.Warning);
                                }
                            }
                        }
                    }
                    else
                    {
                        messagesDelegate?.Invoke($"Tenant app catalog doesn't exist. ALM step will be skipped!", ProvisioningMessageType.Warning);
                    }
                }
            }
            return(parser);
        }
 public void DownloadWorkflowFile(string workflowID, FileConnectorBase writer, Stream fileStream, WorkflowLevel workflowLevel)
 {
     writer.SaveFileStream(workflowID + ".xml", workflowFolderName, fileStream);
 }