public bool Evaluate(Function function, JObject subject, JObject resource, JObject environment)
        {
            if (function == null)
            {
                return(true);
            }

            var parameters = new List <object>();

            foreach (var param in function.Parameters)
            {
                // if parameter is another function
                if (param.Value == null)
                {
                    parameters.Add(InvokeFunction(param, subject, resource, environment));
                }
                else
                {
                    // if parameter is a constant value
                    if (param.ResourceID == null)
                    {
                        parameters.Add(param.Value);
                    }
                    // if parameter is a value taken from repository
                    else
                    {
                        JToken value = null;
                        switch (param.ResourceID)
                        {
                        case "Subject":
                            value = subject.SelectToken(param.Value);
                            break;

                        case "Environment":
                            value = environment.SelectToken(param.Value);
                            break;

                        default:
                            value = resource.SelectToken(param.Value);
                            break;
                        }
                        //if (value == null)
                        //    throw new ConditionalExpressionException(string.Format(ErrorMessage.MissingField, param.Value, param.ResourceID));
                        parameters.Add(value);
                    }
                }
            }
            var    factory = UserDefinedFunctionFactory.GetInstance();
            string result  = factory.ExecuteFunction(function.FunctionName, parameters.ToArray()).ToString();
            bool   isConvertSuccessfully = Boolean.TryParse(result, out bool expressionResult);

            if (!isConvertSuccessfully)
            {
                throw new ConditionalExpressionException(string.Format("Method {0} didn't return boolean value", function.FunctionName));
            }

            return(expressionResult);
        }
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            // Add framework services.
            services.AddMvc();

            //services.Configure<MongoDbContextProvider>(Configuration);
            services.AddSingleton(new MongoDbContextProvider()
            {
                ConnectionString   = Configuration["MongoDbContextProvider:ConnectionString"],
                PolicyDatabaseName = Configuration["MongoDbContextProvider:PolicyDatabaseName"],
                UserCollectionName = Configuration["MongoDbContextProvider:UserCollectionName"],
                UserDatabaseName   = Configuration["MongoDbContextProvider:UserDatabaseName"]
            });

            MongoDbContextProvider.Setup();

            services.AddScoped(typeof(IAccessControlPolicyRepository), typeof(AccessControlPolicyMongoDbRepository));
            services.AddScoped(typeof(IPrivacyPolicyRepository), typeof(PrivacyPolicyMongoDbRepository));
            services.AddScoped(typeof(IPolicyCombiningRepository), typeof(PolicyCombiningMongoDbRepository));
            services.AddScoped(typeof(IPrivacyDomainRepository), typeof(PrivacyDomainMongoDbRepository));
            services.AddScoped(typeof(IResourceRepository), typeof(ResourceMongoDbRepository));
            services.AddScoped(typeof(ISubjectRepository), typeof(SubjectMongoDbRepository));

            services.AddSingleton(typeof(AccessControlService));
            services.AddSingleton(typeof(PrivacyService));
            services.AddSingleton(typeof(SecurityService));
            services.AddSingleton(typeof(ConditionalExpressionService));

            var corsBuilder = new CorsPolicyBuilder();

            corsBuilder.AllowAnyHeader();
            corsBuilder.AllowAnyMethod();
            corsBuilder.AllowAnyOrigin(); // For anyone access.
            corsBuilder.AllowCredentials();

            services.AddCors(options =>
            {
                options.AddPolicy("CorsPolicy", corsBuilder.Build());
            });

            var pluginFunctionFactory = UserDefinedFunctionFactory.GetInstance();

            pluginFunctionFactory.RegisterDefaultFunctions();

            var domainFactory = PrivacyDomainPluginFactory.GetInstance();

            domainFactory.RegisterDefaultPlugin();
        }
        private static IContainer SetupContainer()
        {
            MongoDbContextProvider.Setup();

            var builder = new ContainerBuilder();

            builder.RegisterType <AccessControlPolicyMongoDbRepository>().As <IAccessControlPolicyRepository>();
            builder.RegisterType <PrivacyPolicyMongoDbRepository>().As <IPrivacyPolicyRepository>();
            builder.RegisterType <PolicyCombiningMongoDbRepository>().As <IPolicyCombiningRepository>();
            builder.RegisterType <PrivacyDomainMongoDbRepository>().As <IPrivacyDomainRepository>().SingleInstance();
            builder.RegisterType <AccessControlPolicyMongoDbRepository>().As <IAccessControlPolicyRepository>();
            builder.RegisterType <SubjectMongoDbRepository>().As <ISubjectRepository>();
            builder.RegisterType <ResourceMongoDbRepository>().As <IResourceRepository>();

            builder.RegisterType <LoggerFactory>().As <ILoggerFactory>().SingleInstance();
            builder.RegisterType <Logger <AccessControlService> >().As <ILogger <AccessControlService> >();
            builder.RegisterType <Logger <PrivacyService> >().As <ILogger <PrivacyService> >();
            builder.RegisterType <Logger <ConditionalExpressionService> >().As <ILogger <ConditionalExpressionService> >();

            builder.Register(c => new MongoDbContextProvider()
            {
                ConnectionString   = "mongodb://localhost:27017",
                PolicyDatabaseName = "Policy",
                UserCollectionName = "UserDB",
                UserDatabaseName   = "UserDB"
            }).SingleInstance();

            builder.RegisterType <AccessControlService>().SingleInstance();
            builder.RegisterType <PrivacyService>().SingleInstance();
            builder.RegisterType <ConditionalExpressionService>().SingleInstance();
            builder.RegisterType <SecurityService>().SingleInstance();

            var pluginFunctionFactory = UserDefinedFunctionFactory.GetInstance();

            pluginFunctionFactory.RegisterDefaultFunctions();

            var domainFactory = PrivacyDomainPluginFactory.GetInstance();

            domainFactory.RegisterDefaultPlugin();

            var container = builder.Build();

            return(container);
        }
        public IEnumerable <string> Get()
        {
            var function = UserDefinedFunctionFactory.GetInstance();

            return(function.GetAllFunctionNames());
        }
        private string InvokeFunction(Function function, JObject subject, JObject resource, JObject environment)
        {
            var parameters = new List <string>();

            foreach (var param in function.Parameters)
            {
                // if parameter is another function
                if (param.Value == null)
                {
                    string resultFunctionInvoke = InvokeFunction(param, subject, resource, environment);

                    bool isOrOperatorEscape  = (function.FunctionName.Equals("Or", StringComparison.OrdinalIgnoreCase) && resultFunctionInvoke.Equals("true"));
                    bool isAndOperatorEscape = (function.FunctionName.Equals("And", StringComparison.OrdinalIgnoreCase) && resultFunctionInvoke.Equals("false"));

                    if (isOrOperatorEscape || isAndOperatorEscape)
                    {
                        return(resultFunctionInvoke);
                    }
                    else
                    {
                        parameters.Add(resultFunctionInvoke);
                    }
                }
                else
                {
                    // if parameter is a constant value
                    if (param.ResourceID == null)
                    {
                        parameters.Add(param.Value);
                    }
                    // if parameter is a value taken from repository
                    else
                    {
                        JToken value = null;
                        switch (param.ResourceID)
                        {
                        case "Subject":
                            value = subject.SelectToken(param.Value);
                            break;

                        case "Environment":
                            value = environment.SelectToken(param.Value);
                            break;

                        default:
                            value = resource.SelectToken(param.Value);
                            break;
                        }
                        if (value == null)
                        {
                            throw new ConditionalExpressionException(string.Format(ErrorMessage.MissingField, param.Value, param.ResourceID));
                        }

                        parameters.Add(value.ToString());
                    }
                }
            }
            var    factory = UserDefinedFunctionFactory.GetInstance();
            string result  = factory.ExecuteFunction(function.FunctionName, parameters.ToArray());

            return(result);
        }
        private FunctionInfo GetUserFunction(string keyword)
        {
            var factory = UserDefinedFunctionFactory.GetInstance();

            return(factory.GetFunction(keyword));
        }