Exemple #1
0
        public void ActualizarRol(Rol rol)
        {
            IRol administradorRol = null;

            try
            {
                var ctx = new XmlApplicationContext("~/Modulo Seguridad/Springs/SpringRol.xml");
                administradorRol = (IRol)ctx["AdministradorRol"];
                administradorRol.ActualizarRol(rol);
            }
            catch (FaultException)
            {
                throw;
            }
            catch (Exception ex)
            {
                ThrowsExceptionParaLogError.LoguearError($"Mensaje : {ex.Message}///Excepción Interna : {ex.InnerException}///Pila de Seguimiento : {ex.StackTrace}///Fuente : {ex.Source}///Link : {ex.HelpLink}");
                throw;
            }
            finally
            {
                if (administradorRol != null)
                {
                    administradorRol.LiberarRecursos();
                }
            }
        }
Exemple #2
0
        public IEnumerable <Operacion> ObtenerOperacionesPorIdRol(int idRol)
        {
            IRol administradorRol = null;

            try
            {
                var ctx = new XmlApplicationContext("~/Modulo Seguridad/Springs/SpringRol.xml");
                administradorRol = (IRol)ctx["AdministradorRol"];
                var operaciones = administradorRol.ObtenerOperacionesPorIdRol(idRol);
                return(operaciones.ToList());
            }
            catch (FaultException)
            {
                throw;
            }
            catch (Exception ex)
            {
                ThrowsExceptionParaLogError.LoguearError($"Mensaje : {ex.Message}///Excepción Interna : {ex.InnerException}///Pila de Seguimiento : {ex.StackTrace}///Fuente : {ex.Source}///Link : {ex.HelpLink}");
                throw;
            }
            finally
            {
                if (administradorRol != null)
                {
                    administradorRol.LiberarRecursos();
                }
            }
        }
Exemple #3
0
        public void LoginUsuario()
        {
            System.Console.Out.WriteLine("Ingrese un usuario:");
            String _cadenaUsuario = System.Console.In.ReadLine();

            System.Console.Out.WriteLine("Ingrese un contraseña:");
            String _cadenaContrasena = System.Console.In.ReadLine();

            System.Console.Out.WriteLine("Se esta Autenticando espere por favor...");
            IUsuario      _usuario     = AutenticacionUsuario(_cadenaUsuario, _cadenaContrasena);
            IRol          _rol         = VerificarRolUsuario(_usuario);
            List <ITarea> _listaTareas = MostrarManejadorTareas(_rol);

            if (_listaTareas != null)
            {
                System.Console.WriteLine("Fecha\tNombre\tUsuario\tEstado");
                foreach (ITarea _tarea in _listaTareas)
                {
                    System.Console.WriteLine("%s\t%s\t%s\t%s", _tarea.ObtenerFecha(), _tarea.ObtenerNombre(), _tarea.ObtenerUsario().ObtenerNombre(), _tarea.ObtenerEstado());
                }
            }
            else
            {
                System.Console.WriteLine("Nada que listar");
            }
        }
Exemple #4
0
        internal static IPermission[] SearchPermissions(this IRol me, IFunction function = null, params IDiscriminator[] discriminators)
        {
            return(Printer.Indent($"{nameof(RolExtensions)}.{nameof(SearchPermissions)}:", () =>
            {
                Printer.Indent("Input parameters", () =>
                {
                    Printer.WriteLine($"Rol: {me.Name}");
                    Printer.WriteLine($"Function: {function?.Name ?? "<null>"}");
                    Printer.Foreach($"Discriminators:", discriminators, dis => Printer.WriteLine($"{dis.TypeName} - {dis.Name}"));
                });
                // Function validation
                if (!(function?.IsValid() ?? true))
                {
                    throw new ArgumentException($"The '{nameof(function)}' pararameter with value '{function}' has an invalid state", nameof(function));
                }
                // Discriminators validation
                //if (discriminators == null || !discriminators.Any()) throw new ArgumentException($"The '{nameof(discriminators)}' pararameter cannot be null or empty", nameof(discriminators));
                var invalidDiscriminator = discriminators?.FirstOrDefault(d => !d.IsValid());
                if (invalidDiscriminator != null)
                {
                    throw new InvalidStateException($"The '{invalidDiscriminator}' discriminator has an invalid state");
                }

                // Load all permissions recursively
                IEnumerable <IPermission> GetPermissions(IRol rol)
                {
                    var r = new List <IPermission>();
                    if (rol.Permissions != null)
                    {
                        r.AddRange(rol.Permissions);
                    }
                    if (rol.Groups != null)
                    {
                        foreach (var gro in rol.Groups)
                        {
                            r.AddRange(GetPermissions(gro));
                        }
                    }
                    return r;
                }
                var permissions = GetPermissions(me);
                Printer.Indent("Permissions:", () => permissions.Print(PrintMode.Table));
                //Printer.Foreach($"Rol permissions ({permissions.Count()}):", permissions, p =>
                //{
                //    Printer.WriteLine("Permission: " + p);
                //});

                // Filter
                var matchs = permissions.Where(p => p.Match(function, discriminators)).ToArray();
                Printer.Indent("Filtered permissions:", () => matchs.Print(PrintMode.Table));
                //Printer.WriteLine($"'{matchs.Length}' permission matches");

                return matchs;
            }));
        }
Exemple #5
0
        internal static IEnumerable <IPermission> AllPermissions(this IRol me)
        {
            var r = new List <IPermission>();

            if (me.Permissions != null)
            {
                r.AddRange(me.Permissions);
            }
            if (me.Groups != null)
            {
                foreach (var gro in me.Groups)
                {
                    r.AddRange(gro.AllPermissions());
                }
            }
            return(r);
        }
Exemple #6
0
 public List <ITarea> MostrarManejadorTareas(IRol rol)
 {
     if (rol != null)
     {
         if (rol.ObtenerNombre().Equals("SuperUsuario"))
         {
             ManejadorTareasSuperUsuario usuario = new ManejadorTareasSuperUsuario();
             return(usuario.ListarTareas());
         }
         else if (rol.ObtenerNombre().Equals("UsuarioComun"))
         {
             ManejadorTareasSuperUsuario usuario = new ManejadorTareasSuperUsuario();
             return(usuario.ListarTareas());
         }
     }
     return(null);
 }
Exemple #7
0
        internal static IPermission[] SearchPermissions(this IRol me, bool forFilter, IFunction function, TypeDiscriminator typeDiscriminator, params IDiscriminator[] discriminators)
        {
            using (var res = Printer.CallResult <IPermission[]>())
            {
                discriminators = discriminators.RemoveNulls();
                using (Printer.Indent2("Inpupt Prameters"))
                {
                    Printer.WriteLine($"Rol: {me?.Name}");
                    Printer.WriteLine($"For filter: " + forFilter);
                    Printer.WriteLine($"Function: {function?.ToString() ?? "<null>"}");
                    Printer.WriteLine($"Type discriminator: {typeDiscriminator?.ToString() ?? "<null>"}");
                    Printer.Foreach($"Discriminators:", discriminators, dis => Printer.WriteLine($"{dis}"));
                }
                // Function validation
                if (!(function?.IsValid() ?? true))
                {
                    throw new ArgumentException($"The '{nameof(function)}' pararameter with value '{function}' has an invalid state", nameof(function));
                }

                // TypeDiscriminator validation
                if (!typeDiscriminator?.IsValid() ?? false)
                {
                    throw new InvalidStateException($"The '{typeDiscriminator}' discriminator has an invalid state");
                }

                // Discriminators validation
                var invalidDiscriminator = discriminators?.FirstOrDefault(d => !d.IsValid());

                if (invalidDiscriminator != null)
                {
                    throw new InvalidStateException($"The '{invalidDiscriminator}' discriminator has an invalid state");
                }

                // Get & print rol permissions
                var permissions = me.AllPermissions();
                using (Printer.Indent2("Permissions:"))
                    permissions.Print(PrintMode.Table);
                using (Printer.Indent2("Iterate permissions:"))
                    res.Value = permissions.Where(p => p.Match(forFilter, function, typeDiscriminator, discriminators)).ToArray();
                res.OnPrintResult = r => r.Print(PrintMode.Table);
                return(res.Value);
            }
        }
Exemple #8
0
 public Nrol()
 {
     rol_repository = new Rrol();
 }
Exemple #9
0
        internal static Expression <Func <TEntity, bool> > FilterExpression <TEntity>(this IRol me, IFunction[] functions)
        {
            using (var res = Printer.CallResult <Expression <Func <TEntity, bool> > >())
            {
                #region Methods
                MethodInfo GetCastMethod(Type type) =>
                typeof(Enumerable).GetTypeInfo().DeclaredMethods
                .Where(m => m.Name == nameof(Enumerable.Cast))
                .Single(m => m.GetParameters().Length == 1)
                .MakeGenericMethod(type);
                MethodInfo GetOfTypeMethod(Type type) =>
                typeof(Enumerable).GetTypeInfo().DeclaredMethods
                .Where(m => m.Name == nameof(Enumerable.OfType))
                .Single(m => m.GetParameters().Length == 1)
                .MakeGenericMethod(type);
                MethodInfo GetToListMethod(Type type) =>
                typeof(Enumerable).GetTypeInfo().DeclaredMethods
                .Where(m => m.Name == nameof(Enumerable.ToList))
                .Single(m => m.GetParameters().Length == 1)
                .MakeGenericMethod(type);
                MethodInfo GetContainsMethod(Type type) =>
                typeof(Enumerable).GetTypeInfo().DeclaredMethods
                .Where(m => m.Name == nameof(Enumerable.Contains))
                .Single(m => m.GetParameters().Length == 2)
                .MakeGenericMethod(type);

                Expression <Func <TEntity, bool> > GetContainsExpression(bool value, IScope sco, Type disType, PropertyInfo proInfo)
                {
                    var foreignDiscriminators = Enumerable.Empty <IDiscriminator>();

                    if (sco.Propagation.HasFlag(ScopePropagation.ToMe))
                    {
                        foreignDiscriminators = foreignDiscriminators.Union(new[] { sco.Discriminator });
                    }
                    if (sco.Propagation.HasFlag(ScopePropagation.ToInclusions))
                    {
                        foreignDiscriminators = foreignDiscriminators.Union(sco.Discriminator.GetAllInclusions().Select(d => d));
                    }
                    if (sco.Propagation.HasFlag(ScopePropagation.ToExclusions))
                    {
                        foreignDiscriminators = foreignDiscriminators.Union(sco.Discriminator.GetAllExclusions().Select(d => d));
                    }
                    var foreignDiscriminatorssOfType = (IEnumerable <IDiscriminator>)GetOfTypeMethod(disType).Invoke(null, new object[] { foreignDiscriminators });

                    // Si no hay claves externas del tipo de esta propiedad, continuo con la siguiente propiedad
                    if (!foreignDiscriminatorssOfType.Any())
                    {
                        return(null);
                    }
                    var foreignKeys       = foreignDiscriminatorssOfType.Select(d => d.Id);
                    var foreignKeysCasted = GetCastMethod(proInfo.PropertyType).Invoke(null, new object[] { foreignKeys });
                    var foreignKeysListed = GetToListMethod(proInfo.PropertyType).Invoke(null, new object[] { foreignKeysCasted });


                    var entityParameter    = Expression.Parameter(typeof(TEntity));
                    var memberExpression   = Expression.Property(entityParameter, proInfo);
                    var containsExpression = Expression.Call(GetContainsMethod(proInfo.PropertyType),
                                                             Expression.Constant(foreignKeysListed, foreignKeysListed.GetType()),
                                                             memberExpression);
                    var curExp = Expression.Lambda <Func <TEntity, bool> >((value ? (Expression)containsExpression : Expression.Not(containsExpression)), entityParameter);

                    return(curExp);
                }

                #region PrintExpression
                void PrintExpression(Expression exp)
                {
                    if (exp == null)
                    {
                        Printer.WriteLine("NULL");
                    }
                    else if (exp is BinaryExpression)
                    {
                        PrintBinaryExpression(exp as BinaryExpression);
                    }
                    else if (exp is MethodCallExpression)
                    {
                        PrintMethodCallExpression(exp as MethodCallExpression);
                    }
                    else if (exp is ConstantExpression)
                    {
                        PrintConstantExpression(exp as ConstantExpression);
                    }
                    else if (exp is MemberExpression)
                    {
                        PrintMemberExpression(exp as MemberExpression);
                    }
                    else if (exp is UnaryExpression)
                    {
                        PrintUnaryExpression(exp as UnaryExpression);
                    }
                    else
                    {
                        Printer.WriteLine($"'{exp.GetType().Name}'");
                    }
                }

                void PrintBinaryExpression(BinaryExpression exp)
                {
                    using (Printer.Indent2("("))
                    {
                        PrintExpression(exp.Left);
                        if (Printer.IsLineWritePending)
                        {
                            Printer.WriteLine("");
                        }
                        Printer.WriteLine(exp.NodeType.ToString().ToUpper());
                        PrintExpression(exp.Right);
                        if (Printer.IsLineWritePending)
                        {
                            Printer.WriteLine("");
                        }
                    }
                    if (Printer.IsLineWritePending)
                    {
                        Printer.WriteLine("");
                    }
                    Printer.WriteLine(")");
                }

                void PrintMethodCallExpression(MethodCallExpression exp)
                {
                    var isExtenssionMethod = exp.Method.GetCustomAttribute <ExtensionAttribute>() != null;

                    if (isExtenssionMethod)
                    {
                        PrintExpression(exp.Arguments[0]);
                        Printer.Write($".{exp.Method.Name}(");
                        foreach (var e in exp.Arguments.Skip(1))
                        {
                            PrintExpression(e);
                        }
                    }
                    else
                    {
                        Printer.Write($"{exp.Method.Name}(");
                        foreach (var e in exp.Arguments)
                        {
                            PrintExpression(e);
                        }
                    }
                    Printer.Write(")");
                }

                void PrintConstantExpression(ConstantExpression exp)
                {
                    var r = "";

                    if (exp.Value == null)
                    {
                        r += "null";
                    }
                    else if (exp.Value.GetType().IsSubclassOfRawGeneric(typeof(List <>)))
                    {
                        var toAdd = "[";
                        foreach (var obj in (IEnumerable)exp.Value)
                        {
                            toAdd += obj + ", ";
                        }
                        toAdd = toAdd.Trim(' ', ',') + "]";
                        r    += toAdd;
                    }
                    else
                    {
                        r += exp.Value;
                    }
                    Printer.Write(r);
                }

                void PrintMemberExpression(MemberExpression exp)
                {
                    var r = "";

                    r += exp.Member.Name;
                    Printer.Write(r);
                }

                void PrintUnaryExpression(UnaryExpression exp)
                {
                    switch (exp.NodeType)
                    {
                    case ExpressionType.Not:
                        Printer.Write("!");
                        break;

                    default:
                        Printer.Write("<undefined>");
                        break;
                    }
                    PrintExpression(exp.Operand);
                }

                #endregion
                #endregion
                using (Printer.Indent2("Input parameters:"))
                {
                    Printer.WriteLine("Rol:");
                    new[] { me }.Print(PrintMode.Table);
                    Printer.WriteLine("Functions:");
                    functions.Print(PrintMode.Table);
                    Printer.WriteLine("Type: " + typeof(TEntity).Name);
                }
                res.OnPrintResult = r =>
                {
                    Printer.WriteLine("Expression:");
                    PrintExpression(r?.Body);
                    Printer.WriteLine("");
                };
                var typeDiscriminator = Factory.Get <TypeDiscriminatorFactory>().FromType <TEntity>();
                if (typeDiscriminator == null)
                {
                    Printer.WriteLine($"Type '{typeof(TEntity).Name}' hasn't TypeDiscriminator associated to it, no filter applies");
                    return(res.Value = Expression.Lambda <Func <TEntity, bool> >(Expression.Constant(true), Expression.Parameter(typeof(TEntity))));
                }

                var props = typeof(TEntity).GetDiscriminatedProperties();
                Printer.Foreach("Properties:", props, p => Printer.WriteLine($"{p.PropertyType.Name} {p.PropertyInfo.Name} - {p.DiscriminatorTypeId} {p.DiscriminatorType.Name}"));
                var pers = functions.SelectMany(fun => me.SearchPermissions(
                                                    true,
                                                    fun,
                                                    Factory.Get <TypeDiscriminatorFactory>().FromType <TEntity>(),
                                                    typeof(TEntity).GetDiscriminatorsOfDiscriminatedProperties().ToArray()
                                                    ))
                           .Distinct().ToList();
                Expression <Func <TEntity, bool> > denyPersExp = null;
                Printer.Foreach("Deny permissions:", pers.Where(p => !p.Value), per =>
                {
                    Expression <Func <TEntity, bool> > perExp = null;
                    using (Printer.Indent2($"Permission: {per.ToOneLineString()}"))
                    {
                        Printer.Foreach("Scopes:", per.Scopes, sco =>
                        {
                            using (Printer.Indent2($"Scope: {sco.ToOneLineString()}"))
                            {
                                // Recorro las propiedades que son del tipo de este discriminador
                                foreach (var pro in props.Where(p => AreEquals(p.DiscriminatorTypeId, sco.Discriminator.TypeKey)).ToList())
                                {
                                    Printer.WriteLine($"Property: {pro.PropertyType.Name} {pro.PropertyInfo.Name}");
                                    var exp = GetContainsExpression(per.Value, sco, pro.DiscriminatorType, pro.PropertyInfo);
                                    if (exp == null)
                                    {
                                        exp = Expression.Lambda <Func <TEntity, bool> >(Expression.Constant(false), Expression.Parameter(typeof(TEntity)));
                                    }
                                    if (perExp == null)
                                    {
                                        perExp = exp;
                                    }
                                    else
                                    {
                                        perExp = perExp.And(exp);
                                    }
                                }
                            }
                        });
                        if (perExp == null)
                        {
                            perExp = Expression.Lambda <Func <TEntity, bool> >(Expression.Constant(false), Expression.Parameter(typeof(TEntity)));
                        }
                    }
                    if (perExp != null)
                    {
                        if (denyPersExp != null)
                        {
                            denyPersExp = denyPersExp.And(perExp);
                        }
                        else
                        {
                            denyPersExp = perExp;
                        }
                    }
                });
                Expression <Func <TEntity, bool> > grantPersExp = null;
                Printer.Foreach("Grant permissions:", pers.Where(p => p.Value), per =>
                {
                    using (Printer.Indent2($"Permission: {per.ToOneLineString()}"))
                    {
                        Expression <Func <TEntity, bool> > perExp = null;
                        Printer.Foreach("Scopes:", per.Scopes, sco =>
                        {
                            using (Printer.Indent2($"Scope: {sco.ToOneLineString()}"))
                            {
                                // Recorro las propiedades que son del tipo de este discriminador
                                foreach (var pro in props.Where(p => AreEquals(p.DiscriminatorTypeId, sco.Discriminator.TypeKey)).ToList())
                                {
                                    Printer.WriteLine($"Property: {pro.PropertyType.Name} {pro.PropertyInfo.Name}");
                                    var exp = GetContainsExpression(per.Value, sco, pro.DiscriminatorType, pro.PropertyInfo);
                                    if (exp == null)
                                    {
                                        exp = Expression.Lambda <Func <TEntity, bool> >(Expression.Constant(false), Expression.Parameter(typeof(TEntity)));
                                    }
                                    if (perExp == null)
                                    {
                                        perExp = exp;
                                    }
                                    else
                                    {
                                        perExp = perExp.Or(exp);
                                    }
                                }
                            }
                        });
                        if (perExp == null)
                        {
                            perExp = Expression.Lambda <Func <TEntity, bool> >(Expression.Constant(true), Expression.Parameter(typeof(TEntity)));
                        }
                        if (perExp != null)
                        {
                            if (grantPersExp != null)
                            {
                                grantPersExp = grantPersExp.Or(perExp);
                            }
                            else
                            {
                                grantPersExp = perExp;
                            }
                        }
                    }
                });
                if (denyPersExp != null && grantPersExp != null)
                {
                    res.Value = denyPersExp.And(grantPersExp);
                }
                if (denyPersExp != null && grantPersExp == null)
                {
                    res.Value = denyPersExp;
                }
                if (denyPersExp == null && grantPersExp != null)
                {
                    res.Value = grantPersExp;
                }
                res.Value = res.Value ?? Expression.Lambda <Func <TEntity, bool> >(Expression.Constant(false), Expression.Parameter(typeof(TEntity)));


                return(res.Value);
            }
        }
Exemple #10
0
 public static bool IsRoot(this IRol me)
 {
     using (var res = Printer.CallResult <bool>())
         return(res.Value = me.Can(Functions.Admin).Anything());
 }
Exemple #11
0
 public frmUsuario()
 {
     InitializeComponent();
     usua = new MUsuario();
     rol  = new MRol();
 }
Exemple #12
0
 public static IRolCan Can(this IRol me, params IFunction[] functions)
 => new _RolCan(me, functions, false);
Exemple #13
0
 public static IRolCan EnsureCan(this IRol me, params IFunction[] functions)
 => new _RolCan(me, functions, true);
Exemple #14
0
 public RolController(IRol rol)
 {
     _rol = rol;
 }
Exemple #15
0
 public _RolCan(IRol rol, IFunction[] functions, bool throwExceptionIfCannot)
 {
     Rol       = rol;
     Functions = functions;
     ThrowExceptionIfCannot = throwExceptionIfCannot;
 }
Exemple #16
0
 public static bool IsRoot(this IRol me) => me.Can(Functions.Admin).Anything();
 public RolController(IRol rol)
 {
     _rol = rol;
 }
Exemple #18
0
        public static IEnumerable <TSource> AuthorizedTo <TSource>(this IEnumerable <TSource> source, IRol rol, params IFunction[] functions)
        {
            if (rol == null)
            {
                rol = Factory.Get <IdentityManager>().GetCurrent();
            }
            var pre = rol.FilterExpression <TSource>(functions);

            return(source is IQueryable <TSource>
                   ?((IQueryable <TSource>)source).Where(pre)
                       : source.Where(pre.Compile()));
        }
Exemple #19
0
 public DetallesUsuario()
 {
     usr = new MUsuario();
     rl  = new MRol();
 }
Exemple #20
0
        public static IQueryable <TSource> AuthorizedTo <TSource>(this IQueryable <TSource> source, IRol rol, params IFunction[] functions)
        {
            if (rol == null)
            {
                rol = Factory.Get <IdentityManager>().GetCurrent();
            }
            var pre = rol.FilterExpression <TSource>(functions);

            //if (pre == null) return Enumerable.Empty<TSource>().AsQueryable();
            return(source.Where(pre));
        }
Exemple #21
0
 public List <ITarea> MostrarManejadorTareas(IRol rol)
 {
     throw new NotImplementedException();
 }
Exemple #22
0
        internal static Expression <Func <TEntity, bool> > FilterExpression <TEntity>(this IRol me, IFunction[] functions)
        {
            return(Printer.Indent($"{typeof(RolExtensions).GetTypeInfo().DeclaredMethods.FirstOrDefault(m => m.Name == nameof(FilterExpression)).GetSignature()}:", () =>
            {
                Printer.Indent("Input parameters:", () =>
                {
                    Printer.WriteLine("Rol:");
                    new[] { me }.Print(PrintMode.Table);
                    Printer.WriteLine("Functions:");
                    functions.Print(PrintMode.Table);
                    Printer.WriteLine("Type: " + typeof(TEntity).Name);
                });
                #region Methods
                var getCastMethod = new Func <Type, MethodInfo>(type =>
                                                                typeof(Enumerable).GetTypeInfo().DeclaredMethods
                                                                .Where(m => m.Name == nameof(Enumerable.Cast))
                                                                .Single(m => m.GetParameters().Length == 1)
                                                                .MakeGenericMethod(type));
                var getOfTypeMethod = new Func <Type, MethodInfo>(type =>
                                                                  typeof(Enumerable).GetTypeInfo().DeclaredMethods
                                                                  .Where(m => m.Name == nameof(Enumerable.OfType))
                                                                  .Single(m => m.GetParameters().Length == 1)
                                                                  .MakeGenericMethod(type));
                var getToListMethod = new Func <Type, MethodInfo>(type =>
                                                                  typeof(Enumerable).GetTypeInfo().DeclaredMethods
                                                                  .Where(m => m.Name == nameof(Enumerable.ToList))
                                                                  .Single(m => m.GetParameters().Length == 1)
                                                                  .MakeGenericMethod(type));
                var getContainsMethod = new Func <Type, MethodInfo>(type =>
                                                                    typeof(Enumerable).GetTypeInfo().DeclaredMethods
                                                                    .Where(m => m.Name == nameof(Enumerable.Contains))
                                                                    .Single(m => m.GetParameters().Length == 2)
                                                                    .MakeGenericMethod(type));
                var getContainsExpression = new Func <bool, IScope, Type, PropertyInfo, Expression <Func <TEntity, bool> > >((value, sco, disType, proInfo) =>
                {
                    IEnumerable <IDiscriminator> foreignDiscriminators = Enumerable.Empty <IDiscriminator>();
                    if (sco.Propagation.HasFlag(ScopePropagation.ToMe))
                    {
                        foreignDiscriminators = foreignDiscriminators.Union(new[] { sco.Discriminator });
                    }
                    if (sco.Propagation.HasFlag(ScopePropagation.ToInclusions))
                    {
                        foreignDiscriminators = foreignDiscriminators.Union(sco.Discriminator.GetAllInclusions().Select(d => d));
                    }
                    if (sco.Propagation.HasFlag(ScopePropagation.ToExclusions))
                    {
                        foreignDiscriminators = foreignDiscriminators.Union(sco.Discriminator.GetAllExclusions().Select(d => d));
                    }
                    var foreignDiscriminatorssOfType = (IEnumerable <IDiscriminator>)getOfTypeMethod(disType).Invoke(null, new object[] { foreignDiscriminators });
                    // Si no hay claves externas del tipo de esta propiedad, continuo con la siguiente propiedad
                    if (!foreignDiscriminatorssOfType.Any())
                    {
                        return null;
                    }
                    var foreignKeys = foreignDiscriminatorssOfType.Select(d => d.Id);
                    var foreignKeysCasted = getCastMethod(proInfo.PropertyType).Invoke(null, new object[] { foreignKeys });
                    var foreignKeysListed = getToListMethod(proInfo.PropertyType).Invoke(null, new object[] { foreignKeysCasted });


                    var entityParameter = Expression.Parameter(typeof(TEntity));
                    var memberExpression = Expression.Property(entityParameter, proInfo);
                    var containsExpression = Expression.Call(getContainsMethod(proInfo.PropertyType),
                                                             Expression.Constant(foreignKeysListed, foreignKeysListed.GetType()),
                                                             memberExpression);
                    var curExp = Expression.Lambda <Func <TEntity, bool> >((value ? (Expression)containsExpression : Expression.Not(containsExpression)), entityParameter);
                    return curExp;
                });
                #endregion
                var props = typeof(TEntity).GetRuntimeProperties()
                            .Where(p => p.GetCustomAttribute <DiscriminatedByAttribute>(true, false, false) != null)
                            .Select(p => new
                {
                    PropertyInfo = p,
                    PropertyType = p.PropertyType,
                    DiscriminatorType = p.GetCustomAttribute <DiscriminatedByAttribute>(true).Type,
                    DiscriminatorTypeId =
                        p.GetCustomAttribute <DiscriminatedByAttribute>(true).Type.GetTypeInfo()
                        .GetCustomAttribute <DiscriminatorAttribute>(true).TypeId,
                });
                Printer.Foreach("Properties:", props, p => Printer.WriteLine($"{p.PropertyType.Name} {p.PropertyInfo.Name}"));
                Expression <Func <TEntity, bool> > res = null;
                // Load permissions for all given functions
                var pers = functions.SelectMany(fun => me.SearchPermissions(fun, Factory.Get <TypeDiscriminatorFactory>().FromType <TEntity>())).Distinct().ToList();
                //var pers = functions.SelectMany(fun => me.SearchPermissions(fun)).Distinct().ToList();
                //var pers = me.SearchPermissions().ToList();
                // Los permisos se agrupan por Value (concesión/denegación) y se combinan estos grupos con AND
                // Los permisos de denegación, se combinan entre ellos con AND
                // Los permisos de concesión, se combinan entre ellos con OR
                // Ejemplo:
                // (
                //    Denypermission1
                //    AND
                //    DenyPermission2
                //    AND
                //    DenyPermission3
                // )
                // AND
                // (
                //    GrantPermission1
                //    OR
                //    GrantPermission2
                //    OR
                //    GrantPermission3
                // )
                Expression <Func <TEntity, bool> > denyPersExp = null;
                Printer.Foreach("Deny permissions:", pers.Where(p => !p.Value), per =>
                {
                    Expression <Func <TEntity, bool> > perExp = null;
                    Printer.Indent($"Permission: {per}", () =>
                    {
                        Printer.Foreach("Scopes:", per.Scopes, sco =>
                        {
                            Printer.Indent($"Scope: {sco}", () =>
                            {
                                // Recorro las propiedades que son del tipo de este discriminador
                                foreach (var pro in props.Where(p => p.DiscriminatorTypeId.Equals(sco.Discriminator.TypeId)).ToList())
                                {
                                    Printer.WriteLine($"Property: {pro.PropertyType.Name} {pro.PropertyInfo.Name}");
                                    var exp = getContainsExpression(per.Value, sco, pro.DiscriminatorType, pro.PropertyInfo);
                                    if (exp == null)
                                    {
                                        exp = Expression.Lambda <Func <TEntity, bool> >(Expression.Constant(false), Expression.Parameter(typeof(TEntity)));
                                    }
                                    if (perExp == null)
                                    {
                                        perExp = exp;
                                    }
                                    else
                                    {
                                        perExp = perExp.And(exp);
                                    }
                                }
                            });
                        });
                        if (!per.Scopes.Any())
                        {
                            perExp = Expression.Lambda <Func <TEntity, bool> >(Expression.Constant(false), Expression.Parameter(typeof(TEntity)));
                        }
                    });
                    if (perExp != null)
                    {
                        if (denyPersExp != null)
                        {
                            denyPersExp = denyPersExp.And(perExp);
                        }
                        else
                        {
                            denyPersExp = perExp;
                        }
                    }
                });
                Expression <Func <TEntity, bool> > grantPersExp = null;
                Printer.Foreach("Grant permissions:", pers.Where(p => p.Value), per =>
                {
                    Printer.Indent($"Permission: Value<{per.Value}> - Function<{per.Function.Name}> - Scopes<{per.Scopes.Count()}>", () =>
                    {
                        Expression <Func <TEntity, bool> > perExp = null;
                        Printer.Foreach("Scopes:", per.Scopes, sco =>
                        {
                            Printer.Indent($"Scope: Discriminator<{sco.Discriminator.Name}({sco.Discriminator.Id})> - Propagation<{sco.Propagation}>", () =>
                            {
                                // Recorro las propiedades que son del tipo de este discriminador
                                foreach (var pro in props.Where(p => p.DiscriminatorTypeId.Equals(sco.Discriminator.TypeId)).ToList())
                                {
                                    Printer.WriteLine($"Property: {pro.PropertyType.Name} {pro.PropertyInfo.Name}");
                                    var exp = getContainsExpression(per.Value, sco, pro.DiscriminatorType, pro.PropertyInfo);
                                    if (exp == null)
                                    {
                                        exp = Expression.Lambda <Func <TEntity, bool> >(Expression.Constant(false), Expression.Parameter(typeof(TEntity)));
                                    }
                                    if (perExp == null)
                                    {
                                        perExp = exp;
                                    }
                                    else
                                    {
                                        perExp = perExp.Or(exp);
                                    }
                                }
                            });
                        });
                        //if (!per.Scopes.Any())
                        if (perExp == null)
                        {
                            perExp = Expression.Lambda <Func <TEntity, bool> >(Expression.Constant(true), Expression.Parameter(typeof(TEntity)));
                        }
                        if (perExp != null)
                        {
                            if (grantPersExp != null)
                            {
                                grantPersExp = grantPersExp.Or(perExp);
                            }
                            else
                            {
                                grantPersExp = perExp;
                            }
                        }
                    });
                });
                if (denyPersExp != null && grantPersExp != null)
                {
                    res = denyPersExp.And(grantPersExp);
                }
                if (denyPersExp != null && grantPersExp == null)
                {
                    res = denyPersExp;
                }
                if (denyPersExp == null && grantPersExp != null)
                {
                    res = grantPersExp;
                }
                res = res ?? Expression.Lambda <Func <TEntity, bool> >(Expression.Constant(false), Expression.Parameter(typeof(TEntity)));

                Printer.WriteLine("Expression:");
                PrintExpression(res?.Body);
                if (Printer.IsLineWritePending)
                {
                    Printer.WriteLine("");
                }

                return res;
            }));
        }