Esempio n. 1
0
        /// <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);
        }