コード例 #1
0
        /// <summary>
        /// Creates the filter function for reading, updating or deleting data from an enumeration of models
        /// </summary>
        /// <param name="operation">The database operation that is being performed</param>
        /// <param name="identityService">The identity service to fetch the user from</param>
        /// <param name="userManager">A userManager to pass to the ACLs</param>
        /// <param name="dbContext">A dbContext to pass to the ACLs</param>
        /// <param name="serviceProvider">Service provider to pass to the ACLs</param>
        /// <typeparam name="TModel">The type of the model to add security to</typeparam>
        /// <returns>An expression that can be user for the where condition of a linq query</returns>
        public static Expression <Func <TModel, bool> > CreateSecurityFilter <TModel>(
            DATABASE_OPERATION operation,
            IIdentityService identityService,
            UserManager <User> userManager,
            LactalisDBContext dbContext,
            IServiceProvider serviceProvider)
            where TModel : IOwnerAbstractModel, new()
        {
            identityService.RetrieveUserAsync().Wait();
            var model         = new TModel();
            var userGroups    = identityService.Groups;
            var userModelAcls = model.Acls.Where(x => userGroups.Contains(x.Group) || x.IsVisitorAcl);

            Expression <Func <TModel, bool> > baseRule = _ => false;
            var filter = Expression.OrElse(baseRule.Body, baseRule.Body);

            if (!userModelAcls.Any())
            {
                // If we have no rules on this model then we should inherit from the model driven base rule
                Expression <Func <TModel, bool> > defaultFilter = _ => ALLOW_DEFAULT;
                filter = Expression.OrElse(filter, defaultFilter.Body);
            }
            else
            {
                // Otherwise combine the filter on acl with any existing filters
                var securityContext = new SecurityContext
                {
                    DbContext       = dbContext,
                    UserManager     = userManager,
                    Groups          = identityService.Groups,
                    ServiceProvider = serviceProvider,
                };
                IEnumerable <Expression <Func <TModel, bool> > > acls = null;
                switch (operation)
                {
                case DATABASE_OPERATION.READ:
                    acls = userModelAcls.Select(acl => acl.GetReadConditions <TModel>(identityService.User, securityContext));
                    break;

                case DATABASE_OPERATION.UPDATE:
                    acls = userModelAcls.Select(acl => acl.GetUpdateConditions <TModel>(identityService.User, securityContext));
                    break;

                case DATABASE_OPERATION.DELETE:
                    acls = userModelAcls.Select(acl => acl.GetDeleteConditions <TModel>(identityService.User, securityContext));
                    break;

                default:
                    break;
                }

                filter = acls.Aggregate(filter, (current, expression) =>
                                        Expression.OrElse(current, expression.Body));
            }

            var param    = Expression.Parameter(typeof(TModel), "model");
            var replacer = new ParameterReplacer(param);

            return(Expression.Lambda <Func <TModel, bool> >(replacer.Visit(filter), param));
        }
コード例 #2
0
 /// <summary>
 /// A security filter that can be used over a list of all user entities
 /// </summary>
 /// <param name="user"> The user attempting to perform the operation on all users </param>
 /// <param name="groups"> The groups the user belongs to </param>
 /// <param name="operation"> The database operation the user is trying to perform  </param>
 /// <param name="serviceProvider">Service provider to pass to the ACLs</param>
 /// <returns> An expression that can be used for the where condition of a linq query </returns>
 public static Expression <Func <User, bool> > AllUsersFilter(
     User user,
     IList <string> groups,
     DATABASE_OPERATION operation,
     IServiceProvider serviceProvider)
 {
     return(ExpressionHelper.OrExpressions(
                new List <Expression <Func <User, bool> > >
     {
         UserFilter <AdminEntity>(user, groups, "AdminEntity", operation, serviceProvider),
         UserFilter <FarmerEntity>(user, groups, "FarmerEntity", operation, serviceProvider),
     }
                ));
 }
コード例 #3
0
 /// <summary>
 /// A security filter for a single user entity
 /// </summary>
 /// <param name="user"> The user attempting to perform the operation </param>
 /// <param name="groups"> The groups the user belongs to </param>
 /// <param name="discriminator"> The user model discriminator </param>
 /// <param name="operation"> The database operation the user is trying to perform  </param>
 /// <param name="serviceProvider">Service provider to pass to the ACLs</param>
 /// <typeparam name="TModel"> The user model trying to be accessed </typeparam>
 /// <returns> An expression that can be used for the where condition of a linq query </returns>
 private static Expression <Func <User, bool> > UserFilter <TModel>(
     User user,
     IList <string> groups,
     string discriminator,
     DATABASE_OPERATION operation,
     IServiceProvider serviceProvider)
     where TModel : class, IOwnerAbstractModel, new()
 {
     return(ExpressionHelper.AndExpressions(
                new List <Expression <Func <User, bool> > >
     {
         SecurityService.GetAggregatedUserModelAcls <TModel>(user, groups, operation, serviceProvider),
         u => u.Discriminator == discriminator
     }
                ));
 }