Example #1
0
 /// <summary>
 /// Extends a <see cref="PnPContext"/> with Microsoft 365 admin functionality
 /// </summary>
 /// <param name="context"><see cref="PnPContext"/> to extend</param>
 /// <returns>An <see cref="IMicrosoft365Admin"/> instance enabling Microsoft 365 admin operations</returns>
 public static IMicrosoft365Admin GetMicrosoft365Admin(this PnPContext context)
 {
     return(new Microsoft365Admin(context));
 }
Example #2
0
 /// <summary>
 /// Extends a <see cref="PnPContext"/> with tenant Application Lifecycle Management (ALM) functionality
 /// </summary>
 /// <param name="context"><see cref="PnPContext"/> to extend</param>
 /// <returns>An <see cref="ITenantAppManager"/> instance enabling tenant app catalog operations</returns>
 public static ITenantAppManager GetTenantAppManager(this PnPContext context)
 {
     return(new TenantAppManager(context));
 }
Example #3
0
 /// <summary>
 /// Extends a <see cref="PnPContext"/> with site collection Application Lifecycle Management (ALM) functionality
 /// </summary>
 /// <param name="context"><see cref="PnPContext"/> to extend</param>
 /// <returns>An <see cref="ISiteCollectionAppManager"/> instance enabling site collection app catalog operations</returns>
 public static ISiteCollectionAppManager GetSiteCollectionAppManager(this PnPContext context)
 {
     return(new SiteCollectionAppManager(context));
 }
Example #4
0
        /// <summary>
        /// Method to resolve a set of tokens in a provided tokenized string
        /// </summary>
        /// <param name="tokenizedValue">A string with tokens</param>
        /// <param name="pnpObject">The domain model object to use as the target reference</param>
        /// <param name="context"><see cref="PnPContext"/> to get information from needed for token resolving</param>
        /// <returns>The string with tokens resolved</returns>
        public static async Task <string> ResolveTokensAsync(IMetadataExtensible pnpObject, string tokenizedValue, PnPContext context = null)
        {
            // Define the result variable
            string result = tokenizedValue;

            // Get the context aware version of the target pnpObject
            var contextAwareObject = pnpObject as IDataModelWithContext;

            // If we don't have an input context, let's try to use
            // the one associated with the input entity, if any
            if (context == null && contextAwareObject != null)
            {
                context = contextAwareObject.PnPContext;
            }

            // Grab the tokens in this input (tokens are between curly braces)
            var matches = regex.Matches(tokenizedValue);

            // Iterate over the tokens and replace them
            foreach (Match match in matches)
            {
                // Replace {Id}
                if (match.Value.Equals("{Id}"))
                {
                    var model = pnpObject;

                    if (model.Metadata.ContainsKey(PnPConstants.MetaDataRestId))
                    {
                        result = result.Replace("{Id}", model.Metadata[PnPConstants.MetaDataRestId]);
                    }
                }
                // Replace {Parent.Id}
                else if (match.Value.Equals("{Parent.Id}"))
                {
                    // there's either a collection object inbetween (e.g. ListItem --> ListItemCollection --> List), so take the parent of the parent
                    // or
                    // the parent is model class itself (e.g. Web --> Site.RootWeb)
                    IDataModelParent parent = GetParentDataModel(pnpObject);

                    // Ensure the parent object
                    if (parent != null)
                    {
                        await((IDataModelParent)pnpObject).EnsureParentObjectAsync().ConfigureAwait(true);
                    }

                    if (parent is IMetadataExtensible p)
                    {
                        if (p.Metadata.ContainsKey(PnPConstants.MetaDataRestId))
                        {
                            result = result.Replace("{Parent.Id}", p.Metadata[PnPConstants.MetaDataRestId]);
                        }
                    }
                }
                // Replace {GraphId}
                else if (match.Value.Equals("{GraphId}"))
                {
                    var model = pnpObject;

                    if (model.Metadata.ContainsKey(PnPConstants.MetaDataGraphId))
                    {
                        result = result.Replace("{GraphId}", model.Metadata[PnPConstants.MetaDataGraphId]);
                    }
                }
                // Replace {Parent.GraphId}
                else if (match.Value.Equals("{Parent.GraphId}"))
                {
                    // there's either a collection object inbetween (e.g. TeamChannel --> TeamChannelCollection --> Team), so take the parent of the parent
                    // or
                    // the parent is model class itself (e.g. TeamChannel --> Team.PrimaryChannel)
                    IDataModelParent parent = GetParentDataModel(pnpObject);

                    // Ensure the parent object
                    if (parent != null)
                    {
                        await((IDataModelParent)pnpObject).EnsureParentObjectAsync().ConfigureAwait(true);
                    }

                    if (parent is IMetadataExtensible p)
                    {
                        if (p.Metadata.ContainsKey(PnPConstants.MetaDataGraphId))
                        {
                            result = result.Replace("{Parent.GraphId}", p.Metadata[PnPConstants.MetaDataGraphId]);
                        }
                    }
                }
                // Replace tokens coming from the Site object connected to the current PnPContext
                else if (match.Value.StartsWith("{Site.") && context != null)
                {
                    var propertyToLoad = match.Value.Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries)[1].Replace("}", "");

                    switch (propertyToLoad)
                    {
                    case "GroupId":
                    {
                        await context.Site.EnsurePropertiesAsync(p => p.GroupId).ConfigureAwait(false);

                        if (context.Site.HasValue(propertyToLoad))
                        {
                            result = result.Replace(match.Value, context.Site.GroupId.ToString());
                        }
                        break;
                    }

                    case "Id":
                    {
                        await context.Site.EnsurePropertiesAsync(p => p.Id).ConfigureAwait(false);

                        if (context.Site.HasValue(propertyToLoad))
                        {
                            result = result.Replace(match.Value, context.Site.Id.ToString());
                        }
                        break;
                    }

                    case "Url":
                    {
                        await context.Site.EnsurePropertiesAsync(p => p.Url).ConfigureAwait(false);

                        if (context.Site.HasValue(propertyToLoad))
                        {
                            result = result.Replace(match.Value, context.Site.Url.ToString());
                        }
                        break;
                    }

                    case "HubSiteId":
                    {
                        await context.Site.EnsurePropertiesAsync(p => p.HubSiteId).ConfigureAwait(false);

                        if (context.Site.HasValue(propertyToLoad))
                        {
                            result = result.Replace(match.Value, context.Site.HubSiteId.ToString());
                        }
                        break;
                    }
                    }
                }
                // Replace tokens coming from the Web object connected to the current PnPContext
                else if (match.Value.StartsWith("{Web.") && context != null)
                {
                    var propertyToLoad = match.Value.Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries)[1].Replace("}", "");

                    switch (propertyToLoad)
                    {
                    case "Id":
                    {
                        await context.Web.EnsurePropertiesAsync(p => p.Id).ConfigureAwait(false);

                        if (context.Web.HasValue(propertyToLoad))
                        {
                            result = result.Replace(match.Value, context.Web.Id.ToString());
                        }
                        break;
                    }

                    case "GraphId":
                    {
                        var model = context.Web as IMetadataExtensible;

                        if (model.Metadata.ContainsKey(PnPConstants.MetaDataGraphId))
                        {
                            result = result.Replace("{Web.GraphId}", model.Metadata[PnPConstants.MetaDataGraphId]);
                        }
                        break;
                    }
                    }
                }
                // Replace tokens coming from the List object connected to the current PnPContext
                else if (match.Value.StartsWith("{List.") && context != null)
                {
                    var propertyToLoad = match.Value.Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries)[1].Replace("}", "");

                    switch (propertyToLoad)
                    {
                    case "Id":
                    {
                        // Try to see if the current object is a list
                        var list = pnpObject as Model.SharePoint.IList;

                        // If the object is a list item
                        if (list == null)
                        {
                            if (pnpObject is Model.SharePoint.IListItem listItem)
                            {
                                // Get the parent list of the current list item
                                list = GetParentDataModel(listItem as IMetadataExtensible) as Model.SharePoint.IList;

                                // Option A: the file has the ListId property loaded
                                if (list == null && GetParentDataModel(listItem as IMetadataExtensible) is Model.SharePoint.IFile file && file.IsPropertyAvailable(p => p.ListId))
                                {
                                    result = result.Replace(match.Value, file.ListId.ToString());
                                    break;
                                }

                                // Option B: the IListItem has a property that indicates the used list
                                if (list == null && (listItem as IMetadataExtensible).Metadata.ContainsKey(PnPConstants.MetaDataListId))
                                {
                                    result = result.Replace(match.Value, (listItem as IMetadataExtensible).Metadata[PnPConstants.MetaDataListId]);
                                    break;
                                }
                            }
                            else if (pnpObject is Model.SharePoint.IFile file)
                            {
                                listItem = GetParentDataModel(file as IMetadataExtensible) as Model.SharePoint.IListItem;
                                list     = GetParentDataModel(listItem as IMetadataExtensible) as Model.SharePoint.IList;
                            }
                            else if (pnpObject is Model.SharePoint.IFileVersion fileVersion)
                            {
                                if (fileVersion.Parent is Model.SharePoint.IFile)
                                {
                                    var fileVersionfile = GetParentDataModel(fileVersion as IMetadataExtensible) as Model.SharePoint.IFile;
                                    listItem = GetParentDataModel(fileVersionfile as IMetadataExtensible) as Model.SharePoint.IListItem;
                                }
                                else if (fileVersion.Parent is Model.SharePoint.IListItemVersion)
                                {
                                    var listItemVersion = GetParentDataModel(fileVersion as IMetadataExtensible) as Model.SharePoint.IListItemVersion;
                                    listItem = GetParentDataModel(listItemVersion as IMetadataExtensible) as Model.SharePoint.IListItem;
                                }
                                else
                                {
                                    listItem = null;
                                }

                                list = GetParentDataModel(listItem as IMetadataExtensible) as Model.SharePoint.IList;
                            }
                            else if (pnpObject is Model.SharePoint.IListItemVersion listItemVersion)
                            {
                                listItem = GetParentDataModel(listItemVersion as IMetadataExtensible) as Model.SharePoint.IListItem;
                                list     = GetParentDataModel(listItem as IMetadataExtensible) as Model.SharePoint.IList;
                            }
                            else if (pnpObject is Model.SharePoint.IComment comment)
                            {
                                listItem = GetParentDataModel(comment as IMetadataExtensible) as Model.SharePoint.IListItem;

                                if (listItem == null)
                                {
                                    // comment was a reply to another comment
                                    var parentComment = GetParentDataModel(comment as IMetadataExtensible) as Model.SharePoint.IComment;
                                    listItem = GetParentDataModel(parentComment as IMetadataExtensible) as Model.SharePoint.IListItem;
                                }

                                // the IListItem has a property that indicates the used list
                                if (listItem != null && (listItem as IMetadataExtensible).Metadata.ContainsKey(PnPConstants.MetaDataListId))
                                {
                                    result = result.Replace(match.Value, (listItem as IMetadataExtensible).Metadata[PnPConstants.MetaDataListId]);
                                    break;
                                }

                                list = GetParentDataModel(listItem as IMetadataExtensible) as Model.SharePoint.IList;
                            }
                            else if (pnpObject is Model.SharePoint.IAttachment attachment)
                            {
                                listItem = GetParentDataModel(attachment as IMetadataExtensible) as Model.SharePoint.IListItem;
                                list     = GetParentDataModel(listItem as IMetadataExtensible) as Model.SharePoint.IList;
                            }
                        }

                        // If we've got the list
                        if (list != null)
                        {
                            // We retrieve the Id and we use it as the token value
                            await list.EnsurePropertiesAsync(l => l.Id).ConfigureAwait(false);

                            result = result.Replace(match.Value, list.Id.ToString());
                        }
                        break;
                    }
                    }
                }
                // Replace tokens coming from the List Item object connected to the current PnPContext
                else if (match.Value.StartsWith("{Item.") && context != null)
                {
                    var propertyToLoad = match.Value.Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries)[1].Replace("}", "");

                    switch (propertyToLoad)
                    {
                    case "Id":
                    {
                        // Try to see if the current object is a list item
                        var listItem = pnpObject as Model.SharePoint.IListItem;

                        // If the object is a descendant of a list item
                        if (listItem == null)
                        {
                            var model = pnpObject;
                            if (model is Model.SharePoint.IFileVersion)
                            {
                                // Should return either an IListItemVersion or an IFile
                                model = GetParentDataModel(model) as IMetadataExtensible;
                            }

                            if (model is Model.SharePoint.IFile || model is Model.SharePoint.IListItemVersion)
                            {
                                // Should return an IListItem
                                listItem = GetParentDataModel(model) as Model.SharePoint.IListItem;
                            }
                        }

                        // If we've got the list item
                        if (listItem != null)
                        {
                            // We retrieve the Id and we use it as the token value
                            await listItem.EnsurePropertiesAsync(l => l.Id).ConfigureAwait(false);

                            result = result.Replace(match.Value, listItem.Id.ToString());
                        }
                        break;
                    }
                    }
                }
                // Replace {hostname}
                else if (match.Value.Equals("{hostname}"))
                {
                    result = result.Replace("{hostname}", context.Uri.DnsSafeHost);
                }
                // Replace {serverrelativepath}
                else if (match.Value.Equals("{serverrelativepath}"))
                {
                    result = result.Replace("{serverrelativepath}", context.Uri.PathAndQuery);
                }
            }

            return(result);
        }
Example #5
0
 /// <summary>
 /// Extends a <see cref="PnPContext"/> with SharePoint admin functionality
 /// </summary>
 /// <param name="context"><see cref="PnPContext"/> to extend</param>
 /// <returns>An <see cref="ISharePointAdmin"/> instance enabling SharePoint admin operations</returns>
 public static ISharePointAdmin GetSharePointAdmin(this PnPContext context)
 {
     return(new SharePointAdmin(context));
 }
Example #6
0
        internal static async Task CopyContextInitializationAsync(PnPContext source, PnPContext target)
        {
            if (source.Web.IsPropertyAvailable(p => p.Id) &&
                source.Web.IsPropertyAvailable(p => p.Url) &&
                source.Web.IsPropertyAvailable(p => p.RegionalSettings) &&
                source.Site.IsPropertyAvailable(p => p.Id) &&
                source.Site.IsPropertyAvailable(p => p.GroupId))
            {
                target.Web.SetSystemProperty(p => p.Id, source.Web.Id);
                target.Web.SetSystemProperty(p => p.Url, source.Web.Url);
                target.Web.Requested         = true;
                (target.Web as Web).Metadata = new Dictionary <string, string>((source.Web as Web).Metadata);

                // Copy regional settings, important to trigger the creation of the regional settings model from the target web model
                var regionalSettings = target.Web.RegionalSettings;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.AM))
                {
                    regionalSettings.SetSystemProperty(p => p.AM, source.Web.RegionalSettings.AM);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.CollationLCID))
                {
                    regionalSettings.SetSystemProperty(p => p.CollationLCID, source.Web.RegionalSettings.CollationLCID);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.DateFormat))
                {
                    regionalSettings.SetSystemProperty(p => p.DateFormat, source.Web.RegionalSettings.DateFormat);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.DateSeparator))
                {
                    regionalSettings.SetSystemProperty(p => p.DateSeparator, source.Web.RegionalSettings.DateSeparator);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.DecimalSeparator))
                {
                    regionalSettings.SetSystemProperty(p => p.DecimalSeparator, source.Web.RegionalSettings.DecimalSeparator);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.DigitGrouping))
                {
                    regionalSettings.SetSystemProperty(p => p.DigitGrouping, source.Web.RegionalSettings.DigitGrouping);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.FirstDayOfWeek))
                {
                    regionalSettings.SetSystemProperty(p => p.FirstDayOfWeek, source.Web.RegionalSettings.FirstDayOfWeek);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.IsEastAsia))
                {
                    regionalSettings.SetSystemProperty(p => p.IsEastAsia, source.Web.RegionalSettings.IsEastAsia);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.IsRightToLeft))
                {
                    regionalSettings.SetSystemProperty(p => p.IsRightToLeft, source.Web.RegionalSettings.IsRightToLeft);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.IsUIRightToLeft))
                {
                    regionalSettings.SetSystemProperty(p => p.IsUIRightToLeft, source.Web.RegionalSettings.IsUIRightToLeft);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.ListSeparator))
                {
                    regionalSettings.SetSystemProperty(p => p.ListSeparator, source.Web.RegionalSettings.ListSeparator);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.LocaleId))
                {
                    regionalSettings.SetSystemProperty(p => p.LocaleId, source.Web.RegionalSettings.LocaleId);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.NegativeSign))
                {
                    regionalSettings.SetSystemProperty(p => p.NegativeSign, source.Web.RegionalSettings.NegativeSign);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.NegNumberMode))
                {
                    regionalSettings.SetSystemProperty(p => p.NegNumberMode, source.Web.RegionalSettings.NegNumberMode);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.PM))
                {
                    regionalSettings.SetSystemProperty(p => p.PM, source.Web.RegionalSettings.PM);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.PositiveSign))
                {
                    regionalSettings.SetSystemProperty(p => p.PositiveSign, source.Web.RegionalSettings.PositiveSign);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.ShowWeeks))
                {
                    regionalSettings.SetSystemProperty(p => p.ShowWeeks, source.Web.RegionalSettings.ShowWeeks);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.ThousandSeparator))
                {
                    regionalSettings.SetSystemProperty(p => p.ThousandSeparator, source.Web.RegionalSettings.ThousandSeparator);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.Time24))
                {
                    regionalSettings.SetSystemProperty(p => p.Time24, source.Web.RegionalSettings.Time24);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.TimeMarkerPosition))
                {
                    regionalSettings.SetSystemProperty(p => p.TimeMarkerPosition, source.Web.RegionalSettings.TimeMarkerPosition);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.TimeSeparator))
                {
                    regionalSettings.SetSystemProperty(p => p.TimeSeparator, source.Web.RegionalSettings.TimeSeparator);
                }
                ;
                regionalSettings.Requested = true;
                (regionalSettings as RegionalSettings).Metadata = new Dictionary <string, string>((source.Web.RegionalSettings as RegionalSettings).Metadata);

                // Copy timezone settings
                var timeZone = regionalSettings.TimeZone;
                if (source.Web.RegionalSettings.TimeZone.IsPropertyAvailable(p => p.Description))
                {
                    timeZone.SetSystemProperty(p => p.Description, source.Web.RegionalSettings.TimeZone.Description);
                }
                ;
                if (source.Web.RegionalSettings.TimeZone.IsPropertyAvailable(p => p.Id))
                {
                    timeZone.SetSystemProperty(p => p.Id, source.Web.RegionalSettings.TimeZone.Id);
                }
                ;
                if (source.Web.RegionalSettings.TimeZone.IsPropertyAvailable(p => p.Bias))
                {
                    timeZone.SetSystemProperty(p => p.Bias, source.Web.RegionalSettings.TimeZone.Bias);
                }
                ;
                if (source.Web.RegionalSettings.TimeZone.IsPropertyAvailable(p => p.DaylightBias))
                {
                    timeZone.SetSystemProperty(p => p.DaylightBias, source.Web.RegionalSettings.TimeZone.DaylightBias);
                }
                ;
                if (source.Web.RegionalSettings.TimeZone.IsPropertyAvailable(p => p.StandardBias))
                {
                    timeZone.SetSystemProperty(p => p.StandardBias, source.Web.RegionalSettings.TimeZone.StandardBias);
                }
                ;
                timeZone.Requested = true;
                (timeZone as Model.SharePoint.TimeZone).Metadata = new Dictionary <string, string>((source.Web.RegionalSettings.TimeZone as Model.SharePoint.TimeZone).Metadata);

                // Copy site settings
                target.Site.SetSystemProperty(p => p.Id, source.Site.Id);
                target.Site.SetSystemProperty(p => p.GroupId, source.Site.GroupId);
                target.Site.Requested          = true;
                (target.Site as Site).Metadata = new Dictionary <string, string>((source.Site as Site).Metadata);

                // Copy the additional initialization properties (if any)
                // Only "basic" properties are cloned, complex properties (e.g. Web.Lists) are not cloned as
                // a common use case of using a cloned context is to start "clean", basic web/site properties do not change
                // when cloning for the same site url, but one might want to load collections (= complex property)
                // using a different filter
                if (source.LocalContextOptions != null)
                {
                    List <Expression <Func <ISite, object> > > clonedSiteProperties = new List <Expression <Func <ISite, object> > >();
                    List <Expression <Func <IWeb, object> > >  clonedWebProperties  = new List <Expression <Func <IWeb, object> > >();

                    if (source.LocalContextOptions.AdditionalSitePropertiesOnCreate != null)
                    {
                        foreach (var prop in source.LocalContextOptions.AdditionalSitePropertiesOnCreate)
                        {
                            if (!prop.Body.Type.ImplementsInterface(typeof(IDataModelParent)) && !prop.Body.Type.ImplementsInterface(typeof(IQueryable)))
                            {
                                clonedSiteProperties.Add(prop);
                                target.Site.SetSystemProperty(prop, GetPropertyValue(source.Site, prop));
                            }
                        }
                    }

                    if (source.LocalContextOptions.AdditionalWebPropertiesOnCreate != null)
                    {
                        foreach (var prop in source.LocalContextOptions.AdditionalWebPropertiesOnCreate)
                        {
                            if (!prop.Body.Type.ImplementsInterface(typeof(IDataModelParent)) && !prop.Body.Type.ImplementsInterface(typeof(IQueryable)))
                            {
                                clonedWebProperties.Add(prop);
                                target.Web.SetSystemProperty(prop, GetPropertyValue(source.Web, prop));
                            }
                        }
                    }

                    if (clonedSiteProperties.Any() || clonedWebProperties.Any())
                    {
                        target.LocalContextOptions = new PnPContextOptions()
                        {
                            AdditionalSitePropertiesOnCreate = clonedSiteProperties.Any() ? clonedSiteProperties : null,
                            AdditionalWebPropertiesOnCreate  = clonedWebProperties.Any() ? clonedWebProperties : null
                        };
                    }
                }
            }
            else
            {
                // seems the data in the source context was not what we expected, run the usual initialization to reset it, reuse the source context options
                // if specified
                await InitializeContextAsync(target, source.LocalContextOptions).ConfigureAwait(false);
            }
        }
Example #7
0
        private async Task SendBlazorInitEventAsync(PnPContext context)
        {
            try
            {
                // Ensure the tenant id was fetched
                await context.SetAADTenantId().ConfigureAwait(false);

                using (var request = new HttpRequestMessage(HttpMethod.Post, $"https://dc.services.visualstudio.com/v2/track"))
                {
                    // Build payload
                    var body = new
                    {
                        name = "AppEvents",
                        time = DateTime.Now.ToUniversalTime().ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffZ"),
                        iKey = TelemetryManager.InstrumentationKey,
                        data = new
                        {
                            baseType = "EventData",
                            baseData = new
                            {
                                ver        = 2,
                                name       = "PnPCoreInit",
                                properties = new
                                {
                                    PnPCoreSDKVersion = "1.0.0.0",
                                    AADTenantId       = GlobalOptions.AADTenantId.ToString(),
                                    OS = "WASM"
                                }
                            }
                        }
                    };

                    var jsonBody = JsonSerializer.Serialize(body, PnPConstants.JsonSerializer_IgnoreNullValues);

                    using (StringContent content = new StringContent(jsonBody))
                    {
                        // Remove the default Content-Type content header
                        if (content.Headers.Contains("Content-Type"))
                        {
                            content.Headers.Remove("Content-Type");
                        }
                        // Add the batch Content-Type header
                        content.Headers.Add($"Content-Type", "application/x-json-stream");

                        // Connect content to request
                        request.Content = content;

                        HttpResponseMessage response = await httpClient.SendAsync(request).ConfigureAwait(false);

                        if (!response.IsSuccessStatusCode)
                        {
                            Log.LogDebug($"Blazor telemetry failure: {await response.Content.ReadAsStringAsync().ConfigureAwait(false)}");
                        }
                    }
                }
            }
            // Never fail if telemetry is failing
#pragma warning disable CA1031 // Do not catch general exception types
            catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
            {
                Log.LogDebug($"Blazor telemetry failure: {ex}");
            }
        }
Example #8
0
 private static string GetPropertiesFile(PnPContext context)
 {
     return(Path.Combine(GetPath(context), $"{context.TestName}-{context.TestId}.properties"));
 }
Example #9
0
        /// <summary>
        /// When using REST batch requests the URL needs to be correctly cased, so we're loading the web url while doing an interactive request.
        /// Also loading the default needed properties to save additional loads for missing key properties
        /// </summary>
        /// <param name="context">PnPContext being initialized</param>
        /// <param name="options">Options for the initialization of this context</param>
        /// <returns></returns>
        internal static async Task InitializeContextAsync(PnPContext context, PnPContextOptions options)
        {
            // Set environment if not yet set
            if (!context.Environment.HasValue)
            {
                context.Environment = CloudManager.GetEnvironmentFromUri(context.Uri);
                // Ensure the Microsoft Graph URL is set depending on the used cloud environment
                context.GraphClient.UpdateBaseAddress(CloudManager.GetMicrosoftGraphAuthority(context.Environment.Value));
            }

            // Store the provided options, needed for context cloning
            context.LocalContextOptions = options;

            // IMPORTANT: this first call is an interactive call by design as that allows us set the
            //            web URL using the correct casing. Correct casing is required in REST batching

            // IMPORTANT: if you change this logic by adding more initialization data you also need
            //            to update the CopyContextInitialization method!

            // Combine the default properties to load with optional additional properties
            var(siteProps, webProps) = GetDefaultPropertiesToLoad(options);

            // Use the query client to build the correct initialization query for the given Web properties
            BaseDataModel <IWeb> concreteEntity = EntityManager.GetEntityConcreteInstance(typeof(IWeb), context.Web, context) as BaseDataModel <IWeb>;
            var entityInfo     = EntityManager.GetClassInfo(concreteEntity.GetType(), concreteEntity, null, webProps.ToArray());
            var apiCallRequest = await QueryClient.BuildGetAPICallAsync(concreteEntity, entityInfo, new ApiCall($"_api/Web", ApiType.SPORest), true).ConfigureAwait(false);

            // Load required web properties
            var api = new ApiCall(apiCallRequest.ApiCall.Request, ApiType.SPORest)
            {
                Interactive = true
            };

            await(context.Web as Web).RequestAsync(api, HttpMethod.Get, "Get").ConfigureAwait(false);

            // Replace the context URI with the value using the correct casing
            context.Uri = context.Web.Url;

            // Request the site properties
            await context.Site.LoadAsync(siteProps.ToArray()).ConfigureAwait(false);

            // Ensure the Graph ID is set once and only once
            if (context.Web is IMetadataExtensible me)
            {
                if (!me.Metadata.ContainsKey(PnPConstants.MetaDataGraphId))
                {
                    me.Metadata.Add(PnPConstants.MetaDataGraphId, $"{context.Uri.DnsSafeHost},{context.Site.Id},{context.Web.Id}");
                }
            }

            // If the GroupId is available ensure it's also correctly set on the Group metadata so that calls via that
            // model can work
            if (context.Site.IsPropertyAvailable(p => p.GroupId) && context.Site.GroupId != Guid.Empty)
            {
                if (context.Group is IMetadataExtensible groupMetaData)
                {
                    if (!groupMetaData.Metadata.ContainsKey(PnPConstants.MetaDataGraphId))
                    {
                        groupMetaData.Metadata.Add(PnPConstants.MetaDataGraphId, context.Site.GroupId.ToString());
                    }
                }
            }
        }
Example #10
0
 private static string GetResponseFile(PnPContext context, string orderPrefix)
 {
     return(Path.Combine(GetPath(context), $"{context.TestName}-{context.TestId}-{orderPrefix}.response.json"));
 }
Example #11
0
 private static string GetDebugFile(PnPContext context, string orderPrefix)
 {
     return(Path.Combine(GetPath(context), $"{context.TestName}-{context.TestId}-{orderPrefix}.debug"));
 }
Example #12
0
        internal static async Task CopyContextInitializationAsync(PnPContext source, PnPContext target)
        {
            if (source.Web.IsPropertyAvailable(p => p.Id) &&
                source.Web.IsPropertyAvailable(p => p.Url) &&
                source.Web.IsPropertyAvailable(p => p.RegionalSettings) &&
                source.Site.IsPropertyAvailable(p => p.Id) &&
                source.Site.IsPropertyAvailable(p => p.GroupId))
            {
                target.Web.SetSystemProperty(p => p.Id, source.Web.Id);
                target.Web.SetSystemProperty(p => p.Url, source.Web.Url);
                target.Web.Requested         = true;
                (target.Web as Web).Metadata = new System.Collections.Generic.Dictionary <string, string>((source.Web as Web).Metadata);

                // Copy regional settings, important to trigger the creation of the regional settings model from the target web model
                var regionalSettings = target.Web.RegionalSettings;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.AM))
                {
                    regionalSettings.SetSystemProperty(p => p.AM, source.Web.RegionalSettings.AM);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.CollationLCID))
                {
                    regionalSettings.SetSystemProperty(p => p.CollationLCID, source.Web.RegionalSettings.CollationLCID);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.DateFormat))
                {
                    regionalSettings.SetSystemProperty(p => p.DateFormat, source.Web.RegionalSettings.DateFormat);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.DateSeparator))
                {
                    regionalSettings.SetSystemProperty(p => p.DateSeparator, source.Web.RegionalSettings.DateSeparator);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.DecimalSeparator))
                {
                    regionalSettings.SetSystemProperty(p => p.DecimalSeparator, source.Web.RegionalSettings.DecimalSeparator);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.DigitGrouping))
                {
                    regionalSettings.SetSystemProperty(p => p.DigitGrouping, source.Web.RegionalSettings.DigitGrouping);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.FirstDayOfWeek))
                {
                    regionalSettings.SetSystemProperty(p => p.FirstDayOfWeek, source.Web.RegionalSettings.FirstDayOfWeek);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.IsEastAsia))
                {
                    regionalSettings.SetSystemProperty(p => p.IsEastAsia, source.Web.RegionalSettings.IsEastAsia);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.IsRightToLeft))
                {
                    regionalSettings.SetSystemProperty(p => p.IsRightToLeft, source.Web.RegionalSettings.IsRightToLeft);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.IsUIRightToLeft))
                {
                    regionalSettings.SetSystemProperty(p => p.IsUIRightToLeft, source.Web.RegionalSettings.IsUIRightToLeft);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.ListSeparator))
                {
                    regionalSettings.SetSystemProperty(p => p.ListSeparator, source.Web.RegionalSettings.ListSeparator);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.LocaleId))
                {
                    regionalSettings.SetSystemProperty(p => p.LocaleId, source.Web.RegionalSettings.LocaleId);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.NegativeSign))
                {
                    regionalSettings.SetSystemProperty(p => p.NegativeSign, source.Web.RegionalSettings.NegativeSign);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.NegNumberMode))
                {
                    regionalSettings.SetSystemProperty(p => p.NegNumberMode, source.Web.RegionalSettings.NegNumberMode);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.PM))
                {
                    regionalSettings.SetSystemProperty(p => p.PM, source.Web.RegionalSettings.PM);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.PositiveSign))
                {
                    regionalSettings.SetSystemProperty(p => p.PositiveSign, source.Web.RegionalSettings.PositiveSign);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.ShowWeeks))
                {
                    regionalSettings.SetSystemProperty(p => p.ShowWeeks, source.Web.RegionalSettings.ShowWeeks);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.ThousandSeparator))
                {
                    regionalSettings.SetSystemProperty(p => p.ThousandSeparator, source.Web.RegionalSettings.ThousandSeparator);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.Time24))
                {
                    regionalSettings.SetSystemProperty(p => p.Time24, source.Web.RegionalSettings.Time24);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.TimeMarkerPosition))
                {
                    regionalSettings.SetSystemProperty(p => p.TimeMarkerPosition, source.Web.RegionalSettings.TimeMarkerPosition);
                }
                ;
                if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.TimeSeparator))
                {
                    regionalSettings.SetSystemProperty(p => p.TimeSeparator, source.Web.RegionalSettings.TimeSeparator);
                }
                ;
                regionalSettings.Requested = true;
                (regionalSettings as RegionalSettings).Metadata = new System.Collections.Generic.Dictionary <string, string>((source.Web.RegionalSettings as RegionalSettings).Metadata);

                // Copy timezone settings
                var timeZone = regionalSettings.TimeZone;
                if (source.Web.RegionalSettings.TimeZone.IsPropertyAvailable(p => p.Description))
                {
                    timeZone.SetSystemProperty(p => p.Description, source.Web.RegionalSettings.TimeZone.Description);
                }
                ;
                if (source.Web.RegionalSettings.TimeZone.IsPropertyAvailable(p => p.Id))
                {
                    timeZone.SetSystemProperty(p => p.Id, source.Web.RegionalSettings.TimeZone.Id);
                }
                ;
                if (source.Web.RegionalSettings.TimeZone.IsPropertyAvailable(p => p.Bias))
                {
                    timeZone.SetSystemProperty(p => p.Bias, source.Web.RegionalSettings.TimeZone.Bias);
                }
                ;
                if (source.Web.RegionalSettings.TimeZone.IsPropertyAvailable(p => p.DaylightBias))
                {
                    timeZone.SetSystemProperty(p => p.DaylightBias, source.Web.RegionalSettings.TimeZone.DaylightBias);
                }
                ;
                if (source.Web.RegionalSettings.TimeZone.IsPropertyAvailable(p => p.StandardBias))
                {
                    timeZone.SetSystemProperty(p => p.StandardBias, source.Web.RegionalSettings.TimeZone.StandardBias);
                }
                ;
                timeZone.Requested = true;
                (timeZone as Model.SharePoint.TimeZone).Metadata = new System.Collections.Generic.Dictionary <string, string>((source.Web.RegionalSettings.TimeZone as Model.SharePoint.TimeZone).Metadata);

                // Copy site settings
                target.Site.SetSystemProperty(p => p.Id, source.Site.Id);
                target.Site.SetSystemProperty(p => p.GroupId, source.Site.GroupId);
                target.Site.Requested          = true;
                (target.Site as Site).Metadata = new System.Collections.Generic.Dictionary <string, string>((source.Site as Site).Metadata);
            }
            else
            {
                // seems the data in the source context was not what we expected, run the usual initialization to reset it
                await InitializeContextAsync(target).ConfigureAwait(false);
            }
        }
Example #13
0
 /// <summary>
 /// Mocks the response for a given request
 /// </summary>
 /// <param name="context">Current PnPContext</param>
 /// <param name="requestKey">Key we used to calculate the hash, used to identify the response to return</param>
 /// <returns>Server response from the mock response</returns>
 internal static Stream MockResponseAsStream(PnPContext context, string requestKey)
 {
     return(MockResponse(context, requestKey).AsStream());
 }
Example #14
0
 private static string GetDebugFile(PnPContext context, /*string hash,*/ string orderPrefix)
 {
     //return Path.Combine(GetPath(context), $"{context.TestName}-{context.TestId}-{orderPrefix}-{hash}.debug");
     return(Path.Combine(GetPath(context), $"{context.TestName}-{context.TestId}-{orderPrefix}.debug"));
 }
Example #15
0
        internal Dictionary <string, string> PopulateRequestProperties(BatchRequest request, PnPContext context)
        {
            Dictionary <string, string> properties = new Dictionary <string, string>(10)
            {
                { "PnPCoreSDKVersion", Version },
                { "AADTenantId", GlobalOptions.AADTenantId.ToString() },
                { "Model", request.Model.GetType().FullName },
                { "ApiType", request.ApiCall.Type.ToString() },
                { "ApiMethod", request.Method.ToString() },
                { "GraphFirst", context.GraphFirst.ToString() },
                { "GraphCanUseBeta", context.GraphCanUseBeta.ToString() },
                { "GraphAlwaysUseBeta", context.GraphAlwaysUseBeta.ToString() },
                { "OS", GetOSVersion() },
                { "Operation", request.OperationName },
            };

            return(properties);
        }
Example #16
0
 internal virtual void LogServiceRequest(BatchRequest request, PnPContext context)
 {
     TelemetryClient.TrackEvent("PnPCoreRequest", PopulateRequestProperties(request, context));
 }