Example #1
0
        private static ActionAndStrategy GetClaimSetSpecificActionAndStrategy(ActionAndStrategy pair, string claimSetName)
        {
            if (pair == null)
            {
                return(null);
            }

            if (!pair.ExplicitActionAndStrategyByClaimSetName.ContainsKey(claimSetName))
            {
                return(null);
            }

            return(pair.ExplicitActionAndStrategyByClaimSetName[claimSetName]);
        }
Example #2
0
        //private static void ClearOutputFolder()
        //{
        //    if (Directory.Exists(BaseOutputFolder))
        //    {
        //        Directory
        //            .GetFiles(BaseOutputFolder)
        //            .ToList()
        //            .ForEach(File.Delete);
        //    }
        //}

        private static AdjacencyGraph <Resource, Edge <Resource> > LoadAuthorizationMetadataGraph(
            string connectionString, out List <string> claimSetNames)
        {
            var resourceGraph = new AdjacencyGraph <Resource, Edge <Resource> >();

            const string providerName = "System.Data.SqlClient";

            string metadataSql = @"
select	rc.ResourceClaimId, rc.ResourceName, prc.ResourceName as ParentResourceName, a.ActionName, as_.AuthorizationStrategyName
from	dbo.ResourceClaims rc
        left join dbo.ResourceClaims prc
            ON rc.ParentResourceClaimId = prc.ResourceClaimId
        left join dbo.ResourceClaimAuthorizationMetadatas rcas
            ON rc.ResourceClaimId = rcas.ResourceClaim_ResourceClaimId
        left join dbo.AuthorizationStrategies as_
            ON rcas.AuthorizationStrategy_AuthorizationStrategyId = as_.AuthorizationStrategyId
        left join dbo.Actions a
            ON rcas.Action_ActionId = a.ActionId
order by rc.ResourceName, a.ActionId, as_.AuthorizationStrategyName";

            string claimSetSql = @"
select	ClaimSetId, ClaimSetName, ResourceName, ActionName, null As StrategyName
from	dbo.ClaimSets cs
        left join dbo.ClaimSetResourceClaims csrc ON cs.ClaimSetId = csrc.ClaimSet_ClaimSetId
        left join dbo.Actions a ON csrc.Action_ActionId = a.ActionId
        left join dbo.ResourceClaims rc ON csrc.ResourceClaim_ResourceClaimId = rc.ResourceClaimId
order by ClaimSetName, ResourceName, Action_ActionId
";

            var metadataEdges           = GetResourceClaimMetadata(connectionString, providerName, metadataSql);
            var claimsetResourceActions = GetClaimSetMetadata(connectionString, providerName, claimSetSql);

            var distinctMetadataEdges =
                (from e in metadataEdges
                 select new
            {
                e.ResourceName,
                e.ParentResourceName
            }
                ).Distinct();

            // First process the segments into the graph
            foreach (var metadataEdge in distinctMetadataEdges)
            {
                if (string.IsNullOrEmpty(metadataEdge.ParentResourceName))
                {
                    resourceGraph.AddVertex(new Resource(metadataEdge.ResourceName));
                }
                else
                {
                    resourceGraph.AddVerticesAndEdge(
                        new Edge <Resource>(new Resource(metadataEdge.ParentResourceName), new Resource(metadataEdge.ResourceName)));
                }
            }

            // Now augment the vertices with authorization strategies and actions
            var edgesGroupedByResoureName =
                from e in metadataEdges
                where e.ActionName != null
                group e by e.ResourceName
                into g
                select new
            {
                ResourceName = g.Key,
                Actions      = g.Select(
                    x => new
                {
                    x.ActionName,
                    StrategyName = x.AuthorizationStrategyName
                })
            };

            // Augment each vertex with the actions/strategies
            foreach (var edge in edgesGroupedByResoureName)
            {
                var vertex = resourceGraph.Vertices.Single(x => x.Name == edge.ResourceName);

                vertex.ActionAndStrategyPairs.AddRange(
                    from e in edge.Actions
                    select new ActionAndStrategy
                {
                    ActionName            = e.ActionName,
                    AuthorizationStrategy = e.StrategyName
                });
            }

            // Process claim set data
            var claimsetMetadata =
                (from c in claimsetResourceActions
                 group c by c.ClaimSetName
                 into mainGroup
                 select new
            {
                ClaimSetName = mainGroup.Key,
                Resources =
                    (from mg in mainGroup
                     group mg by mg.ResourceName
                     into subGroup
                     select new
                {
                    ResourceName = subGroup.Key,
                    ActionStrategy =
                        (from sg in subGroup
                         where !string.IsNullOrEmpty(sg.ActionName)
                         select new
                    {
                        sg.ActionName,
                        sg.StrategyName
                    })
                        .ToList()
                }).ToList()
            }).ToList();

            claimSetNames = claimsetMetadata.Select(x => x.ClaimSetName).ToList();

            foreach (var claimsetItem in claimsetMetadata)
            {
                string claimSetName = claimsetItem.ClaimSetName;

                foreach (var resourceItem in claimsetItem.Resources)
                {
                    var resourceVertex = resourceGraph.Vertices.Single(x => x.Name == resourceItem.ResourceName);

                    foreach (var actionStrategyItem in resourceItem.ActionStrategy)
                    {
                        var actionVertex = resourceVertex.ActionAndStrategyPairs.SingleOrDefault(x => x.ActionName == actionStrategyItem.ActionName);

                        // If action vertex doesn't yet exist in the graph, create it implicitly now
                        if (actionVertex == null)
                        {
                            var newAction = new ActionAndStrategy
                            {
                                ActionName = actionStrategyItem.ActionName
                            };

                            resourceVertex.ActionAndStrategyPairs.Add(newAction);

                            actionVertex = newAction;
                        }

                        // Make note that we've got metadata explicitly assigning this action
                        actionVertex.ExplicitActionAndStrategyByClaimSetName[claimSetName] = new ActionAndStrategy
                        {
                            ActionName            = actionStrategyItem.ActionName,
                            AuthorizationStrategy =
                                actionStrategyItem.StrategyName
                        };
                    }
                }

                // Now process each of the root nodes from top to bottom to determine effective permissions at each vertex
                foreach (var rootVertex in GetRootNodes(resourceGraph))
                {
                    SetParentReferences(null, rootVertex, resourceGraph);
                }
            }

            return(resourceGraph);
        }
Example #3
0
        private static AdjacencyGraph <Resource, Edge <Resource> > LoadAuthorizationMetadataGraph(
            string connectionString, out List <string> claimSetNames)
        {
            var resourceGraph = new AdjacencyGraph <Resource, Edge <Resource> >();

            var calimsSql = @"
SELECT rc.ClaimName,
       rc.DisplayName,
       prc.ClaimName   AS ParentClaimName,
       prc.DisplayName AS ParentDisplayName,
       a.ActionName,
       as_.AuthorizationStrategyName
FROM   dbo.ResourceClaims rc
       LEFT JOIN dbo.ResourceClaims prc ON rc.ParentResourceClaimId = prc.ResourceClaimId
       LEFT JOIN dbo.ResourceClaimActions rca ON rc.ResourceClaimId = rca.ResourceClaimId
       LEFT JOIN dbo.ResourceClaimActionAuthorizationStrategies rcaas ON rca.ResourceClaimActionId = rcaas.ResourceClaimActionId
       LEFT JOIN dbo.AuthorizationStrategies as_ ON rcaas.AuthorizationStrategyId = as_.AuthorizationStrategyId
       LEFT JOIN dbo.Actions a ON rca.ActionId = a.ActionId
ORDER  BY rc.DisplayName,
          a.ActionId,
          as_.AuthorizationStrategyName
";

            var claimSetsSql = @"
SELECT ClaimSetName,
       ClaimName,
       ActionName,
       AuthorizationStrategyName AS StrategyName
FROM   dbo.ClaimSets cs
       LEFT JOIN dbo.ClaimSetResourceClaimActions csrca ON cs.ClaimSetId = csrca.ClaimSetId
	   LEFT JOIN dbo.ClaimSetResourceClaimActionAuthorizationStrategyOverrides csrcaaso ON csrca.ClaimSetResourceClaimActionId = csrcaaso.ClaimSetResourceClaimActionId
       LEFT JOIN dbo.AuthorizationStrategies as_ ON csrcaaso.AuthorizationStrategyId = as_.AuthorizationStrategyId
	   LEFT JOIN dbo.Actions a ON csrca.ActionId = a.ActionId
       LEFT JOIN dbo.ResourceClaims rc ON csrca.ResourceClaimId = rc.ResourceClaimId
ORDER  BY ClaimSetName,
          rc.DisplayName,
          a.ActionId 
";

            using var conn = new SqlConnection(connectionString);
            var claims    = conn.Query <ResourceSegmentData>(calimsSql);
            var claimSets = conn.Query <ClaimsetResourceActionData>(claimSetsSql);

            // Ignore ClaimSets that don't have ClaimSetResourceClaimActions ('Ownership Based Test', for example)
            claimSets = claimSets
                        .Where(x => x.ClaimName != null)
                        .ToList();

            var uniqueEdges = claims
                              .GroupBy(e => (e.ClaimName, e.ParentClaimName))
                              .Select(grp => grp.First());

            claimNamesToDisplayNames = uniqueEdges.ToDictionary(e => e.ClaimName, e => e.DisplayName);

            // First add empty vertices and edges to the graph, each claim is a vertex
            foreach (var edge in uniqueEdges)
            {
                var vertex = GetOrAddVertex(resourceGraph, edge.ClaimName);

                if (!string.IsNullOrEmpty(edge.ParentClaimName))
                {
                    var parentVertex = GetOrAddVertex(resourceGraph, edge.ParentClaimName);
                    resourceGraph.AddEdge(new Edge <Resource>(parentVertex, vertex));
                }
            }

            var edgesGroupedByClaim = claims
                                      .Where(resource => resource.ActionName != null)
                                      .GroupBy(resource => resource.ClaimName)
                                      .Select(resourcesByClaim => new
            {
                ClaimName = resourcesByClaim.Key,
                Actions   = resourcesByClaim
                            .GroupBy(resource => resource.ActionName)
                            .Select(resourcesByAction => new
                {
                    Name       = resourcesByAction.Key,
                    Strategies = resourcesByAction.Select(resource => resource.AuthorizationStrategyName).ToHashSet()
                })
            });

            // Now augment the vertices with authorization strategies and actions
            foreach (var edge in edgesGroupedByClaim)
            {
                var vertex = resourceGraph.Vertices.Single(x => x.ClaimName == edge.ClaimName);

                vertex.ActionAndStrategyPairs.AddRange(
                    edge.Actions.Select(action => new ActionAndStrategy
                {
                    ActionName            = action.Name,
                    AuthorizationStrategy = action.Strategies
                })
                    );
            }

            var claimSetsGroupedByName = claimSets
                                         .GroupBy(csra => csra.ClaimSetName)
                                         .Select(csrasByClaimSet => new
            {
                ClaimSetName = csrasByClaimSet.Key,
                Resources    = csrasByClaimSet
                               .GroupBy(csra => csra.ClaimName)
                               .Select(csrasByClaim => new
                {
                    ClaimName      = csrasByClaim.Key,
                    ActionStrategy = csrasByClaim
                                     .Where(csra => !string.IsNullOrEmpty(csra.ActionName))
                                     .Select(csra => new
                    {
                        csra.ActionName,
                        csra.StrategyName
                    })
                                     .ToList()
                })
                               .ToList()
            })
                                         .ToList();

            claimSetNames = claimSetsGroupedByName.Select(x => x.ClaimSetName).ToList();

            // Now augment the vertices with claimSet overrides
            foreach (var claimSet in claimSetsGroupedByName)
            {
                var claimSetName = claimSet.ClaimSetName;

                foreach (var resource in claimSet.Resources)
                {
                    var vertex = resourceGraph.Vertices.Single(x => x.ClaimName == resource.ClaimName);

                    foreach (var actionStrategy in resource.ActionStrategy)
                    {
                        var actionAndStrategyPair = vertex.ActionAndStrategyPairs.SingleOrDefault(x => x.ActionName == actionStrategy.ActionName);

                        if (actionAndStrategyPair == null)
                        {
                            // There are no ActionAndStrategyPairs because the resource doesn't have explicit metadata,
                            //      but it has an override so add the ActionAndStrategyPair now
                            var newActionAndStrategyPair = new ActionAndStrategy
                            {
                                ActionName = actionStrategy.ActionName
                                             // AuthorizationStrategy stays null since it only stores metadata,
                                             //      overrides go to StrategyOverridesByClaimSetName
                            };

                            vertex.ActionAndStrategyPairs.Add(newActionAndStrategyPair);

                            actionAndStrategyPair = newActionAndStrategyPair;
                        }

                        // Make note that we've got an override explicitly assigned
                        if (!actionAndStrategyPair.StrategyOverridesByClaimSetName.ContainsKey(claimSetName))
                        {
                            actionAndStrategyPair.StrategyOverridesByClaimSetName.Add(claimSetName, new HashSet <string>());
                        }

                        if (actionStrategy.StrategyName != null)
                        {
                            actionAndStrategyPair.StrategyOverridesByClaimSetName[claimSetName].Add(actionStrategy.StrategyName);
                        }
                    }
                }

                // Now process each of the root nodes from top to bottom to determine effective permissions at each vertex
                foreach (var rootVertex in GetRootNodes(resourceGraph))
                {
                    SetParentReferences(null, rootVertex, resourceGraph);
                }
            }

            return(resourceGraph);
        }