/// <summary> /// /// Get the queries for a given user and permission or operation. /// </summary> /// <param name="subjectId"> /// The ID of the <see cref="Subject"/>, that is a <see cref="UserAccount"/> or <see cref="Role"/> instance. /// This cannot be negative. /// </param> /// <param name="permission"> /// The permission to get the query for. This should be one of <see cref="Permissions.Read"/>, /// <see cref="Permissions.Modify"/> or <see cref="Permissions.Delete"/>. Or null to match all permissions. /// </param> /// <param name="securableEntityTypes"> /// The IDs of <see cref="SecurableEntity"/> types being accessed. Or null to match all entity types. /// </param> /// <returns> /// The queries to run. /// </returns> /// <exception cref="ArgumentException"> /// <paramref name="subjectId"/> does not exist. Also, <paramref name="permission"/> should /// be one of <see cref="Permissions.Read"/>, <see cref="Permissions.Modify"/> or <see cref="Permissions.Delete"/> /// </exception> public IEnumerable <AccessRuleQuery> GetQueries(long subjectId, [CanBeNull] EntityRef permission, [CanBeNull] IList <long> securableEntityTypes) { // Get all applicable access rules for this subject/permission/types ICollection <AccessRule> accessRules = RuleRepository.GetAccessRules(subjectId, permission, securableEntityTypes); IList <AccessRuleQuery> result = new List <AccessRuleQuery>( ); // Store the enties that, when changed, should invalidate this cache entry. using (CacheContext cacheContext = CacheContext.GetContext()) using (new SecurityBypassContext()) { foreach (AccessRule allowAccess in accessRules) { Report accessRuleReport = allowAccess.AccessRuleReport; if (accessRuleReport == null) { continue; } if (allowAccess.ControlAccess == null) { continue; } // Load the report query graph Report accessRuleReportGraph = ReportEntityRepository.Get <Report>(allowAccess.AccessRuleReport.Id, ReportHelpers.QueryPreloaderQuery); // Convert the report to a structured query StructuredQuery accessRuleReportQuery = Converter.Convert(accessRuleReportGraph, ConverterSettings); StructuredQueryHelper.OptimiseAuthorisationQuery(accessRuleReportQuery); // Add cache invalidations // Consider using .. StructuredQueryHelper.IdentifyStructureCacheDependencies // See also: cacheContext in EntityAccessControlChecker.CheckAccessControlByQuery cacheContext.Entities.Add(accessRuleReport.Id); // Should this rule be considered for reports? bool ignoreForReports = allowAccess.AccessRuleIgnoreForReports == true; // Create container object AccessRuleQuery accessRuleQuery = new AccessRuleQuery(allowAccess.Id, accessRuleReport.Id, allowAccess.ControlAccess.Id, accessRuleReportQuery, ignoreForReports); result.Add(accessRuleQuery); } } return(result); }