// 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 (�..) 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")) //); }
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 )); }
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); }
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}***")); }
protected WcfRoutine(Guid correlationToken, Routines.MemberTag memberTag, string faultCodeNamespace, object input) : this( correlationToken, memberTag, faultCodeNamespace, ApplicationSettings, InjectedManager.ResetConfigurationContainerFactoryClassic(), input) { }
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)); }
// 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(); } } }
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); }
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 )); }
//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(); } } }
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); }
public static HtmlString MarkdownException(this IHtmlHelper helper, Exception exception) { var html = InjectedManager.ToHtml(exception); return(new HtmlString(html)); }
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); }