コード例 #1
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection serviceCollection)
        {
            applicationSettings = InjectedManager.CreateApplicationSettingsStandard(Configuration);
            serviceCollection.AddSingleton(applicationSettings);
            serviceCollection.AddSingleton(Configuration);
            serviceCollection.AddSingleton(serviceCollection);

            // for section real time update
            serviceCollection.Configure <List <RoutineResolvable> >(Configuration.GetSection("Routines"));
            // todo: configuration container should be builded from "snapshot" that is acessed by
            //serviceCollection.AddScoped(sp => sp.GetService<Microsoft.Extensions.Options.IOptionsSnapshot<List<RoutineResolvable>>>().Value);

            serviceCollection.AddMemoryCache(); // AddDistributedMemoryCache();

            serviceCollection.AddRazorPages();

            // NOTE: without this unicode characters (non-english) are serialized as HTML char entities (&#x00..)
            serviceCollection.Configure <WebEncoderOptions>(webEncoderOptions => {
                webEncoderOptions.TextEncoderSettings = new TextEncoderSettings(UnicodeRanges.All);
            });

            // NOTE: alternatively for MVC
            // services.AddControllersWithViews();
            // NOTE: legacy ASP Core
            // serviceCollection.AddMvc((options) => { options.EnableEndpointRouting = false; }).SetCompatibilityVersion(CompatibilityVersion.Version_3_0);

            // supports webpack real time server
            //serviceCollection.AddSingleton(new DevProxyMiddlewareSettings(
            //    new PathString("/dist"),
            //    new Uri("http://localhost:63558"))
            //);
        }
コード例 #2
0
ファイル: AspNetCoreManager.cs プロジェクト: xsysfan/Routines
        public static IRoutineHandlerAsync <TUser, TUserContext> GetUserHandlerAsync <TUser, TUserContext>(
            AspRoutineFeature aspRoutineFeature,
            Func <object> getInput,
            TUser user,
            TUserContext userContext,
            ContainerFactory containerFactory,
            MemberTag memberTag,
            ApplicationSettings applicationSettings,
            Func <TUserContext, string> configurationFor
            )
        {
            var composeLoggers = InjectedManager.ComposeNLogMemberLoggerFactory(aspRoutineFeature.TraceDocument.Builder);
            var logger         = new AdminkaRoutineHandlerFactory <TUserContext>(aspRoutineFeature.CorrelationToken,
                                                                                 InjectedManager.DefaultRoutineTagTransformException, composeLoggers,
                                                                                 applicationSettings.PerformanceCounters);
            var  @for      = configurationFor(userContext);
            var  container = containerFactory.CreateContainer(memberTag, @for);
            bool hasVerboseLoggingPrivilege = true;
            var  input          = getInput();
            var  routineHandler = logger.CreateLoggingHandler(memberTag, container, userContext, hasVerboseLoggingPrivilege, input);

            return(new ComplexRoutineHandlerAsync <TUser, TUserContext>(
                       closure => user,
                       routineHandler
                       ));
        }
コード例 #3
0
ファイル: MarkdownTagHelper.cs プロジェクト: xsysfan/Routines
        public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
        {
            var c          = (await output.GetChildContentAsync()).GetContent();
            var html       = InjectedManager.Markdown(c);
            var htmlString = new HtmlString(html);

            output.Content.SetHtmlContent(htmlString);
        }
コード例 #4
0
        public static string TestDependencies()
        {
            var t0       = typeof(UserContext);
            var t1       = typeof(RoutineClosure <UserContext>);
            var identity = InjectedManager.GetDefaultIdentity();

            return(InjectedManager.Markdown($"*** fail early {t1.GetType().Name} {t0.Assembly} {identity}***"));
        }
コード例 #5
0
ファイル: WcfRoutine.cs プロジェクト: xsysfan/Routines
 protected WcfRoutine(Guid correlationToken, Routines.MemberTag memberTag, string faultCodeNamespace,
                      object input)
     : this(
         correlationToken, memberTag, faultCodeNamespace,
         ApplicationSettings,
         InjectedManager.ResetConfigurationContainerFactoryClassic(),
         input)
 {
 }
コード例 #6
0
ファイル: WcfRoutine.cs プロジェクト: xsysfan/Routines
        public static Exception TransformException(
            Exception exception,
            Guid correlationToken,
            Routines.MemberTag memberTag,
            string faultCodeNamespace /*, Func<Exception, string> markdownException*/)
        {
            var    code = default(string);
            string message;

            if (exception is AdminkaException adminkaException)
            {
                message = adminkaException.Message;
                code    = adminkaException.Code;
            }
            else
            {
                message = "Remote server error: " + exception.Message + "(" + exception.GetType().FullName + ")";
                if (exception.Data.Contains("Code"))
                {
                    code = exception.Data["Code"] as string;
                }
            }

            var routineError = new RoutineError()
            {
                CorrelationToken = correlationToken,
                MemberTag        = new MemberTag()
                {
                    Namespace = memberTag.Namespace,
                    Type      = memberTag.Type,
                    Member    = memberTag.Member
                },
                Message = message,
                AdminkaExceptionCode = code,

                Details = InjectedManager.Markdown(exception)
            };

            if (exception.Data.Count > 0)
            {
                var data = new Dictionary <string, string>();
                foreach (var k in exception.Data.Keys)
                {
                    if (k is string kStr && exception.Data[k] is string vStr)
                    {
                        data[kStr] = vStr;
                    }
                }
                if (data.Count > 0)
                {
                    routineError.Data = data;
                }
            }
            return(new WcfException(routineError, message, "UNSPECIFIED", faultCodeNamespace));
        }
コード例 #7
0
        // TODO setup ReturnUrl
        // For this every link to potentially forbidden should contain returnUrl parameter
        // one option to get it is HttpContext.Request.GetDisplayUrl();
        void Prepare()
        {
            var routineFeature   = this.HttpContext.Features.Get <AspRoutineFeature>();
            var exceptionHandler = this.HttpContext.Features.Get <IExceptionHandlerFeature>();
            var exception        = exceptionHandler?.Error;

            if (exception != null && routineFeature == null)
            {
                var markdown = InjectedManager.Markdown(exception);
                var correlationTokenRequest = this.HttpContext.Request.Headers["X-CorrelationToken"].FirstOrDefault();
                Guid.TryParse(correlationTokenRequest, out var correlationToken);

                //TODO add internal authorization log ?
                //applicationSettings.UnhandledExceptionLogger.TraceError(correlationToken, markdown);
            }

            RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;

            Message = "Access denied. Ask network administrator to promote your user account.";
            Title   = "Security";

            var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");

            if (environment == "Development")
            {
                ShowAdvancedInformation = true;
            }
            else
            {
                var isAdminPrivilege = false; // TODO: add this privilege through config file to the users with specific names
                if (isAdminPrivilege)
                {
                    ShowAdvancedInformation = true;
                }
            }
            if (ShowAdvancedInformation)
            {
                if (routineFeature != null && routineFeature.TraceDocument != null)
                {
                    var text = routineFeature.TraceDocument.Build();
                    ExceptionHtml = InjectedManager.ToHtml(text);
                }
                else if (exception != null)
                {
                    ExceptionHtml = InjectedManager.ToHtml(exception);
                }
                if (routineFeature != null)
                {
                    CorrelationToken = routineFeature.CorrelationToken.ToString();
                }
            }
        }
コード例 #8
0
        public static string GetErrorActionJson(Exception ex, string aspRequestId, bool isAdminPrivilege)
        {
            string content;

            if (isAdminPrivilege)
            {
                var markdownMessage = InjectedManager.Markdown(ex);
                var htmlMessage     = InjectedManager.ToHtmlException(markdownMessage);
                var source          = new { isAdminPrivilege = true, aspRequestId, htmlMessage };
                content = JsonConvert.SerializeObject(source);
            }
            else
            {
                var source = new { isAdminPrivilege = false, message = "There was been a problem with the website. We are working on resolving it." };
                content = JsonConvert.SerializeObject(source);
            }
            return(content);
        }
コード例 #9
0
        public static ComplexRoutineHandlerAsync <StorageRoutineHandlerAsync <TUserContext>, TUserContext> GetContainerStorageHandlerAsync <TUserContext>(
            ContainerFactory containerFactory,
            MemberTag memberTag,
            AspRoutineFeature aspRoutineFeature,
            Func <object> getInput,
            TUserContext userContext,
            ApplicationSettings applicationSettings,
            //Func<TUserContext, string> getConfigurationFor,
            Func <TUserContext, string> getAuditStamp
            )
        {
            var adminkaRoutineHandlerFactory = new AdminkaRoutineHandlerFactory <TUserContext>(
                correlationToken: Guid.NewGuid(),
                InjectedManager.DefaultRoutineTagTransformException,
                InjectedManager.ComposeNLogMemberLoggerFactory(null),
                applicationSettings.PerformanceCounters);

            IHandlerAsync <RoutineClosure <TUserContext> > loggingHandler = adminkaRoutineHandlerFactory.CreateLoggingHandler(
                memberTag,
                containerFactory.CreateContainer(memberTag, getAuditStamp(userContext)),
                userContext,
                hasVerboseLoggingPrivilege: false,
                getInput());

            return(new ComplexRoutineHandlerAsync <StorageRoutineHandlerAsync <TUserContext>, TUserContext> /*AdminkaRoutineHandlerBase<TUserContext>*/ (
                       closure => new AuthenticationDomStorageRoutineHandlerAsync <TUserContext>(
                           applicationSettings.AdminkaStorageConfiguration,
                           userContext,
                           null,
                           new Handler <RoutineClosure <TUserContext>, RoutineClosure <TUserContext> >(
                               () => closure,
                               closure
                               ),
                           getAudit: uc => getAuditStamp(uc)
                           ),
                       loggingHandler
                       ));
        }
コード例 #10
0
        //public static bool FindSqlException(AggregateException aggregateException, out SqlException sqlException)
        //{
        //    sqlException = null;
        //    foreach (var ex in aggregateException.InnerExceptions)
        //    {
        //        if (ex is SqlException)
        //        {
        //            sqlException = (SqlException)ex;
        //            return true;
        //        }
        //    }
        //    return false;
        //}

        void Prepare()
        {
            var exceptionHandler   = this.HttpContext.Features.Get <IExceptionHandlerFeature>();
            var aspRoutineFeature  = this.HttpContext.Features.Get <AspRoutineFeature>();
            var pageRoutineFeature = this.HttpContext.Features.Get <PageRoutineFeature>();

            // TODO: create url tree (where to go on error) and url to title (button name) map
            if (pageRoutineFeature != null)
            {
                ReturnUrl = pageRoutineFeature.Referrer;
            }

            var    unhandledException  = exceptionHandler?.Error;
            string detailsMarkdown     = default;
            var    isHandledByDocument = aspRoutineFeature != null && aspRoutineFeature.TraceDocument.IsExceptionHandled;

            if (unhandledException != null && !isHandledByDocument)
            {
                detailsMarkdown = InjectedManager.Markdown(unhandledException);
                var correlationTokenRequest = this.HttpContext.Request.Headers["X-CorrelationToken"].FirstOrDefault();
                Guid.TryParse(correlationTokenRequest, out var correlationToken);
                applicationSettings.UnhandledExceptionLogger.TraceError(correlationToken, detailsMarkdown);
            }
            RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;

            //SqlException sqlException = null;
            var remoteServerErrorType = SqlServerManager.QuickAnalyze(unhandledException);

            if (remoteServerErrorType == RemoteServerErrorType.DOWN)
            {
                Message = "Adminka is currently down for maintenance. Back soon.";
                Title   = "Maintenance";
            }
            else if (remoteServerErrorType == RemoteServerErrorType.OVERLOADED)
            {
                Message = "Adminka is a bit overloaded right now... We are sorry asking you try again later";
                Title   = "Maintenance";
            }


            var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");

            if (environment == "Development" || applicationSettings.ForceDetailsOnCustomErrorPage)
            {
                ShowAdvancedInformation = true;
            }
            else
            {
                var isAdminPrivilege = User.Claims.Any(c => c.Type == "PRIVILEGE" && c.Value == "ADMIN");
                if (isAdminPrivilege)
                {
                    ShowAdvancedInformation = true;
                }
            }
            if (ShowAdvancedInformation)
            {
                if (isHandledByDocument)
                {
                    var text = aspRoutineFeature.TraceDocument.Build();
                    ExceptionHtml = InjectedManager.ToHtml(text);
                }
                else if (unhandledException != null && detailsMarkdown != null)
                {
                    ExceptionHtml = InjectedManager.ToHtmlException(detailsMarkdown);
                }

                if (aspRoutineFeature != null)
                {
                    CorrelationToken = aspRoutineFeature.CorrelationToken.ToString();
                }
            }
        }
コード例 #11
0
        public IHandlerOmni <RoutineClosure <TUserContext> > CreateLoggingHandler(
            MemberTag memberTag,
            IContainer container,
            TUserContext userContext,
            bool hasVerboseLoggingPrivilege,
            object input)
        {
            var loggingConfiguration        = container.Resolve <LoggingConfiguration>();
            var loggingVerboseConfiguration = container.Resolve <LoggingVerboseConfiguration>();

            var memberLogger = composeLoggers(base.CorrelationToken, memberTag);

            var bufferedMemberLogger = base.CreateMemberLogger(memberLogger,
                                                               loggingVerboseConfiguration.ShouldVerboseWithStackTrace,
                                                               loggingConfiguration.StartActivity);

            var activityLogger  = (IActivityLogger)bufferedMemberLogger;
            var dataLogger      = (IDataLogger)bufferedMemberLogger;
            var exceptionLogger = (IExceptionLogger)bufferedMemberLogger;
            var errorLogger     = (IErrorLogger)bufferedMemberLogger;

            Func <object, object, TimeSpan, bool> testInputOutput;

            if (!loggingVerboseConfiguration.Input && !loggingVerboseConfiguration.Output && !loggingVerboseConfiguration.Verbose)
            {
                testInputOutput = (i, o, d) => false;
            }
            else
            {
                testInputOutput = InjectedManager.ComposeTestInputOutput(
                    loggingVerboseConfiguration.ErrorRuleLang,
                    loggingVerboseConfiguration.ErrorRule,
                    (d, m) => errorLogger.LogError(d, m));
            }

            var configFileEnableVerbose = loggingVerboseConfiguration.Verbose;
            var exceptionHandler        = new ExceptionHandler(
                ex =>
            {
                performanceCounters.CountError();
                exceptionLogger.LogException(DateTime.Now, ex);
            },
                ex => routineTransformException(ex, base.CorrelationToken, memberTag /*, InjectedManager.Markdown*/)
                );
            var enableVerbose = hasVerboseLoggingPrivilege;

            if (!enableVerbose)
            {
                enableVerbose = configFileEnableVerbose;
            }
            var(routineHandler, closure) = CreateRoutineHandler(
                configFileEnableVerbose && hasVerboseLoggingPrivilege,
                logVerbose => new RoutineClosure <TUserContext>(userContext, logVerbose, container),
                exceptionHandler,
                loggingConfiguration.FinishActivity,
                input,
                activityLogger,
                (dateTime, o) => dataLogger.Input(dateTime, o),
                (dateTime, o) => dataLogger.Output(dateTime, o),
                memberTag,
                bufferedMemberLogger.LogVerbose,
                loggingVerboseConfiguration.ShouldVerboseWithStackTrace,
                testInputOutput,
                performanceCounters.CountDurationTicks
                );

            return(routineHandler);
        }
コード例 #12
0
        public static HtmlString MarkdownException(this IHtmlHelper helper, Exception exception)
        {
            var html = InjectedManager.ToHtml(exception);

            return(new HtmlString(html));
        }
コード例 #13
0
ファイル: AspNetCoreManager.cs プロジェクト: xsysfan/Routines
        GetUserAndFailedActionResultInitialisedAsync(
            ApplicationSettings applicationSettings,
            MemberTag memberTag,
            Func <string> getName,
            Func <string, bool> systemIsInRole,
            //Func<IReadOnlyList<string>> getGroups,
            //Func<(string givenName, string surname)> getUserData,
            AspRoutineFeature aspRoutineFeature,
            IMemoryCache memoryCache,
            Func <IActionResult> getForbiddenActionResult,
            Func <Exception, IActionResult> exceptionToActionResult = null
            )
        {
            var containerFactory = InjectedManager.CreateContainerFactory(applicationSettings.ConfigurationContainerFactory);
            Func <string, IContainer> getContainer = @for => containerFactory.CreateContainer(memberTag, @for);

            var routine = new AdminkaAnonymousRoutineHandlerAsync(
                applicationSettings,
                applicationSettings.PerformanceCounters,
                applicationSettings.ConfigurationContainerFactory,
                InjectedManager.DefaultRoutineTagTransformException,
                aspRoutineFeature.CorrelationToken,
                aspRoutineFeature.TraceDocument.Builder,
                new MemberTag("MvcAppManager", "GetUserAndFailedActionResultInitialisedAsync"),
                new AnonymousUserContext("Authentication"),
                null);
            IActionResult forbiddenAsActionResult = default;

            var user = await routine.HandleAsync(async (container, closure) =>
            {
                try
                {
                    var useAdAuthorization = applicationSettings.UseAdAuthorization;
                    var isInRole           = default(Func <string, bool>);
                    var userNameWithDomain = default(string);

                    if (useAdAuthorization)
                    {
                        userNameWithDomain          = getName();
                        var personalContainer       = getContainer(userNameWithDomain);
                        var personalContainerGroups = personalContainer.Resolve <FakeAdConfiguration>().FakeAdGroups;
                        if (personalContainer == null || personalContainerGroups.Count > 0)
                        {
                            isInRole = g => personalContainerGroups.Contains(g);
                        }
                        else
                        {
                            isInRole = systemIsInRole;
                        }

                        closure.Verbose?.Invoke($"useAdAuthorization:{useAdAuthorization}, adUserName: {userNameWithDomain}");

                        var firstName  = default(string);
                        var secondName = default(string);
                        //var (firstName, secondName) = ActiveDirectoryManager.GetUserData(windowsIdentity);

                        return(await container.ResolveAuthenticationDomDbContextHandlerAsync().HandleDbContextAsync(
                                   async(db) =>
                        {
                            return await memoryCache.GetOrCreateAsync(
                                "USER::" + userNameWithDomain,
                                async cacheEntry =>
                            {
                                cacheEntry
                                .SetAbsoluteExpiration(TimeSpan.FromHours(5))
                                .SetSlidingExpiration(TimeSpan.FromMinutes(5));
                                var authenticationService = new AuthenticationService(db);

                                var u = await authenticationService.GetUserAsync(userNameWithDomain, firstName, secondName, isInRole);
                                return u;
                            }
                                );
                        }
                                   ));
                    }
                    else
                    {
                        var fakeAdConfiguration = closure.Resolve <FakeAdConfiguration>();

                        userNameWithDomain = fakeAdConfiguration.FakeAdUser;
                        isInRole           = g => fakeAdConfiguration.FakeAdGroups.Contains(g);

                        closure.Verbose?.Invoke($"useAdAuthorization:{useAdAuthorization}, adUserName: {userNameWithDomain}");

                        return(await container.ResolveAuthenticationDomDbContextHandlerAsync().HandleDbContextAsync(
                                   async(db) =>
                        {
                            var authenticationService = new AuthenticationService(db);
                            var userEntity = await authenticationService.GetUserAsync(
                                fakeAdConfiguration.FakeAdUser, "Anonymous", "Anonymous", isInRole);
                            return userEntity;
                        }
                                   ));
                    }
                }
                catch (Exception ex)
                {
                    if (exceptionToActionResult != null)
                    {
                        forbiddenAsActionResult = exceptionToActionResult(ex);
                        return(null);
                    }
                    else
                    {
                        throw new AdminkaException("User authetication and authorization service generates an error because of configuration or network connection problems", ex);
                    }
                }
            });

            if (user == default && forbiddenAsActionResult == default)
            {
                forbiddenAsActionResult = getForbiddenActionResult();
            }

            return(forbiddenAsActionResult, user, containerFactory);
        }