protected void SearchIssuer(QueryContext context, GraphIssuer issuer) { var tracker = new GraphTracker(issuer); context.Tracker.Push(tracker); // Set the Issuer to visited bit, avoiding re-searching the issuer context.Visited.SetFast(issuer.Index, true); // Process current level if (context.Tracker.Count == context.Level) { context.IssuerCount++; // Run though all targets foreach (var targetIndex in context.Targets.Keys) { // Check the current issuer if it has trusted the target! if (!issuer.TryGetSubject(targetIndex, out GraphSubject graphSubject)) { continue; } tracker.SubjectKey = targetIndex; context.SubjectCount++; SearchSubject(context, tracker, graphSubject); } } else { // Otherwise continue down! if (issuer.SubjectsCount() > 0) { foreach (var subjectEntry in issuer.Subjects) // Need only to iterate subjects that are entities not things { tracker.SubjectKey = subjectEntry.Key; if (context.Visited.GetFast(subjectEntry.Value.TargetIssuer.Index)) { continue; } if (FollowIssuer(context, subjectEntry.Value)) { SearchIssuer(context, subjectEntry.Value.TargetIssuer); } } } } context.Tracker.Pop(); }
protected void SearchSubject(QueryContext context, GraphTracker tracker, GraphSubject subject) { var claims = FilterClaims(context, subject); // Filter down to claim searching on if (claims.Count == 0) { return; } BuildResult(context, tracker, claims); // Target found! var targetIssuer = tracker.Issuer.Subjects[tracker.SubjectKey].TargetIssuer; context.TargetsFound[targetIssuer.Index] = targetIssuer; }
protected void BuildResult(QueryContext context, GraphTracker currentTracker, List <int> claimsFound) { if ((context.Flags & QueryFlags.LeafsOnly) == QueryFlags.LeafsOnly) { AddResult(context, currentTracker.Issuer.Index, claimsFound, currentTracker); } else { // Full tree, or first path foreach (var tracker in context.Tracker) { AddResult(context, currentTracker.Issuer.Index, claimsFound, tracker); } } }
protected void SearchSubject(QueryContext context, GraphTracker tracker, GraphSubject subject) { int index = 0; var claims = GetClaims(context, subject); //foreach (var type in context.ClaimTypes) //{ // if (subject.Claims.GetIndex(context.ClaimScope, type, out index)) // Check local scope for claims // claims.Add(new Tuple<long, int>(new SubjectClaimIndex(context.ClaimScope, type).Value, index)); // else // if (subject.Claims.GetIndex(TrustService.GlobalScopeIndex, type, out index)) // Check global scope for claims // claims.Add(new Tuple<long, int>(new SubjectClaimIndex(TrustService.GlobalScopeIndex, type).Value, index)); //} if (claims.Count == 0) { return; } if (context.Flags == QueryFlags.IncludeClaimTrust) { if (subject.Claims.GetIndex(context.ClaimScope, context.BinaryClaimTypeIndex, out index)) // Check local scope for claims { claims.Add(new Tuple <long, int>(new SubjectClaimIndex(context.ClaimScope, context.BinaryClaimTypeIndex).Value, index)); } } //else // Check Global scope disable for now. Need more expirence. //if (subject.Claims.GetIndex(TrustService.GlobalScopeIndex, TrustService.BinaryClaimTypeIndex, out index)) // Check global scope for claims //claims.Add(new Tuple<long, int>(new SubjectClaimIndex(TrustService.GlobalScopeIndex, TrustService.BinaryClaimTypeIndex).Value, index)); BuildResult(context, tracker, claims); // Target found! var targetIssuer = tracker.Issuer.Subjects[tracker.SubjectKey].TargetIssuer; context.TargetsFound[targetIssuer.Index] = targetIssuer; }
private void AddResult(QueryContext context, int issuerIndex, List <int> claimsFound, GraphTracker tracker) { if (!context.TrackerResults.ContainsKey(tracker.Issuer.Index)) { tracker.Subjects = new GraphSubjectDictionary <int, GraphSubject>(); context.TrackerResults.Add(tracker.Issuer.Index, tracker); } var result = context.TrackerResults[tracker.Issuer.Index]; GraphSubject graphSubject; if (!result.Subjects.ContainsKey(tracker.SubjectKey)) { // Only subjects with unique keys graphSubject = tracker.Issuer.Subjects[tracker.SubjectKey]; // GraphSubject is a value type and therefore its copied //graphSubject.Claims = new ConcurrentDictionary<long, int>(); //graphSubject.Claims = new GraphSubjectDictionary<long, int>(); var subject = tracker.Issuer.Subjects[tracker.SubjectKey]; graphSubject.Claims = FilterClaims(context, subject); result.Subjects.Add(tracker.SubjectKey, graphSubject); // Register the target found } else { graphSubject = result.Subjects[tracker.SubjectKey]; } //if (graphSubject.ClaimCount() == 0) //{ // // Add claims to the current tracker level. // var subject = tracker.Issuer.Subjects[tracker.SubjectKey]; // var claims = FilterClaims(context, subject); // foreach (var item in claims) // { // result.Subjects[tracker.SubjectKey].AddClaim(item); // //result.Subjects[tracker.SubjectKey].Claims[item.Item1] = item.Item2; // } //} }