Example #1
0
        protected override void FillHierarchy(Uri context, string[] entityTypes, string hierarchyNodeID, int numberOfLevels, Microsoft.SharePoint.WebControls.SPProviderHierarchyTree hierarchy)
        {
            AzureCPLogging.Log(String.Format("[{0}] FillHierarchy called", ProviderInternalName),
                TraceSeverity.VerboseEx, EventSeverity.Information, AzureCPLogging.Categories.Core);

            SPSecurity.RunWithElevatedPrivileges(delegate ()
            {
                if (!Initialize(context, entityTypes))
                    return;

                this.Lock_Config.EnterReadLock();
                try
                {
                    if (hierarchyNodeID == null)
                    {
                        // Root level
                        //foreach (var azureObject in FinalAttributeList.Where(x => !String.IsNullOrEmpty(x.peoplePickerAttributeHierarchyNodeId) && !x.CreateAsIdentityClaim && entityTypes.Contains(x.ClaimEntityType)))
                        foreach (var azureObject in this.ProcessedAzureObjects.FindAll(x => !x.CreateAsIdentityClaim && entityTypes.Contains(x.ClaimEntityType)))
                        {
                            hierarchy.AddChild(
                                new Microsoft.SharePoint.WebControls.SPProviderHierarchyNode(
                                    _ProviderInternalName,
                                    azureObject.ClaimTypeMappingName,
                                    azureObject.ClaimType,
                                    true));
                        }
                    }
                }
                catch (Exception ex)
                {
                    AzureCPLogging.LogException(ProviderInternalName, "in FillHierarchy", AzureCPLogging.Categories.Claims_Picking, ex);
                }
                finally
                {
                    this.Lock_Config.ExitReadLock();
                }
            });
        }
Example #2
0
        protected override void FillSearch(Uri context, string[] entityTypes, string searchPattern, string hierarchyNodeID, int maxCount, Microsoft.SharePoint.WebControls.SPProviderHierarchyTree searchTree)
        {
            AzureCPLogging.Log(String.Format("[{0}] FillSearch called, incoming input: \"{1}\"", ProviderInternalName, searchPattern),
                TraceSeverity.VerboseEx, EventSeverity.Information, AzureCPLogging.Categories.Core);

            SPSecurity.RunWithElevatedPrivileges(delegate ()
            {
                if (!Initialize(context, entityTypes))
                    return;

                this.Lock_Config.EnterReadLock();
                try
                {
                    string input = searchPattern;
                    SPProviderHierarchyNode matchNode = null;
                    // List<T>.FindAll returns an empty list if no result found: http://msdn.microsoft.com/en-us/library/fh1w7y8z(v=vs.110).aspx
                    List<AzureADObject> azureObjects;
                    if (!String.IsNullOrEmpty(hierarchyNodeID))
                    {
                        // Restrict search to objects currently selected in the hierarchy (may return multiple results if identity claim type)
                        azureObjects = this.ProcessedAzureObjects.FindAll(x =>
                            String.Equals(x.ClaimType, hierarchyNodeID, StringComparison.InvariantCultureIgnoreCase) &&
                            entityTypes.Contains(x.ClaimEntityType));
                    }
                    else
                    {
                        azureObjects = this.ProcessedAzureObjects.FindAll(x => entityTypes.Contains(x.ClaimEntityType));
                    }

                    if (this.CurrentConfiguration.AlwaysResolveUserInput)
                    {
                        List<PickerEntity> entities = CreatePickerEntityForSpecificClaimTypes(
                            input,
                            azureObjects.FindAll(x => !x.CreateAsIdentityClaim),
                            false);
                        if (entities != null)
                        {
                            foreach (var entity in entities)
                            {
                                // Add current PickerEntity to the corresponding attribute in the hierarchy
                                // Use Claim type has key
                                string entityClaimType = entity.Claim.ClaimType;
                                // ClaimTypeMappingName cannot be null as it is value of SPClaimTypeMapping.IncomingClaimTypeDisplayName, which is mandatory
                                string ClaimTypeMappingName = azureObjects
                                    .First(x =>
                                        !x.CreateAsIdentityClaim &&
                                        String.Equals(x.ClaimType, entityClaimType, StringComparison.InvariantCultureIgnoreCase))
                                    .ClaimTypeMappingName;

                                if (searchTree.HasChild(entityClaimType))
                                {
                                    matchNode = searchTree.Children.First(x => String.Equals(x.HierarchyNodeID, entityClaimType, StringComparison.InvariantCultureIgnoreCase));
                                }
                                else
                                {
                                    matchNode = new SPProviderHierarchyNode(_ProviderInternalName, ClaimTypeMappingName, entityClaimType, true);
                                    searchTree.AddChild(matchNode);
                                }
                                matchNode.AddEntity(entity);
                                AzureCPLogging.Log(String.Format("[{0}] Added permission created without AAD lookup because AzureCP configured to always resolve input: claim value: \"{1}\", claim type: \"{2}\" to the list of results.", ProviderInternalName, entity.Claim.Value, entity.Claim.ClaimType), TraceSeverity.Medium, EventSeverity.Information, AzureCPLogging.Categories.Claims_Picking);
                            }
                        }
                        return;
                    }

                    // Check if input starts with PrefixToBypassLookup in a AzureADObject
                    List<AzureADObject> objectsMatchingInputPrefix = azureObjects.FindAll(x =>
                        !String.IsNullOrEmpty(x.PrefixToBypassLookup) &&
                        input.StartsWith(x.PrefixToBypassLookup, StringComparison.InvariantCultureIgnoreCase));
                    if (objectsMatchingInputPrefix.Count > 0)
                    {
                        // Input has a prefix, so it should be validated with no lookup
                        AzureADObject objectMatchingInputPrefix = objectsMatchingInputPrefix.First();
                        if (objectsMatchingInputPrefix.Count > 1)
                        {
                            // Multiple objects have same prefix, which is bad
                            AzureCPLogging.Log(String.Format("[{0}] Multiple objects have same prefix {1}, which is bad.", ProviderInternalName, objectMatchingInputPrefix.PrefixToBypassLookup), TraceSeverity.Unexpected, EventSeverity.Error, AzureCPLogging.Categories.Claims_Picking);
                            return;
                        }

                        PickerEntity entity = CreatePickerEntityForSpecificClaimType(
                            input.Substring(objectMatchingInputPrefix.PrefixToBypassLookup.Length),
                            objectMatchingInputPrefix,
                            true);

                        if (searchTree.HasChild(objectMatchingInputPrefix.ClaimType))
                        {
                            matchNode = searchTree.Children.First(x => String.Equals(x.HierarchyNodeID, objectMatchingInputPrefix.ClaimType, StringComparison.InvariantCultureIgnoreCase));
                        }
                        else
                        {
                            matchNode = new SPProviderHierarchyNode(_ProviderInternalName, objectMatchingInputPrefix.ClaimTypeMappingName, objectMatchingInputPrefix.ClaimType, true);
                            searchTree.AddChild(matchNode);
                        }
                        matchNode.AddEntity(entity);
                        AzureCPLogging.Log(String.Format("[{0}] Added permission created without AAD lookup because input matches a keyword: claim value: \"{1}\", claim type: \"{2}\" to the list of results.", ProviderInternalName, entity.Claim.Value, entity.Claim.ClaimType), TraceSeverity.Medium, EventSeverity.Information, AzureCPLogging.Categories.Claims_Picking);
                    }
                    else
                    {
                        // Perform AAD lookup
                        // Claims provider is called by static methods in SPClaimProviderOperations class. As a consequence, results must be declared in the method (and not in the class) to ensure that each thread has it own unique collection
                        List<AzurecpResult> results = new List<AzurecpResult>();
                        BuildFilterAndProcessResults(
                            input,
                            azureObjects,
                            this.CurrentConfiguration.FilterExactMatchOnly,
                            context,
                            entityTypes,
                            ref results);

                        if (results != null && results.Count > 0)
                        {
                            foreach (var result in results)
                            {
                                // Add current PickerEntity to the corresponding attribute in the hierarchy
                                if (searchTree.HasChild(result.AzureObject.ClaimType))
                                {
                                    matchNode = searchTree.Children.First(x => x.HierarchyNodeID == result.AzureObject.ClaimType);
                                }
                                else
                                {
                                    matchNode = new SPProviderHierarchyNode(_ProviderInternalName, result.AzureObject.ClaimTypeMappingName, result.AzureObject.ClaimType, true);
                                    searchTree.AddChild(matchNode);
                                }
                                matchNode.AddEntity(result.PickerEntity);
                                AzureCPLogging.Log(String.Format("[{0}] Added permission created with AAD lookup: claim value: \"{1}\", claim type: \"{2}\" to the list of results.", ProviderInternalName, result.PickerEntity.Claim.Value, result.PickerEntity.Claim.ClaimType), TraceSeverity.Medium, EventSeverity.Information, AzureCPLogging.Categories.Claims_Picking);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    AzureCPLogging.LogException(ProviderInternalName, "in FillSearch", AzureCPLogging.Categories.Claims_Picking, ex);
                }
                finally
                {
                    this.Lock_Config.ExitReadLock();
                }
            });
        }