/// <summary> /// Get the queries for a given user and permission or operation. /// </summary> /// <returns> /// The list of queries filtered according to the QueryFilter setting. /// </returns> public IEnumerable <AccessRuleQuery> GetQueries(long subjectId, [CanBeNull] Model.EntityRef permission, [CanBeNull] IList <long> securableEntityTypes) { IEnumerable <AccessRuleQuery> unfiltered; IEnumerable <AccessRuleQuery> filtered; unfiltered = Repository.GetQueries(subjectId, permission, securableEntityTypes); // Note: DoesQueryReferToCurrentUser gets cached within the object, so it's cheap to re-enumerate anyway. if (QueryFilter == AccessControl.QueryFilter.RefersToCurrentUser) { filtered = unfiltered.Where(accessRuleQuery => accessRuleQuery.DoesQueryReferToCurrentUser( )); } else { filtered = unfiltered.Where(accessRuleQuery => !accessRuleQuery.DoesQueryReferToCurrentUser( )); } return(filtered); }
/// <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> /// <exception cref="ArgumentNullException"> /// Neither <paramref name="permission"/> nor <paramref name="securableEntityTypes"/> can be null. /// </exception> public IEnumerable <AccessRuleQuery> GetQueries(long subjectId, [CanBeNull] Model.EntityRef permission, [CanBeNull] IList <long> securableEntityTypes) { SubjectPermissionTypesTuple tuple; IEnumerable <AccessRuleQuery> result; result = null; tuple = new SubjectPermissionTypesTuple(subjectId, permission, securableEntityTypes); if (!Cache.TryGetValue(tuple, out result)) { using (CacheContext cacheContext = new CacheContext( )) { result = Repository.GetQueries(subjectId, permission, securableEntityTypes).ToList( ); try { Cache.Add(tuple, result); // Add the cache context entries to the appropriate CacheInvalidator _cacheInvalidator.AddInvalidations(cacheContext, tuple); } catch (ArgumentException) { Trace.WriteLine("CachingQueryRepository: Entity already in cache"); throw; } } } else if (CacheContext.IsSet( )) { using (CacheContext cacheContext = CacheContext.GetContext( )) { // Add the already stored changes that should invalidate this cache // entry to any outer or containing cache contexts. cacheContext.AddInvalidationsFor(_cacheInvalidator, tuple); } } return(result); }
/// <summary> /// Check access. /// </summary> public IDictionary <long, bool> CheckAccess(IList <Model.EntityRef> entities, IList <Model.EntityRef> permissions, Model.EntityRef user) { if (entities == null) { throw new ArgumentNullException(nameof(entities)); } if (permissions == null) { throw new ArgumentNullException(nameof(permissions)); } if (user == null) { throw new ArgumentNullException(nameof(user)); } #if DEBUG if (entities.Any(x => x == null)) { throw new ArgumentException(@"Cannot contain null entries", nameof(entities)); } if (permissions.Any(x => x == null)) { throw new ArgumentException(@"Cannot contain null entries", nameof(permissions)); } #endif return(Checker.CheckAccess(entities, permissions, user)); }
/// <summary> /// Is there an access rule for the specified type(s) that includes the requested permission? E.g. create. /// </summary> /// <param name="entityTypes">The <see cref="Model.EntityType"/>s to check. This cannot be null or contain null.</param> /// <param name="permission">The permission being sought.</param> /// <param name="user"> The user requesting access. This cannot be null. </param> public IDictionary <long, bool> CheckTypeAccess(IList <Model.EntityType> entityTypes, Model.EntityRef permission, Model.EntityRef user) { if (entityTypes == null) { throw new ArgumentNullException(nameof(entityTypes)); } if (entityTypes.Contains(null)) { throw new ArgumentNullException(nameof(entityTypes), "Cannot contain null"); } if (permission == null) { throw new ArgumentNullException(nameof(permission)); } if (user == null) { throw new ArgumentNullException(nameof(user)); } return(Checker.CheckTypeAccess(entityTypes, permission, user)); }
/// <summary> /// Check access. /// </summary> public IDictionary <long, bool> CheckAccess(IList <Model.EntityRef> entities, IList <Model.EntityRef> permissions, Model.EntityRef user) { if (entities == null) { throw new ArgumentNullException("entities"); } if (permissions == null) { throw new ArgumentNullException("permissions"); } if (user == null) { throw new ArgumentNullException("user"); } IDictionary <long, bool> result; // Check using first checker IDictionary <long, bool> firstResult = FirstChecker.CheckAccess(entities, permissions, user); // Determine denied entries List <EntityRef> outstandingEntities = null; bool anyGrantsInFirst = false; foreach (EntityRef entity in entities) { if (firstResult[entity.Id]) { anyGrantsInFirst = true; } else { if (outstandingEntities == null) { outstandingEntities = new List <EntityRef>( ); } outstandingEntities.Add(entity); } } if (outstandingEntities == null) { result = firstResult; } else { // Check using second checker IDictionary <long, bool> secondResult = SecondChecker.CheckAccess(outstandingEntities, permissions, user); // If first granted nothing, then second checker gives a complete picture of the result if (!anyGrantsInFirst) { result = secondResult; } else { // Combine results from both checkers result = new Dictionary <long, bool>(entities.Count); foreach (var pair in firstResult) { result[pair.Key] = pair.Value || secondResult [pair.Key]; } } } return(result); }