private static void HandleError(IApplicationBuilder builder)
        {
            if (Exceptions.Any(p => p.Value.Any()))
            {
                builder.Run(
                    async context =>
                {
                    context.Response.StatusCode  = (int)HttpStatusCode.InternalServerError;
                    context.Response.ContentType = "text/html";

                    IExceptionHandlerFeature error = context.Features.Get <IExceptionHandlerFeature>();
                    if (error != null)
                    {
                        await context.Response.WriteAsync($"<h1>Error: {error.Error.Message}</h1>").ConfigureAwait(false);
                    }
                    StringBuilder errorDetails = new StringBuilder();
                    foreach (KeyValuePair <string, List <Exception> > ex in Exceptions)
                    {
                        foreach (Exception val in ex.Value)
                        {
                            errorDetails.Append($"<h2>Error on {ex.Key}: {val.Message}</h2>");
                            errorDetails.Append($"<h3>Further details: {val.StackTrace}</h3>");
                        }
                    }
                    await context.Response.WriteAsync(errorDetails.ToString()).ConfigureAwait(false);
                    KraftLogger.LogError(errorDetails.ToString());
                });
                return;
            }
        }
예제 #2
0
 public static void RestartApplication(IHostApplicationLifetime applicationLifetime, RestartReason restartReason, Action <bool> restart = null)
 {
     try
     {
         if (applicationLifetime != null)
         {
             if (restartReason != null)
             {
                 KraftLogger.LogDebug($"Method: RestartApplication: Stopping application Reason: {restartReason.Reason} additional info {restartReason.Description}");
             }
             applicationLifetime.StopApplication();
             if (!applicationLifetime.ApplicationStopping.IsCancellationRequested)
             {
                 Task.Delay(10 * 1000, applicationLifetime.ApplicationStopping);
             }
             restart?.Invoke(true);
         }
         else
         {
             KraftLogger.LogDebug("Method: RestartApplication: applicationLifetime is null.");
         }
     }
     catch (Exception exception)
     {
         KraftLogger.LogError(exception, "Method: RestartApplication(IApplicationLifetime applicationLifetime)");
     }
 }
예제 #3
0
        public IActionResult Error()
        {
            IExceptionHandlerPathFeature exceptionHandlerPathFeature = HttpContext.Features.Get <IExceptionHandlerPathFeature>();

            KraftLogger.LogCritical($"Method: public IActionResult Error for path: {exceptionHandlerPathFeature?.Path}", exceptionHandlerPathFeature?.Error);
            return(View());
        }
예제 #4
0
        protected bool CheckValidity(IProcessingContext processingContext, KraftModule module, LoadedNodeSet loadedNodeSet)
        {
            if (processingContext.InputModel.LoaderType == ELoaderType.None)
            {
                Utilities.ExtensionMethods.KraftResult(_HttpContext, HttpStatusCode.NotFound, $"You have to specify a loader type.");
                return(false);
            }
            if (module == null)
            {
                Utilities.ExtensionMethods.KraftResult(_HttpContext, HttpStatusCode.NotFound, $"Requested module: {processingContext.InputModel.Module} doesn't exist or not loaded.");
                return(false);
            }

            if (loadedNodeSet == null)
            {
                Utilities.ExtensionMethods.KraftResult(_HttpContext, HttpStatusCode.NotFound, $"Requested nodeset: {processingContext.InputModel.NodeSet} doesn't exist or not loaded.");
                return(false);
            }
            if (loadedNodeSet.StartNode == null)//Handle errors better and show when a node is addressed but missing.
            {
                string error = $"Node: {processingContext.InputModel.Nodepath} from module: {processingContext.InputModel.Module}, nodeset: {processingContext.InputModel.NodeSet} is missing!";
                KraftLogger.LogError(error);
                Utilities.ExtensionMethods.KraftResult(_HttpContext, HttpStatusCode.InternalServerError, error);
                return(false);
            }
            //If authentication is required but the user is not logged in redirect to authentication
            if (loadedNodeSet.StartNode.RequireAuthentication && !processingContext.InputModel.SecurityModel.IsAuthenticated)
            {
                Utilities.ExtensionMethods.KraftResult(_HttpContext, HttpStatusCode.Unauthorized, null);
                return(false);
            }
            return(true);
        }
예제 #5
0
        public static void KraftResult(HttpContext httpContext, HttpStatusCode statusCode, string error = null)
        {
            httpContext.Response.StatusCode = (int)statusCode;
            switch (statusCode)
            {
            case HttpStatusCode.InternalServerError:
            {
                if (!string.IsNullOrEmpty(error))
                {
                    KraftLogger.LogCritical(error);
                }
                httpContext.Request.Headers.Clear();
                break;
            }

            case HttpStatusCode.Unauthorized:
            {
                //HttpRequest request = httpContext.Request;
                httpContext.Response.StatusCode = StatusCodes.Status401Unauthorized;
                //string redirectUrl = string.Concat(request.Scheme, "://", request.Host.ToUriComponent(), request.PathBase.ToUriComponent(), request.Path.ToUriComponent(), request.QueryString.ToUriComponent());
                //httpContext.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties() { RedirectUri = redirectUrl });
                break;
            }

            default:
            {
                if (!string.IsNullOrEmpty(error))
                {
                    KraftLogger.LogError(error);
                }
                httpContext.Request.Headers.Clear();
                break;
            }
            }
        }
예제 #6
0
        public void Execute(
            LoadedNodeSet loaderContextDefinition,
            IProcessingContext processingContext,
            IPluginAccessor <IDataLoaderPlugin> dataLoaderAccessor,
            IPluginAccessor <INodePlugin> pluginAccessor)
        {
            _CollectiveCall = true;
            //Check for null values
            GenericUtilities.CheckNullOrEmpty(loaderContextDefinition, true);
            GenericUtilities.CheckNullOrEmpty(processingContext, true);
            GenericUtilities.CheckNullOrEmpty(_TransactionScope.PluginServiceManager, true);

            try
            {
                if (processingContext.InputModel.LoaderType.HasFlag(ELoaderType.DataLoader))
                {
                    ExecuteNodeData(loaderContextDefinition, processingContext, dataLoaderAccessor, pluginAccessor);
                }

                if (processingContext.InputModel.LoaderType.HasFlag(ELoaderType.ViewLoader))
                {
                    ExecuteNodeView(loaderContextDefinition, processingContext);
                }

                //if (processingContext.InputModel.LoaderType.HasFlag(ELoaderType.LookupLoader))
                //{
                //    if (loaderContextDefinition.StartNode != null && loaderContextDefinition.StartNode.HasLookup())
                //    {
                //        using (KraftProfiler.Current.Step("Execution time loading lookups: "))
                //        {
                //            foreach (Lookup lookup in loaderContextDefinition.StartNode.Lookups)
                //            {
                //                ISystemPlugin systemPlugin = Utilities.GetPlugin<ISystemPlugin>(lookup.SystemPluginName, _TransactionScope.DependencyInjectionContainer, _KraftModuleConfigurationSettings, ELoaderType.LookupLoader);
                //                GenericUtilities.CheckNullOrEmpty(systemPlugin, true);
                //                IPluginsSynchronizeContextScoped synchronizeContextScoped = await _TransactionScope.GetSynchronizeContextScopedAsync(lookup.SystemPluginName, ELoaderType.LookupLoader, _KraftModuleConfigurationSettings, systemPlugin);
                //                GenericUtilities.CheckNullOrEmpty(synchronizeContextScoped, true);
                //                await systemPlugin.ExecuteAsync(loaderContextDefinition, processingContext, _TransactionScope.PluginServiceManager, synchronizeContextScoped, lookup);
                //            }
                //        }
                //    }
                //}

                _TransactionScope.CommitTransactions();
            }
            catch (Exception ex)
            {
                processingContext.ReturnModel.Status.IsSuccessful = false;
                processingContext.ReturnModel.Status.StatusResults.Add(new StatusResult {
                    StatusResultType = EStatusResult.StatusResultError, Message = ex.Message
                });
                _TransactionScope.RollbackTransactions();
                KraftLogger.LogError(ex.Message, ex);
            }
            finally
            {
                _CollectiveCall = false;
            }
        }
예제 #7
0
 public Task StopAsync(CancellationToken cancellationToken)
 {
     KraftLogger.LogInformation("CoreKraft-Background-Service is stopped.");
     foreach (Timer timer in _Timers)
     {
         timer?.Change(Timeout.Infinite, 0);
     }
     return(Task.CompletedTask);
 }
        private static Assembly AppDomain_OnAssemblyResolve(object sender, ResolveEventArgs args)
        {
            // Ignore missing resources
            if (args.Name.Contains(".resources"))
            {
                return(null);
            }

            // check for assemblies already loaded
            string[] nameParts = args.Name.Split(',');
            Assembly assembly  = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a =>
            {
                string[] parts = a.FullName.Split(',');
                return(parts[0].Equals(nameParts[0], StringComparison.InvariantCultureIgnoreCase));
            }
                                                                                        );

            if (assembly != null)
            {
                return(assembly);
            }

            // Try to load by filename - split out the filename of the full assembly name
            // and append the base path of the original assembly (ie. look in the same dir)
            string fileName = nameParts[0] + ".dll".ToLower();
            bool   found    = false;

            foreach (string dir in _KraftGlobalConfigurationSettings.GeneralSettings.ModulesRootFolders)
            {
                string asmFullName = Path.Combine(dir, "_PluginsReferences", fileName);

                try
                {
                    Assembly loadedAssembly = Assembly.LoadFile(asmFullName);
                    if (loadedAssembly != null)
                    {
                        found = true;
                        return(loadedAssembly);
                    }
                }
                catch
                {
                    //do nothing
                    continue;
                }
                finally
                {
                    if (!found)
                    {
                        KraftLogger.LogError($"Method: CurrentDomain_AssemblyResolve: The file {asmFullName} requested by {args.RequestingAssembly.FullName} was not found!");
                    }
                }
            }
            return(null);
        }
예제 #9
0
        private void FileWatcher_Changed(object sender, FileSystemEventArgs e)
        {
            FileSystemWatcher fileWatcher = sender as FileSystemWatcher;

            fileWatcher.EnableRaisingEvents = false;
            KraftLogger.LogError("FileWatcher_Changed PhysicalPath: " + PhysicalPath);
            KraftLogger.LogError("FileWatcher_Changed VirtualPath: " + VirtualPath);
            fileWatcher.Changed -= new FileSystemEventHandler(FileWatcher_Changed);
            fileWatcher.Dispose();
            _Parent?.RemoveFromCache();
        }
예제 #10
0
        public ActionResult SignIn()
        {
            // Instruct the OIDC client middleware to redirect the user agent to the identity provider.
            // Note: the authenticationType parameter must match the value configured in Startup.cs
            KraftLogger.LogDebug("ActionResult SignIn");
            AuthenticationProperties authenticationProperties = new AuthenticationProperties
            {
                RedirectUri = Url.Action("Index", "Home")
            };

            return(Challenge(authenticationProperties, OpenIdConnectDefaults.AuthenticationScheme));
        }
예제 #11
0
 public IActionResult CatchAll(string catchAll)
 {
     if (!string.IsNullOrEmpty(catchAll))
     {
         if (PATTERNSTATICFILES.Matches(catchAll).Count > 0)
         {
             KraftLogger.LogWarning($"Missing resource: {catchAll}");
             return(NoContent());
         }
     }
     return(View("Index", _KraftGlobalConfigurationSettings));
 }
예제 #12
0
        protected virtual void ExecuteQuery <Context>(Context execContext) where Context : class, IDataLoaderContext
        {
            bool trace = execContext.CurrentNode.Trace;

            string qry = GetQuery(execContext);

            if (qry != null)
            {
                try
                {
                    var runner = Compiler.Compile(qry);
                    if (runner.ErrorText != null)
                    {
                        KraftLogger.LogError($"{execContext.LocationInfo(PLUGIN_INTERNAL_NAME)}\n{runner.ErrorText}");
                        throw new Exception(runner.ErrorText);
                    }
                    using (var host = new ActionQueryHost <Context>(execContext)
                    {
                        { "HostInfo", HostInfo }
                    }) {
                        if (trace)
                        {
                            host.Trace = true;
                        }
                        try
                        {
                            var result = runner.ExecuteScalar(host, ActionQueryHost <Context> .HardLimit(execContext));
                        }
                        catch
                        {
                            if (trace)
                            {
                                var traceInfo = host.GetTraceInfo();
                                if (traceInfo != null)
                                {
                                    KraftLogger.LogError($"{execContext.LocationInfo(PLUGIN_INTERNAL_NAME)}\n");
                                    KraftLogger.LogError(traceInfo.ToString());
                                }
                            }
                            throw;
                        }
                    }
                }
                catch (Exception ex)
                {
                    KraftLogger.LogError(ActionQueryTrace.ExceptionToString(ex));
                    throw;
                }
            }
        }
예제 #13
0
        public Task StartAsync(CancellationToken cancellationToken)
        {
            KraftLogger.LogInformation("CoreKraft-Background-Service is starting.");
            using (IServiceScope scope = _ScopeFactory.CreateScope())
            {
                _KraftGlobalConfigurationSettings = scope.ServiceProvider.GetRequiredService <KraftGlobalConfigurationSettings>();
                _ServiceProvider = scope.ServiceProvider;
                int minutes = _KraftGlobalConfigurationSettings.GeneralSettings.HostingServiceSettings.Interval;
                if (minutes > 0)
                {
                    _Timer = new Timer(DoWork, _ScopeFactory, TimeSpan.Zero, TimeSpan.FromMinutes(minutes));
                }
            }

            return(Task.CompletedTask);
        }
예제 #14
0
 private void DoWork(object state)
 {
     lock (_Lock)
     {
         if (state is List <string> signals)
         {
             foreach (string signal in signals)
             {
                 Stopwatch stopWatch = Stopwatch.StartNew();
                 ExecuteSignals("null", signal);
                 KraftLogger.LogInformation($"Executing signal: {signal} for {stopWatch.ElapsedMilliseconds} ms");
             }
             KraftLogger.LogInformation("Batch of CoreKraft-Background-Services executed.");
         }
     }
 }
예제 #15
0
        public void ExecuteNodeView(
            LoadedNodeSet loaderContextDefinition,
            IProcessingContext processingContext)
        {
            if (!_CollectiveCall)
            {
                //Check for null values
                GenericUtilities.CheckNullOrEmpty(loaderContextDefinition, true);
                GenericUtilities.CheckNullOrEmpty(processingContext, true);
                GenericUtilities.CheckNullOrEmpty(_TransactionScope.PluginServiceManager, true);
            }

            try
            {
                using (KraftProfiler.Current.Step("Execution time loading views: "))
                {
                    if (!string.IsNullOrEmpty(processingContext.InputModel.BindingKey))
                    {
                        View view = loaderContextDefinition.StartNode.Views.Find(v => v.BindingKey.Equals(processingContext.InputModel.BindingKey, StringComparison.OrdinalIgnoreCase));
                        ExecuteNodeViewPrivate(loaderContextDefinition, processingContext, view);
                    }
                    else
                    {
                        foreach (View view in loaderContextDefinition.StartNode.Views)
                        {
                            ExecuteNodeViewPrivate(loaderContextDefinition, processingContext, view);
                        }
                    }
                }
                if (!_CollectiveCall)
                {
                    _TransactionScope.CommitTransactions();
                }
            }
            catch (Exception ex)
            {
                processingContext.ReturnModel.Status.IsSuccessful = false;
                processingContext.ReturnModel.Status.StatusResults.Add(new StatusResult {
                    StatusResultType = EStatusResult.StatusResultError, Message = ex.Message
                });
                if (!_CollectiveCall)
                {
                    _TransactionScope.RollbackTransactions();
                }
                KraftLogger.LogError(ex.Message, ex);
            }
        }
예제 #16
0
        public Task StartAsync(CancellationToken cancellationToken)
        {
            KraftLogger.LogInformation("CoreKraft-Background-Service is starting.");
            _ServiceProvider = _ScopeFactory.CreateScope().ServiceProvider;
            _KraftGlobalConfigurationSettings = _ServiceProvider.GetRequiredService <KraftGlobalConfigurationSettings>();

            foreach (HostingServiceSetting item in _KraftGlobalConfigurationSettings.GeneralSettings.HostingServiceSettings)
            {
                int minutes = item.IntervalInMinutes;
                if (minutes > 0)
                {
                    Timer t = new Timer(DoWork, item.Signals, TimeSpan.FromMinutes(minutes), TimeSpan.FromMinutes(minutes));
                    _Timers.Add(t);
                }
            }
            return(Task.CompletedTask);
        }
예제 #17
0
 public void ExecuteNodeData(
     LoadedNodeSet loaderContextDefinition,
     IProcessingContext processingContext,
     IPluginAccessor <IDataLoaderPlugin> dataLoaderAccessor,
     IPluginAccessor <INodePlugin> pluginAccessor)
 {
     if (!_CollectiveCall)
     {
         //Check for null values
         GenericUtilities.CheckNullOrEmpty(loaderContextDefinition, true);
         GenericUtilities.CheckNullOrEmpty(processingContext, true);
         GenericUtilities.CheckNullOrEmpty(_TransactionScope.PluginServiceManager, true);
     }
     try
     {
         if (processingContext.InputModel.LoaderType.HasFlag(ELoaderType.DataLoader))
         {
             using (KraftProfiler.Current.Step("Execution time loading data: "))
             {
                 if (loaderContextDefinition.StartNode != null && loaderContextDefinition.StartNode.HasValidDataSection(processingContext.InputModel.IsWriteOperation))
                 {
                     IDataIteratorPlugin dataIteratorPlugin = Utilities.GetPlugin <IDataIteratorPlugin>(_KraftModuleConfigurationSettings.NodeSetSettings.SourceLoaderMapping.NodesDataIterator.NodesDataIteratorConf.Name, _TransactionScope.DependencyInjectionContainer, _KraftModuleConfigurationSettings, ELoaderType.DataLoader, true);
                     GenericUtilities.CheckNullOrEmpty(dataIteratorPlugin, true);
                     IProcessingContext r = dataIteratorPlugin.ExecuteAsync(loaderContextDefinition, processingContext, _TransactionScope.PluginServiceManager, dataLoaderAccessor, pluginAccessor).Result;
                 }
             }
         }
         if (!_CollectiveCall)
         {
             _TransactionScope.CommitTransactions();
         }
     }
     catch (Exception ex)
     {
         processingContext.ReturnModel.Status.IsSuccessful = false;
         processingContext.ReturnModel.Status.StatusResults.Add(new StatusResult {
             StatusResultType = EStatusResult.StatusResultError, Message = ex.Message
         });
         if (!_CollectiveCall)
         {
             _TransactionScope.RollbackTransactions();
         }
         KraftLogger.LogError(ex.Message, ex);
     }
 }
예제 #18
0
 private static async void OnApplicationStopping()
 {
     if (string.IsNullOrEmpty(_BaseUrl))
     {
         KraftLogger.LogDebug("Method: OnApplicationStopping: BaseUrl is null.");
         return;
     }
     using (HttpClient client = new HttpClient())
     {
         using (HttpResponseMessage responseMessage = await client.GetAsync(_BaseUrl))
         {
             using (HttpContent content = responseMessage.Content)
             {
                 KraftLogger.LogDebug($"Method: OnApplicationStopping: Calling the application {_BaseUrl} to keepalive.");
                 await content.ReadAsStringAsync();
             }
         }
     }
 }
예제 #19
0
        private void DoWork(object state)
        {
            IServiceScopeFactory scopeFactory = state as IServiceScopeFactory;

            if (scopeFactory != null)
            {
                using (IServiceScope scope = scopeFactory.CreateScope())
                {
                    _KraftGlobalConfigurationSettings = scope.ServiceProvider.GetRequiredService <KraftGlobalConfigurationSettings>();
                    _ServiceProvider = scope.ServiceProvider;
                    foreach (string signal in _KraftGlobalConfigurationSettings.GeneralSettings.HostingServiceSettings.Signals)
                    {
                        Stopwatch stopWatch = Stopwatch.StartNew();
                        ExecuteSignals("null", signal);
                        KraftLogger.LogInformation($"Executing signal: {signal} for {stopWatch.ElapsedMilliseconds} ms");
                    }
                }
            }
            KraftLogger.LogInformation("CoreKraft-Background-Service executed.");
        }
예제 #20
0
        protected override List <Dictionary <string, object> > Read(IDataLoaderReadContext execContext)
        {
            string baseUrl = execContext.DataLoaderContextScoped.CustomSettings["BaseUrl"];
            ParameterResolverValue endpoint = execContext.Evaluate("endpoint");
            ParameterResolverValue method   = execContext.Evaluate("method");
            var result = new List <Dictionary <string, object> >();

            if (!(endpoint.Value is string))
            {
                KraftLogger.LogError("HttpServiceImp endpoint parameter value must be string");
                throw new Exception("endpoint value must be string");
            }
            string url = baseUrl + endpoint.Value;
            var    obj = this.GetHttpContent(url);

            result.Add(new Dictionary <string, object>()
            {
                { "key", obj }
            });
            return(result);
        }
예제 #21
0
        private Dictionary <string, object> UpdateParameters(InputModelParameters parameters)
        {
            //Mix all parameter's collections
            Dictionary <string, object> result = new Dictionary <string, object>();

            foreach (KeyValuePair <string, object> headerItem in parameters.HeaderCollection ?? new Dictionary <string, object>())
            {
                if (!result.ContainsKey(headerItem.Key))
                {
                    result.Add(headerItem.Key, headerItem.Value);
                }
                else
                {
                    KraftLogger.LogWarning($"Parameter from header-collection {headerItem.Key} with value {headerItem.Value} already exist in the collection and cannot be added.");
                }
            }
            foreach (KeyValuePair <string, object> formItem in parameters.FormCollection ?? new Dictionary <string, object>())
            {
                if (!result.ContainsKey(formItem.Key))
                {
                    result.Add(formItem.Key, formItem.Value);
                }
                else
                {
                    KraftLogger.LogWarning($"Parameter from form-body {formItem.Key} with value {formItem.Value} already exist in the collection and cannot be added.");
                }
            }
            foreach (KeyValuePair <string, object> queryItem in parameters.QueryCollection ?? new Dictionary <string, object>())
            {
                if (!result.ContainsKey(queryItem.Key))
                {
                    result.Add(queryItem.Key, queryItem.Value);
                }
                else
                {
                    KraftLogger.LogWarning($"Parameter from query-string {queryItem.Key} with value {queryItem.Value} already exist in the collection and cannot be added.");
                }
            }
            return(result);
        }
예제 #22
0
        private async Task <string> GetHttpContent(string url)
        {
            KraftLogger.LogTrace(url);
            try
            {
                using (var http = new HttpClient())
                {
                    var httpResponse = await http.GetAsync(url);

                    var httpContent = await httpResponse.Content.ReadAsStringAsync();

                    if (httpResponse.StatusCode.ToString().StartsWith("5") || httpResponse.StatusCode.ToString().StartsWith("4"))
                    {
                        KraftLogger.LogWarning("Recieved status code:" + httpResponse.StatusCode, httpResponse);
                    }
                    return(httpContent);
                }
            }
            catch (Exception ex)
            {
                KraftLogger.LogError(ex, "Method: GetHttpContent");
                throw;
            }
        }
예제 #23
0
        /// <summary>
        /// Unlike read write is called exactly once per each row and not called at all if the row's state does not require actual writing.
        /// </summary>
        /// <param name="execContext"></param>
        /// <param name="configuration"></param>
        /// <returns></returns>
        protected override object Write(IDataLoaderWriteContext execContext)
        { //IDataLoaderContext execContext, Configuration configuration) {
            string sqlQuery = null;

            try
            {
                Node node = execContext.CurrentNode;

                // Statement is already selected for the requested operation (While fetching the Configuration
                if (!string.IsNullOrWhiteSpace(Action(execContext)?.Query))
                {
                    // Check if it is valid
                    if (!(execContext.OwnContextScoped is IADOTransactionScope scopedContext))
                    {
                        throw new NullReferenceException("Scoped synchronization and transaction context is not available.");
                    }
                    // Settings should be passed to the scopedContext in the ExternalServiceImp
                    DbConnection  conn  = scopedContext.Connection;
                    DbTransaction trans = scopedContext.StartADOTransaction();

                    using (DbCommand cmd = conn.CreateCommand())
                    {
                        cmd.Transaction = trans;
                        cmd.Parameters.Clear();
                        sqlQuery = ProcessCommand(cmd, Action(execContext).Query, execContext);
                        using (DbDataReader reader = cmd.ExecuteReader())
                        {
                            do
                            {
                                while (reader.Read())
                                {
                                    for (int i = 0; i < reader.FieldCount; i++)
                                    {
                                        string fname = reader.GetName(i);
                                        if (fname == null)
                                        {
                                            continue;
                                        }
                                        fname = fname.ToLower().Trim();
                                        // fname = fname.Trim(); // TODO: We have to rethink this - lowercasing seems more inconvenience than a viable protection against human mistakes.
                                        if (fname.Length == 0)
                                        {
                                            throw new Exception("Empty field name in a store context in nodedesfinition: " + node.NodeSet.Name);
                                        }
                                        object v = reader.GetValue(i);
                                        execContext.Row[fname] = (v is DBNull) ? null : v;
                                    }
                                }
                                // This is important, we have been doing this for a single result before, but it is better to assume more than one, so that
                                // update of the data being written can be done more freely - using more than one select statement after writing. This is
                                // probably rare, but having the opportunity is better than not having it.
                            } while (reader.NextResult());
                            if (execContext.Operation != OPERATION_DELETE)
                            {
                                execContext.DataState.SetUnchanged(execContext.Row);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                if (!string.IsNullOrEmpty(sqlQuery))
                {
                    KraftLogger.LogError($"Write(IDataLoaderWriteContext execContext) >> SQL: {Environment.NewLine}{sqlQuery}", ex, execContext);
                }
                throw;
            }
            return(null); // if this is not null it should add new results in the data
            // TODO: Consider if this is possible and useful (for some future version - not urgent).
        }
        internal DbConnection GetConnection()
        {
            if (_DbConnection == null)
            {
                //Create connection
                string moduleRoot = System.IO.Path.Combine(KraftGlobalConfigurationSettings.GeneralSettings.ModulesRootFolder(ProcessingContext.InputModel.Module), ProcessingContext.InputModel.Module);
                // Support for @moduleroot@ variable replacement for connection strings that refer to file(s)
                string connectionString = (CustomSettings != null && CustomSettings.ContainsKey("ConnectionString"))
                         ? CustomSettings["ConnectionString"].Replace("@moduleroot@", moduleRoot)
                         : null;

                if (string.IsNullOrEmpty(connectionString))
                {
                    throw new NullReferenceException("The Connection String must not be null or empty.");
                }

                // MatchCollection matches = _DynamicParameterRegEx.Matches(connectionString);
                connectionString = _DynamicParameterRegEx.Replace(connectionString, m => {
                    string varname = m.Groups[1].Value;
                    var val        = LoaderContext.Evaluate(varname);
                    if (val.ValueType == EResolverValueType.Invalid)
                    {
                        KraftLogger.LogError($"Expected parameter in connection string: {m.Groups[1].Value} was not resolved! Check that parameter's expression. It is recommended to not define it on node basis, but only in a nodeset root!");
                        // TODO: What shall we return on error? This is temporary decision - there should be something better or just excepton.
                        return(m.Value);
                    }
                    if (!string.IsNullOrWhiteSpace(val.Value + ""))
                    {
                        return(val.Value.ToString());
                    }
                    else
                    {
                        KraftLogger.LogError($"Expected parameter in connection string: {m.Groups[1].Value} was not found or cannot be resolved!");
                        return(m.Value);
                    }
                });

                /*if (matches.Count > 0) {
                 *  for (int i = 0; i < matches.Count; i++) {
                 *
                 *      string parameter = matches[i].Groups["OnlyParameter"].ToString();
                 *
                 *      if (ProcessingContext.InputModel.Data.ContainsKey(parameter)) {
                 *
                 *          connectionString = connectionString.Replace(matches[i].ToString(), ProcessingContext.InputModel.Data[parameter].ToString());
                 *      }
                 *      else if (ProcessingContext.InputModel.Client.ContainsKey(parameter)) {
                 *
                 *          connectionString = connectionString.Replace(matches[i].ToString(), ProcessingContext.InputModel.Client[parameter].ToString());
                 *      }
                 *      else {
                 *
                 *          KraftLogger.LogError($"Expected parameter in connection string: {matches[i]} was not found and the connection string remains invalid! Please consider the casing!");
                 *          //connectionString = connectionString.Replace(matches[i].ToString(), string.Empty);
                 *      }
                 *  }
                 * }*/

                _DbConnection = KraftProfiler.Current.ProfiledDbConnection(new XConnection());
                _DbConnection.ConnectionString = connectionString;
            }
            if (_DbConnection.State != ConnectionState.Open)
            {
                _DbConnection.Open();
            }
            return(_DbConnection);
        }
예제 #25
0
        /// <summary>
        /// Reads uploaded file in predefined directory,
        /// sets the response builder of the return model of the processing context to BinaryResponseBuilder.
        /// </summary>
        /// <param name="execContext">Execution context</param>
        /// <returns>null</returns>
        protected override List <Dictionary <string, object> > Read(IDataLoaderReadContext execContext)
        {
            ReadCustomSettings settings = new ReadCustomSettings(execContext, execContext.PluginServiceManager.GetService <KraftGlobalConfigurationSettings>(typeof(KraftGlobalConfigurationSettings)));

            string filePreviewName = "FILE_preview.svg";
            string previewName     = "preview";
            string file            = execContext.Evaluate("path").Value.ToString();
            string configuredDir   = settings.UploadFolder;
            string defaultDir      = settings.DefaultFolder;

            if (File.Exists(Path.Combine(configuredDir, file)))
            {
                ParameterResolverValue preview = execContext.Evaluate(previewName);

                if (preview.Value != null)
                {
                    string previewValue = preview.Value.ToString();

                    if (previewValue == "1")
                    {
                        string previewFileName = GeneratePreviewName(file);

                        if (File.Exists(Path.Combine(configuredDir, previewFileName)))
                        {
                            file = previewFileName;
                        }
                        else
                        {
                            string extension = Path.GetExtension(file);

                            if (!string.IsNullOrWhiteSpace(extension))
                            {
                                previewFileName = extension.Replace(".", string.Empty).ToUpper() + "_preview.svg";

                                if (File.Exists(Path.Combine(defaultDir, previewFileName)))
                                {
                                    file          = previewFileName;
                                    configuredDir = defaultDir;
                                }
                                else
                                {
                                    file          = filePreviewName;
                                    configuredDir = defaultDir;
                                }
                            }
                            else
                            {
                                file          = filePreviewName;
                                configuredDir = defaultDir;
                            }
                        }
                    }
                }
            }
            else
            {
                if (File.Exists(Path.Combine(defaultDir, settings.FileNotFoundIcon)))
                {
                    configuredDir = defaultDir;
                    file          = settings.FileNotFoundIcon;
                }
                else
                {
                    KraftLogger.LogError($"FileUploadImp-Read: File with name {file} was not found.");
                }
            }

            file = Path.Combine(configuredDir, file);
            string contentType;

            new FileExtensionContentTypeProvider().TryGetContentType(file, out contentType);

            execContext.ProcessingContext.ReturnModel.BinaryData = new PostedFile(contentType, 0, "currentlyNotSet", file, path =>
            {
                return(File.Open(path as string, FileMode.Open));
            }, file);

            execContext.ProcessingContext.ReturnModel.ResponseBuilder = new BinaryResponseBuilder(new ProcessingContextCollection(new List <IProcessingContext> {
                execContext.ProcessingContext
            }));

            return(null);
        }
예제 #26
0
        /*  Considerations:
         *      We have to read the configuration in a single turn and consume it from the internal configuration container
         *      in order to avoid direct hard coded dependency on the system configuration structure - most notably dependency on its
         *      structure and interpreatation.
         *  Solution:
         *      We have a nested class in which the configuration values used by this loader are collected (sometimes with some preprocessing)
         *  Lifecycle:
         *      The configuration (part of it at least) has a lifecycle equal to the node execution which is shorter than the life of the dataloader (at least potentially),
         *      so the configuration has to be reread on each node executio and thus is not persisted in the loader's instance, but passed to the main overridable methods.
         *
         */
        //protected class Configuration {
        //    public string Statement { get; set; }

        //}
        /// <summary>
        ///
        /// </summary>
        /// <param name="execContext"></param>
        /// <returns></returns>
        //protected virtual Configuration ReadConfiguration(IDataLoaderContext execContext) {
        //    var cfg = new Configuration();

        //    if (execContext.Action == ACTION_READ) {
        //        cfg.Statement = execContext.CurrentNode.Read.Select.HasStatement?execContext.CurrentNode.Read.Select.Query:null;
        //    } else if (execContext.Action == ACTION_WRITE) {
        //        switch (execContext.Operation) {
        //            case OPERATION_INSERT:
        //                if (execContext.CurrentNode.Write.Insert.HasStatement) {
        //                    cfg.Statement = execContext.CurrentNode.Write.Insert.Query;
        //                }
        //                break;
        //            case OPERATION_UPDATE:
        //                if (execContext.CurrentNode.Write.Update.HasStatement) {
        //                    cfg.Statement = execContext.CurrentNode.Write.Update.Query;
        //                }
        //                break;
        //            case OPERATION_DELETE:
        //                if (execContext.CurrentNode.Write.Delete.HasStatement) {
        //                    cfg.Statement = execContext.CurrentNode.Write.Delete.Query;
        //                }
        //                break;
        //        }
        //    }
        //    return cfg; ///////////////////////////////
        //}
        #endregion


        //public async Task<object> ExecuteAsync(IDataLoaderContext execContext) {
        //    // The procedure is different enough to deserve splitting by read/write
        //    Configuration cfg = ReadConfiguration(execContext);
        //    object result;
        //    if (execContext.Action == ACTION_WRITE) {
        //        result = ExecuteWrite(execContext, cfg);
        //    } else if (execContext.Action == ACTION_READ) {
        //        result = ExecuteRead(execContext, cfg);
        //    } else {
        //        // unknown action
        //        throw new Exception("Unknown action (only read/write) are supported");
        //    }
        //    return await Task.FromResult(result);
        //}

        protected override List <Dictionary <string, object> > Read(IDataLoaderReadContext execContext)
        {
            // TODO: What to return if there is no statement:
            //  I think we should have two policies - empty object which enables children extraction if logically possible and
            //  null wich stops the processing here.
            List <Dictionary <string, object> > results = new List <Dictionary <string, object> >();
            string sqlQuery = null;

            try
            {
                Node node = execContext.CurrentNode;

                if (!string.IsNullOrWhiteSpace(Action(execContext).Query))
                {
                    // Scope context for the same loader
                    // Check it is valid
                    if (!(execContext.OwnContextScoped is IADOTransactionScope scopedContext))
                    {
                        throw new NullReferenceException("Scoped synchronization and transaction context is not available.");
                    }
                    // Configuration settings Should be set to the scoped context during its creation/obtainment - see ExternalServiceImp

                    // No tranaction in read mode - lets not forget that closing the transaction also closes the connection - so the ;ifecycle control will do this using the transaction based notation
                    // from ITransactionScope
                    DbConnection conn = scopedContext.Connection;
                    using (DbCommand cmd = conn.CreateCommand())
                    {
                        cmd.Transaction = scopedContext.CurrentTransaction; // if we decide to open transaction in future this will guarantee we only have to open it and will take effect throughout the code.
                        cmd.Parameters.Clear();
                        // This will set the resulting command text if everything is Ok.
                        // The processing will make replacements in the SQL and bind parameters by requesting them from the resolver expressions configured on this node.
                        // TODO: Some try...catching is necessary.
                        sqlQuery = ProcessCommand(cmd, Action(execContext).Query, execContext);
                        using (DbDataReader reader = cmd.ExecuteReader())
                        {
                            do
                            {
                                if (reader.HasRows)
                                {
                                    // Read a result (many may be contained) row by row
                                    while (reader.Read())
                                    {
                                        Dictionary <string, object> currentResult = new Dictionary <string, object>(reader.FieldCount);
                                        for (int i = 0; i < reader.FieldCount; i++)
                                        {
                                            string fldname = reader.GetName(i);
                                            if (fldname == null)
                                            {
                                                continue;
                                            }
                                            // TODO: May be configure that or at least create a compile time definition
                                            fldname = fldname.ToLower().Trim(); // TODO: lowercase
                                                                                //fldname = fldname.Trim();
                                            if (fldname.Length == 0)
                                            {
                                                throw new Exception($"Empty name when reading the output of a query. The field index is {i}. The query is: {cmd.CommandText}");
                                            }
                                            if (currentResult.ContainsKey(fldname))
                                            {
                                                throw new Exception($"Duplicated field name in the output of a query. The field is:{fldname}, the query is: {cmd.CommandText}");
                                            }
                                            object v = reader.GetValue(i);
                                            currentResult.Add(fldname, (v is DBNull) ? null : v);
                                        }
                                        // Mark the records unchanged, because they are just picked up from the data store (rdbms in this case).
                                        execContext.DataState.SetUnchanged(currentResult);
                                        results.Add(currentResult);
                                        if (!node.IsList)
                                        {
                                            break;
                                        }
                                    }
                                }
                            } while (reader.NextResult());
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                if (!string.IsNullOrEmpty(sqlQuery))
                {
                    KraftLogger.LogError($"Read(IDataLoaderReadContext execContext) >> SQL: {Environment.NewLine}{sqlQuery}", ex, execContext);
                }
                throw;
            }
            return(results); // TODO: Decide what behavior we want with empty statements. I for one prefer null result, effectively stopping the operation.
        }
        public static IApplicationBuilder UseBindKraft(this IApplicationBuilder app, IHostingEnvironment env)
        {
            //AntiforgeryService
            //app.Use(next => context =>
            //{
            //    if (string.Equals(context.Request.Path.Value, "/", StringComparison.OrdinalIgnoreCase))
            //    {
            //        AntiforgeryTokenSet tokens = app.ApplicationServices.GetService<IAntiforgery>().GetAndStoreTokens(context);
            //        context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions() { HttpOnly = false });
            //    }
            //    return next(context);
            //});

            _KraftGlobalConfigurationSettings.EnvironmentSettings = new KraftEnvironmentSettings(env.ApplicationName, env.ContentRootPath, env.EnvironmentName, env.WebRootPath);
            try
            {
                ILoggerFactory     loggerFactory      = app.ApplicationServices.GetService <ILoggerFactory>();
                DiagnosticListener diagnosticListener = app.ApplicationServices.GetService <DiagnosticListener>();
                //First statement to register Error handling !!!Keep at the top!!!
                app.UseMiddleware <KraftExceptionHandlerMiddleware>(loggerFactory, new ExceptionHandlerOptions(), diagnosticListener);
                AppDomain.CurrentDomain.UnhandledException += AppDomain_OnUnhandledException;
                AppDomain.CurrentDomain.AssemblyResolve    += AppDomain_OnAssemblyResolve;
                if (_KraftGlobalConfigurationSettings.GeneralSettings.RedirectToWww)
                {
                    RewriteOptions rewrite = new RewriteOptions();
                    rewrite.AddRedirectToWwwPermanent();
                    app.UseRewriter(rewrite);
                }
                if (_KraftGlobalConfigurationSettings.GeneralSettings.RedirectToHttps)
                {
                    app.UseForwardedHeaders();
                    app.UseHsts();
                    app.UseHttpsRedirection();
                }
                ExtensionMethods.Init(app, _Logger);
                app.UseBindKraftLogger(env, loggerFactory, ERRORURLSEGMENT);
                app.UseBindKraftProfiler(env, loggerFactory, _MemoryCache);
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }

                _Builder = app;

                BundleCollection bundleCollection = app.UseBundling(env, loggerFactory.CreateLogger("Bundling"), _KraftGlobalConfigurationSettings.GeneralSettings.KraftUrlCssJsSegment, _KraftGlobalConfigurationSettings.GeneralSettings.EnableOptimization);
                bundleCollection.EnableInstrumentations = env.IsDevelopment(); //Logging enabled

                #region Initial module registration
                foreach (string dir in _KraftGlobalConfigurationSettings.GeneralSettings.ModulesRootFolders)
                {
                    if (!Directory.Exists(dir))
                    {
                        throw new Exception($"No \"{dir}\" directory found! The CoreKraft initialization cannot continue.");
                    }
                }
                string kraftUrlSegment = _KraftGlobalConfigurationSettings.GeneralSettings.KraftUrlSegment;

                try
                {
                    KraftModuleCollection       modulesCollection   = app.ApplicationServices.GetService <KraftModuleCollection>();
                    Dictionary <string, string> moduleKey2Path      = new Dictionary <string, string>();
                    IApplicationLifetime        applicationLifetime = app.ApplicationServices.GetRequiredService <IApplicationLifetime>();
                    lock (_SyncRoot)
                    {
                        foreach (string dir in _KraftGlobalConfigurationSettings.GeneralSettings.ModulesRootFolders)
                        {
                            string[] moduleDirectories = Directory.GetDirectories(dir);
                            foreach (string subdirectory in moduleDirectories)
                            {
                                DirectoryInfo moduleDirectory = new DirectoryInfo(subdirectory);
                                if (moduleDirectory.Name != null && moduleDirectory.Name.Equals("_PluginsReferences", StringComparison.InvariantCultureIgnoreCase))
                                {
                                    continue;
                                }
                                ICachingService cachingService = app.ApplicationServices.GetService <ICachingService>();
                                KraftModule     kraftModule    = modulesCollection.GetModule(moduleDirectory.Name);
                                if (kraftModule != null)
                                {
                                    continue;
                                }
                                kraftModule = modulesCollection.RegisterModule(dir, moduleDirectory.Name, cachingService);
                                if (kraftModule == null || !kraftModule.IsInitialized)
                                {
                                    _Logger.LogInformation($"Module not created for directory \"{moduleDirectory.Name}\" because of missing configuration files.");
                                    continue;
                                }
                                KraftStaticFiles.RegisterStaticFiles(app, moduleDirectory.FullName, kraftUrlSegment, _KraftGlobalConfigurationSettings.GeneralSettings.KraftUrlResourceSegment, _KraftGlobalConfigurationSettings.GeneralSettings.KraftUrlModuleImages);
                                KraftStaticFiles.RegisterStaticFiles(app, moduleDirectory.FullName, kraftUrlSegment, _KraftGlobalConfigurationSettings.GeneralSettings.KraftUrlResourceSegment, _KraftGlobalConfigurationSettings.GeneralSettings.KraftUrlModulePublic);
                                moduleKey2Path.Add(kraftModule.Key.ToLower(), dir);
                                //The application will restart when some files changed in the modules directory and subdirectories but only in RELEASE
                                //Check if module is initialized Robert
                                if (kraftModule.IsInitialized && !env.IsDevelopment())
                                {
                                    string moduleFullPath = Path.Combine(dir, kraftModule.Key);
                                    AttachModulesWatcher(moduleFullPath, false, applicationLifetime);
                                    string path2Data = Path.Combine(moduleFullPath, "Data");
                                    if (!HasWritePermissionOnDir(new DirectoryInfo(path2Data), true))
                                    {
                                        throw new SecurityException($"Write access to folder {path2Data} is required!");
                                    }
                                    path2Data = Path.Combine(moduleFullPath, "Images");
                                    if (!HasWritePermissionOnDir(new DirectoryInfo(path2Data), true))
                                    {
                                        throw new SecurityException($"Write access to folder {path2Data} is required!");
                                    }
                                    AttachModulesWatcher(Path.Combine(moduleFullPath, "Css"), true, applicationLifetime);
                                    AttachModulesWatcher(Path.Combine(moduleFullPath, "Documentation"), true, applicationLifetime);
                                    AttachModulesWatcher(Path.Combine(moduleFullPath, "Localization"), true, applicationLifetime);
                                    AttachModulesWatcher(Path.Combine(moduleFullPath, "NodeSets"), true, applicationLifetime);
                                    AttachModulesWatcher(Path.Combine(moduleFullPath, "Scripts"), true, applicationLifetime);
                                    AttachModulesWatcher(Path.Combine(moduleFullPath, "Templates"), true, applicationLifetime);
                                    AttachModulesWatcher(Path.Combine(moduleFullPath, "Views"), true, applicationLifetime);
                                }
                            }
                        }
                        //try to construct all modules
                        modulesCollection.ResolveModuleDependencies();
                        _KraftGlobalConfigurationSettings.GeneralSettings.ModuleKey2Path = moduleKey2Path;
                    }
                    if (!env.IsDevelopment())
                    {
                        _Configuration.GetReloadToken().RegisterChangeCallback(_ =>
                        {
                            RestartReason restartReason = new RestartReason();
                            restartReason.Reason        = "Configuration Changed";
                            restartReason.Description   = $"'appsettings.Production.json' has been altered";
                            AppDomain.CurrentDomain.UnhandledException -= AppDomain_OnUnhandledException;
                            AppDomain.CurrentDomain.AssemblyResolve    -= AppDomain_OnAssemblyResolve;
                            RestartApplication(applicationLifetime, restartReason);
                        }, null);
                    }
                }
                catch (Exception boom)
                {
                    KraftLogger.LogError(boom);
                    throw new Exception($"CoreKrafts module construction failed! {boom.Message}");
                }
                #endregion Initial module registration
                //Configure the CoreKraft routing
                RouteHandler kraftRoutesHandler = new RouteHandler(KraftMiddleware.ExecutionDelegate(app, _KraftGlobalConfigurationSettings));
                app.UseRouter(KraftRouteBuilder.MakeRouter(app, kraftRoutesHandler, kraftUrlSegment));
                app.UseSession();
                if (_KraftGlobalConfigurationSettings.GeneralSettings.AuthorizationSection.RequireAuthorization)
                {
                    app.UseAuthentication();
                }
                //KraftKeepAlive.RegisterKeepAliveAsync(builder);
                //Configure eventually SignalR
                try
                {
                    if (_KraftGlobalConfigurationSettings.GeneralSettings.SignalRSettings.UseSignalR)
                    {
                        app.UseSignalR(routes =>
                        {
                            MethodInfo mapHub  = typeof(HubRouteBuilder).GetMethod("MapHub", new[] { typeof(PathString) });
                            MethodInfo generic = mapHub.MakeGenericMethod(Type.GetType(_KraftGlobalConfigurationSettings.GeneralSettings.SignalRSettings.HubImplementationAsString));
                            generic.Invoke(routes, new object[] { new PathString(_KraftGlobalConfigurationSettings.GeneralSettings.SignalRSettings.HubRoute) });
                        });
                    }
                }
                catch (Exception e)
                {
                    KraftLogger.LogError("Register signalR middleware. Exception: " + e);
                }
                //Signals
                SignalStartup signalStartup = new SignalStartup(app.ApplicationServices, _KraftGlobalConfigurationSettings);
                signalStartup.ExecuteSignalsOnStartup();
                //End Signals
            }
            catch (Exception ex)
            {
                KraftLogger.LogError("Method: UseBindKraft ", ex);
                KraftExceptionHandlerMiddleware.Exceptions[KraftExceptionHandlerMiddleware.EXCEPTIONSONCONFIGURE].Add(ex);
            }

            //This is the last statement
            KraftExceptionHandlerMiddleware.HandleErrorAction(app);
            return(app);
        }
 private static void AppDomain_OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
 {
     KraftLogger.LogCritical("AppDomain_OnUnhandledException: ", e.ExceptionObject);
 }
        public static IServiceProvider UseBindKraft(this IServiceCollection services, IConfiguration configuration)
        {
            try
            {
                services.AddDistributedMemoryCache();
                services.UseBindKraftLogger();
                _KraftGlobalConfigurationSettings = new KraftGlobalConfigurationSettings();
                configuration.GetSection("KraftGlobalConfigurationSettings").Bind(_KraftGlobalConfigurationSettings);
                _Configuration = configuration;

                services.AddSingleton(_KraftGlobalConfigurationSettings);

                if (_KraftGlobalConfigurationSettings.GeneralSettings.RedirectToHttps)
                {
                    services.Configure <ForwardedHeadersOptions>(options =>
                    {
                        options.KnownNetworks.Clear(); //its loopback by default
                        options.KnownProxies.Clear();
                        options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
                    });
                    services.AddHsts(options =>
                    {
                        options.Preload           = true;
                        options.IncludeSubDomains = true;
                        options.MaxAge            = TimeSpan.FromDays(365);
                    });
                    services.AddHttpsRedirection(options =>
                    {
                        options.RedirectStatusCode = StatusCodes.Status307TemporaryRedirect;
                        options.HttpsPort          = 443;
                    });
                }

                if (_KraftGlobalConfigurationSettings.GeneralSettings.SignalRSettings.UseSignalR)
                {
                    services.AddSignalR(hubOptions =>
                    {
                        hubOptions.KeepAliveInterval    = TimeSpan.FromDays(1);
                        hubOptions.EnableDetailedErrors = true;
                    });
                }

                //GRACE DEPENDENCY INJECTION CONTAINER
                DependencyInjectionContainer dependencyInjectionContainer = new DependencyInjectionContainer();
                services.AddSingleton(dependencyInjectionContainer);
                services.AddRouting(options => options.LowercaseUrls = true);

                services.AddResponseCaching();
                services.AddMemoryCache();
                services.AddSession();
                services.UseBindKraftProfiler();
                IServiceProvider    serviceProvider = services.BuildServiceProvider();
                IHostingEnvironment env             = serviceProvider.GetRequiredService <IHostingEnvironment>();
                ILoggerFactory      loggerFactory   = serviceProvider.GetRequiredService <ILoggerFactory>();
                _Logger = loggerFactory.CreateLogger <KraftMiddleware>();

                services.AddLogging(loggingBuilder =>
                {
                    loggingBuilder.ClearProviders();
                    if (env.IsDevelopment())
                    {
                        loggingBuilder.SetMinimumLevel(LogLevel.Error);
                        loggingBuilder.AddConsole();
                        loggingBuilder.AddDebug();
                    }
                });

                //memory cache
                _MemoryCache = serviceProvider.GetRequiredService <IMemoryCache>();

                /*if (_HostingEnvironment.IsDevelopment())
                 * {
                 *  config.CacheProfiles.Add("Default", new CacheProfile() { Location = ResponseCacheLocation.None, Duration = 0 });
                 * }
                 * else
                 * {
                 *  config.CacheProfiles.Add("Default", new CacheProfile() { Location = ResponseCacheLocation.Any, Duration = 60 });
                 * }*/

                ICachingService cachingService = new MemoryCachingService(_MemoryCache);
                services.AddSingleton(cachingService);

                KraftModuleCollection kraftModuleCollection = new KraftModuleCollection(_KraftGlobalConfigurationSettings, dependencyInjectionContainer, _Logger);
                services.AddSingleton(kraftModuleCollection);

                #region Global Configuration Settings

                _KraftGlobalConfigurationSettings.GeneralSettings.ReplaceMacrosWithPaths(env.ContentRootPath, env.WebRootPath);

                #endregion //Global Configuration Settings

                //INodeSet service
                services.AddSingleton(typeof(INodeSetService), new NodeSetService(_KraftGlobalConfigurationSettings, cachingService));

                ILogger logger = loggerFactory.CreateLogger(env.EnvironmentName);
                services.AddSingleton(typeof(ILogger), logger);

                services.AddSingleton(services);
                #region Authorization
                if (_KraftGlobalConfigurationSettings.GeneralSettings.AuthorizationSection.RequireAuthorization)
                {
                    services.AddAuthentication(options =>
                    {
                        options.DefaultScheme          = CookieAuthenticationDefaults.AuthenticationScheme;
                        options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
                    })

                    .AddCookie(options =>
                    {
                        options.LoginPath = new PathString("/account/signin");
                    })

                    .AddOpenIdConnect(options =>
                    {
                        // Note: these settings must match the application details
                        // inserted in the database at the server level.
                        options.ClientId                      = _KraftGlobalConfigurationSettings.GeneralSettings.ClientId;
                        options.ClientSecret                  = _KraftGlobalConfigurationSettings.GeneralSettings.ClientSecret;
                        options.RequireHttpsMetadata          = _KraftGlobalConfigurationSettings.GeneralSettings.RedirectToHttps;
                        options.Authority                     = _KraftGlobalConfigurationSettings.GeneralSettings.Authority;
                        options.GetClaimsFromUserInfoEndpoint = true;
                        options.SaveTokens                    = true;

                        // Use the authorization code flow.
                        options.ResponseType         = OpenIdConnectResponseType.Code;
                        options.AuthenticationMethod = OpenIdConnectRedirectBehavior.RedirectGet;

                        options.Scope.Add("email");
                        options.Scope.Add("roles");
                        options.Scope.Add("firstname");
                        options.Scope.Add("lastname");
                        options.Scope.Add("offline_access");

                        options.Events = new OpenIdConnectEvents
                        {
                            OnRedirectToIdentityProvider = context =>
                            {
                                if (context.Request.Query.ContainsKey("cr"))
                                {
                                    context.ProtocolMessage.SetParameter("cr", context.Request.Query["cr"]);
                                }
                                return(Task.CompletedTask);
                            },
                            OnRemoteFailure = context =>
                            {
                                KraftLogger.LogError(context.Failure);
                                HttpRequest request = context.Request;
                                string redirectUrl  = string.Concat(request.Scheme, "://", request.Host.ToUriComponent(), request.PathBase.ToUriComponent());
                                context.Response.Redirect(redirectUrl);
                                // + "/" + ERRORURLSEGMENT + "?message=" + UrlEncoder.Default.Encode(context.Failure.Message));
                                context.HandleResponse();
                                return(Task.CompletedTask);
                            },
                            OnAuthenticationFailed = context =>
                            {
                                HttpRequest request = context.Request;
                                context.ProtocolMessage.RedirectUri = context.ProtocolMessage.RedirectUri.Replace("http://", "https://");
                                context.HandleResponse();
                                return(Task.CompletedTask);
                            }
                        };
                        options.SecurityTokenValidator = new JwtSecurityTokenHandler
                        {
                            // Disable the built-in JWT claims mapping feature.
                            InboundClaimTypeMap = new Dictionary <string, string>()
                        };
                        options.TokenValidationParameters.NameClaimType = "name";
                        options.TokenValidationParameters.RoleClaimType = "role";
                    });
                }
                else
                {
                    services.AddAuthorization(x =>
                    {
                        x.DefaultPolicy = new AuthorizationPolicyBuilder()
                                          .RequireAssertion(_ => true)
                                          .Build();
                    });
                }
                #endregion Authorization
                services.UseBundling();
                //services.AddDataProtection().PersistKeysToFileSystem(new DirectoryInfo(Path.Combine(_KraftGlobalConfigurationSettings.GeneralSettings.ModulesRootFolder, "BindKraft", "Data")));

                //Signals
                services.AddHostedService <SignalService>();
                //End Signals
            }
            catch (Exception ex)
            {
                KraftLogger.LogError("Method: ConfigureServices ", ex);
                KraftExceptionHandlerMiddleware.Exceptions[KraftExceptionHandlerMiddleware.EXCEPTIONSONCONFIGURESERVICES].Add(ex);
            }

            return(services.BuildServiceProvider());
        }
예제 #30
0
        /// <summary>
        /// Calls and executes plugin.
        /// </summary>
        /// <param name="execContext">Data loader context.</param>
        /// <param name="parameters">Dictionary or custom parameters of the Call Data Loader.</param>
        /// <param name="isWriteOperation">boolean parameter - the type of operation.</param>
        /// <returns>The called plugin result.</returns>
        private List <Dictionary <string, object> > ExecuteOperation(IDataLoaderContext execContext, Dictionary <string, object> parameters, bool isWriteOperation)
        {
            List <Dictionary <string, object> > result = new List <Dictionary <string, object> >();
            CustomSettings customSettings = new CustomSettings(execContext, isWriteOperation);

            if (execContext.ProcessingContext.InputModel.ProcessingContextRef is RequestExecutor requestExecutor)
            {
                parameters = ConcatDictionaries(parameters, GetChildrenFromKeyRecursive(execContext.ProcessingContext.InputModel.Data, execContext.CurrentNode.NodeKey) as IDictionary <string, object>);

                object getChildren = GetChildrenFromKeyRecursive(execContext.ProcessingContext.InputModel.Data, execContext.CurrentNode.NodeKey);

                if (getChildren != null && getChildren is IDictionary <string, object> children)
                {
                    parameters = ConcatDictionaries(parameters, children);
                }
                else
                {
                    parameters = ConcatDictionaries(parameters, execContext.ProcessingContext.InputModel.Data);

                    KraftLogger.LogDebug($"Key '{execContext.CurrentNode.NodeKey}' was not passed in the request data. The CallDataLoader will be executed with input model's data. For the request to node '{execContext.ProcessingContext.InputModel.Module}.{execContext.ProcessingContext.InputModel.NodeSet}.{execContext.CurrentNode.NodeKey}'.");
                }

                InputModelParameters inputModelParameters = new InputModelParameters()
                {
                    Module         = customSettings.ModuleValue,
                    Nodeset        = customSettings.NodesetValue,
                    Nodepath       = customSettings.NodepathValue,
                    Data           = parameters,
                    FormCollection = execContext.ParentResult,
                    KraftGlobalConfigurationSettings = execContext.ProcessingContext.InputModel.KraftGlobalConfigurationSettings,
                    IsWriteOperation = customSettings.OperationValue,
                    LoaderType       = execContext.ProcessingContext.InputModel.LoaderType,
                    SecurityModel    = execContext.ProcessingContext.InputModel.SecurityModel,
                    Server           = execContext.ProcessingContext.InputModel.Server != default(ReadOnlyDictionary <string, object>) ? execContext.ProcessingContext.InputModel.Server.ToDictionary(item => item.Key, item => item.Value) : null
                };

                IProcessingContext processingContext = new ProcessingContext(execContext.ProcessingContext.ProcessorHandler)
                {
                    InputModel = new InputModel(inputModelParameters)
                };

                requestExecutor.ExecuteReEntrance(processingContext, false);

                if (!processingContext.ReturnModel.Status.IsSuccessful)
                {
                    string message = string.Empty;
                    string space   = " ";

                    execContext.ProcessingContext.ReturnModel.Status.IsSuccessful = processingContext.ReturnModel.Status.IsSuccessful;

                    processingContext.ReturnModel.Status.StatusResults.ForEach(statusResult =>
                    {
                        if (message.Length != 0)
                        {
                            message += space + statusResult.Message;
                        }
                        else
                        {
                            message += statusResult.Message;
                        }
                    });

                    throw new Exception(message);
                }

                if (processingContext.ReturnModel.Data is List <Dictionary <string, object> > resultListOfDictionary)
                {
                    result = resultListOfDictionary;
                }
                else if (processingContext.ReturnModel.Data is Dictionary <string, object> resultDictionary)
                {
                    result.Add(resultDictionary);
                }
            }

            return(result);
        }