private void HandleChangedCml(string cml, string captionPrefix) { var cc = new CMLConverter(); if (_lastCml != EmptyCml) { var clone = cc.Import(_lastCml); Debug.WriteLine( $"Pushing F: {clone.ConciseFormula} BL: {clone.MeanBondLength.ToString("#,##0.00")} onto Stack"); _undoStack.Push(clone); } Model m = cc.Import(cml); m.Relabel(true); m.EnsureBondLength(20, false); _lastCml = cc.Export(m); // Cause re-read of settings (in case they have changed) _editorOptions = new AcmeOptions(null); SetDisplayOptions(); RedoStack.SetOptions(_editorOptions); UndoStack.SetOptions(_editorOptions); ShowChemistry($"{captionPrefix} {m.ConciseFormula}", m); }
public void SetOptions(AcmeOptions options) { ShowAtomsInColour = options.ColouredAtoms; ShowAllCarbonAtoms = options.ShowCarbons; ShowImplicitHydrogens = options.ShowHydrogens; ShowMoleculeGrouping = options.ShowMoleculeGrouping; }
private void ChangeSettings_Click(object sender, EventArgs e) { AcmeSettingsHost settings = new AcmeSettingsHost(); settings.Telemetry = _telemetry; AcmeOptions tempOptions = new AcmeOptions(null); settings.TopLeft = new Point(Left, Top); settings.EditorOptions = tempOptions; settings.Telemetry = _telemetry; DialogResult dr = settings.ShowDialog(); if (dr == DialogResult.OK) { _editorOptions = tempOptions.Clone(); SetDisplayOptions(); Display.Chemistry = _lastCml; RedoStack.SetOptions(_editorOptions); UndoStack.SetOptions(_editorOptions); UndoStack.ListOfDisplays.ItemsSource = StackToList(_undoStack); RedoStack.ListOfDisplays.ItemsSource = StackToList(_redoStack); } settings.Close(); }
public FlexForm() { InitializeComponent(); _helper = new SystemHelper(); _telemetry = new TelemetryWriter(true, _helper); _editorOptions = new AcmeOptions(null); }
public override void Refresh() { string module = $"{_product}.{_class}.{MethodBase.GetCurrentMethod().Name}()"; try { _editorOptions = new AcmeOptions(Globals.Chem4WordV3.AddInInfo.ProductAppDataPath); libraryView1.SetOptions(_editorOptions); using (new WaitCursor()) { if (_libraryViewModel == null) { _libraryViewModel = new LibraryViewModel(); } libraryView1.MainGrid.DataContext = _libraryViewModel; } } catch (Exception ex) { using (var form = new ReportError(Globals.Chem4WordV3.Telemetry, Globals.Chem4WordV3.WordTopLeft, module, ex)) { form.ShowDialog(); } } }
private void Save_OnClick(object sender, RoutedEventArgs e) { string module = $"{_product}.{_class}.{MethodBase.GetCurrentMethod().Name}()"; // Copy current model values to options before saving AcmeOptions.BondLength = (int)SettingsModel.CurrentBondLength; AcmeOptions.ShowMoleculeGrouping = SettingsModel.ShowMoleculeGroups; AcmeOptions.ShowHydrogens = SettingsModel.ShowImplicitHydrogens; AcmeOptions.ColouredAtoms = SettingsModel.ShowAtomsInColour; AcmeOptions.ShowCarbons = SettingsModel.ShowAllCarbonAtoms; AcmeOptions.Save(); if (AcmeOptions.Errors.Any()) { Telemetry.Write(module, "Exception", string.Join(Environment.NewLine, AcmeOptions.Errors)); AcmeOptions.Errors = new List <string>(); } AcmeOptions.Dirty = false; WpfEventArgs args = new WpfEventArgs(); args.Button = "SAVE"; args.OutputValue = ""; OnButtonClick?.Invoke(this, args); }
public EditLabelsHost(AcmeOptions options) { using (new WaitCursor()) { _options = options; InitializeComponent(); } }
public NavigatorHost(Microsoft.Office.Interop.Word.Application app, Document doc) : this() { _acmeOptions = new AcmeOptions(Globals.Chem4WordV3.AddInInfo.ProductAppDataPath); navigatorView1.SetOptions(_acmeOptions); ActiveApp = app; ActiveDoc = doc; }
public EditorHost(string cml, List <string> used1DProperties, AcmeOptions options) { InitializeComponent(); _cml = cml; _used1DProperties = used1DProperties; _options = options; }
public AtomPropertyEditor(AtomPropertiesModel model, AcmeOptions options) : this() { if (!DesignerProperties.GetIsInDesignMode(this)) { AtomPropertiesModel = model; DataContext = AtomPropertiesModel; AtomPath.Text = AtomPropertiesModel.Path; _options = options; } }
public SettingsHost(AcmeOptions options, IChem4WordTelemetry telemetry, Point topLeft) : this() { if (!DesignerProperties.GetIsInDesignMode(this)) { UcSettings.AcmeOptions = options; UcSettings.Telemetry = telemetry; UcSettings.OnButtonClick += UcSettingsOnOnButtonClick; _topLeft = topLeft; } }
public static void ShowAcmeSettings(EditorCanvas currentEditor, AcmeOptions options, IChem4WordTelemetry telemetry, Point topLeft) { var mode = Application.Current.ShutdownMode; Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown; var pe = new SettingsHost(options, telemetry, topLeft); ShowDialog(pe, currentEditor); Application.Current.ShutdownMode = mode; }
public EditorHost(string cml, string type) { InitializeComponent(); _editorType = type; AcmeOptions acmeOptions = new AcmeOptions(null); var used1D = SimulateGetUsed1DLabels(cml); MessageFromWpf.Text = ""; SystemHelper helper = new SystemHelper(); var telemetry = new TelemetryWriter(true, helper); switch (_editorType) { case "ACME": Editor acmeEditor = new Editor(); acmeEditor.EditorOptions = acmeOptions; acmeEditor.InitializeComponent(); elementHost1.Child = acmeEditor; // Configure Control acmeEditor.ShowFeedback = false; acmeEditor.TopLeft = new Point(Left, Top); acmeEditor.Telemetry = telemetry; acmeEditor.SetProperties(cml, used1D, acmeOptions); acmeEditor.OnFeedbackChange += AcmeEditorOnFeedbackChange; break; case "LABELS": LabelsEditor labelsEditor = new LabelsEditor(acmeOptions); labelsEditor.InitializeComponent(); elementHost1.Child = labelsEditor; // Configure Control labelsEditor.TopLeft = new Point(Left, Top); labelsEditor.Used1D = used1D; labelsEditor.PopulateTreeView(cml); break; default: CmlEditor cmlEditor = new CmlEditor(); cmlEditor.InitializeComponent(); elementHost1.Child = cmlEditor; // Configure Control cmlEditor.Cml = cml; break; } }
private void OptionsChanged() { // Allow time for FileSytemWatcher to fire Thread.Sleep(250); _renderOptions = new OoXmlV4Options(null); _editorOptions = new AcmeOptions(null); Debug.WriteLine($"ACME ColouredAtoms {_editorOptions.ColouredAtoms}"); Debug.WriteLine($"OoXml ColouredAtoms {_renderOptions.ColouredAtoms}"); UpdateControls(); }
public MainForm() { InitializeComponent(); _helper = new SystemHelper(); _telemetry = new TelemetryWriter(true, _helper); var location = Assembly.GetExecutingAssembly().Location; var path = Path.GetDirectoryName(location); // Use either path or null below _editorOptions = new AcmeOptions(null); _renderOptions = new OoXmlV4Options(null); }
private void AtomPropertyEditor_OnLoaded(object sender, RoutedEventArgs e) { // This moves the window off screen while it renders var point = UIUtils.GetOffScreenPoint(); Left = point.X; Top = point.Y; _options = new AcmeOptions(_options.SettingsPath); SetPreviewProperties(); LoadAtomItems(); LoadFunctionalGroups(); ShowPreview(); }
private void EditWithAcme_Click(object sender, EventArgs e) { #if !DEBUG string module = $"{_product}.{_class}.{MethodBase.GetCurrentMethod().Name}()"; try { #endif if (!string.IsNullOrEmpty(_lastCml)) { using (EditorHost editorHost = new EditorHost(_lastCml, "ACME")) { editorHost.ShowDialog(this); if (editorHost.DialogResult == DialogResult.OK) { CMLConverter cc = new CMLConverter(); var clone = cc.Import(_lastCml); Debug.WriteLine( $"Pushing F: {clone.ConciseFormula} BL: {clone.MeanBondLength.ToString("#,##0.00")} onto Stack"); _undoStack.Push(clone); Model m = cc.Import(editorHost.OutputValue); m.Relabel(true); _lastCml = cc.Export(m); // Cause re-read of settings (in case they have changed) _editorOptions = new AcmeOptions(null); SetDisplayOptions(); RedoStack.SetOptions(_editorOptions); UndoStack.SetOptions(_editorOptions); ShowChemistry($"Edited {m.ConciseFormula}", m); } } TopMost = true; TopMost = false; Activate(); } #if !DEBUG } catch (Exception exception) { _telemetry.Write(module, "Exception", $"Exception: {exception.Message}"); _telemetry.Write(module, "Exception(Data)", $"Exception: {exception}"); MessageBox.Show(exception.StackTrace, exception.Message); } #endif }
public async virtual Task <string> GenerateHttpsCertificateAsync( AcmeOptions options, CancellationToken cancellationToken) { const string certName = "acme-https-cert"; var certs = new CertificateClient(options.KeyVaultUrl, _credential); try { var cert = await certs.GetCertificateAsync(certName, cancellationToken); var thumbprint = Convert.ToHexString(cert.Value.Properties.X509Thumbprint); if (cert.Value.Properties.ExpiresOn > DateTimeOffset.UtcNow.AddDays(30) && (cert.Value.Properties.Enabled ?? false)) { _logger.LogInformation("Existing valid HTTPS certificate has been found with thumbprint {}", thumbprint); return(cert.Value.Name); } _logger.LogWarning("HTTPS certificate {} is expiring soon, automatically generating a new one", thumbprint); } catch (RequestFailedException) { _logger.LogInformation("No existing HTTPS certificate has been found, generating a new one"); } const string accountKeySecretName = "acme-accountkey-pem"; AcmeContext acme; try { var secrets = new SecretClient(options.KeyVaultUrl, _credential); var accountKey = await secrets.GetSecretAsync(accountKeySecretName, cancellationToken : cancellationToken); acme = new AcmeContext(options.DirectoryUrl, KeyFactory.FromPem(accountKey.Value.Value)); _logger.LogDebug("Found existing ACME account"); } catch { _logger.LogInformation("Creating new ACME account at {} with email {}", options.DirectoryUrl, options.AccountEmail); acme = new AcmeContext(options.DirectoryUrl); await acme.NewAccount(options.AccountEmail, termsOfServiceAgreed : true); } string orderIdentifier; string acmeChallengeRecord; if (options.Subdomain is { Length : > 0 })
private void ChangeAcmeSettings_Click(object sender, EventArgs e) { AcmeSettingsHost settings = new AcmeSettingsHost(); settings.Telemetry = _telemetry; settings.TopLeft = new System.Windows.Point(Left + 24, Top + 24); var tempOptions = _editorOptions.Clone(); settings.EditorOptions = tempOptions; DialogResult dr = settings.ShowDialog(); if (dr == DialogResult.OK) { _editorOptions = tempOptions.Clone(); OptionsChanged(); } settings.Close(); }
public bool ChangeSettings(Point topLeft) { string module = $"{_product}.{_class}.{MethodBase.GetCurrentMethod().Name}()"; try { Telemetry.Write(module, "Verbose", "Called"); if (HasSettings) { _editorOptions = new AcmeOptions(SettingsPath) { Dirty = false }; using (var settings = new AcmeSettingsHost()) { settings.Telemetry = Telemetry; settings.TopLeft = topLeft; var tempOptions = _editorOptions.Clone(); settings.EditorOptions = tempOptions; DialogResult dr = settings.ShowDialog(); if (dr == DialogResult.OK) { _editorOptions = tempOptions.Clone(); } settings.Close(); } } } catch (Exception ex) { new ReportError(Telemetry, TopLeft, module, ex).ShowDialog(); } return(true); }
public DialogResult Edit() { DialogResult dialogResult = DialogResult.Cancel; string module = $"{_product}.{_class}.{MethodBase.GetCurrentMethod().Name}()"; try { Telemetry.Write(module, "Verbose", "Called"); if (HasSettings) { _editorOptions = new AcmeOptions(SettingsPath) { Dirty = false }; } using (EditorHost host = new EditorHost(Cml, Used1DProperties, _editorOptions)) { host.TopLeft = TopLeft; DialogResult showDialog = host.ShowDialog(); if (showDialog == DialogResult.OK) { dialogResult = showDialog; Cml = host.OutputValue; } } } catch (Exception ex) { new ReportError(Telemetry, TopLeft, module, ex).ShowDialog(); } return(dialogResult); }
public AcmeCertificateManager(IOptions <AcmeOptions> options) { this.options = options.Value; }
public static void AddAcmeCertificateManager(this IServiceCollection services, AcmeOptions options) { services.AddTransient <IConfigureOptions <AcmeOptions>, AcmeOptionsSetup>(); // services.AddSingleton(Options.Create(options)); services.AddTransient(sp => { var setup = sp.GetService <IConfigureOptions <AcmeOptions> >(); setup.Configure(options); return(Options.Create(options)); }); services.AddTransient <ICertificateManager, AcmeCertificateManager>(); }
public static async Task Main(string[] args) { var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Development"; var isDevelopment = "Development".Equals(environment, StringComparison.OrdinalIgnoreCase); var config = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddInMemoryCollection(new Dictionary <string, string> // add default settings, that will be overridden by commandline { { "Id", "Webapp" }, { "Version", "1.0.0" }, { "ClusterId", "rrod-cluster" }, { "ServiceId", "rrod" } }) .AddCommandLine(args) .AddJsonFile("Webapp.settings.json", optional: true, reloadOnChange: true) .AddJsonFile($"Webapp.settings.{environment}.json", optional: true, reloadOnChange: true) .AddJsonFile("/run/config/Webapp.settings.json", optional: true, reloadOnChange: true) .AddDockerSecrets("/run/secrets", optional: true) .AddUserSecrets <Program>(optional: true) .AddEnvironmentVariables("RROD_") .Build(); var loggerFactory = new LoggerFactory() .AddConsole(config.GetSection("Logging")) .AddDebug(); var logger = loggerFactory.CreateLogger <Program>(); logger.LogWarning($"Starting Webapp in {environment} environment..."); foreach (var provider in config.Providers) { logger.LogInformation($"Config Provider {provider.GetType().Name}: {provider.GetChildKeys(Enumerable.Empty<string>(), null).Count()} settings"); } // ServicePointManager.CheckCertificateRevocationList = false; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; ServicePointManager.DefaultConnectionLimit = 20; int attempt = 0; int initializeAttemptsBeforeFailing = 7; IClusterClient clusterClient = null; while (true) { // Initialize orleans client clusterClient = new ClientBuilder() .ConfigureServices((context, services) => { // services.AddOptions(); services.AddSingleton <ILoggerFactory>(loggerFactory); // services.AddSingleton<IConfiguration>(config); services.Configure <ClusterOptions>(config); }) .AddAzureQueueStreams <AzureQueueDataAdapterV2>("Default", builder => builder.Configure(options => options.ConnectionString = config.GetConnectionString("DataConnectionString"))) .ConfigureApplicationParts(parts => { parts.AddApplicationPart(typeof(ICounterGrain).Assembly).WithReferences(); parts.AddApplicationPart(typeof(AzureQueueDataAdapterV2).Assembly).WithReferences(); }) .UseAzureStorageClustering(options => options.ConnectionString = config.GetConnectionString("DataConnectionString")) .Build(); try { await clusterClient.Connect().ConfigureAwait(false); logger.LogInformation("Client successfully connected to silo host"); break; } catch (OrleansException) { attempt++; logger.LogWarning($"Attempt {attempt} of {initializeAttemptsBeforeFailing} failed to initialize the Orleans client."); if (clusterClient != null) { clusterClient.Dispose(); clusterClient = null; } if (attempt > initializeAttemptsBeforeFailing) { throw; } // Wait 4 seconds before retrying await Task.Delay(TimeSpan.FromSeconds(4)); } } var endpoints = config.GetSection("Http:Endpoints") .GetChildren() .ToDictionary(section => section.Key, section => { var endpoint = new EndpointConfiguration(); section.Bind(endpoint); return(endpoint); }); // if so, start a listener to respond to Acme (Let's Encrypt) requests, using a response received via an Orleans Cache Grain var hasHttps = endpoints.Any(endpoint => endpoint.Value.Scheme.Equals("https", StringComparison.InvariantCultureIgnoreCase)); var needPort80 = endpoints.Any(endpoint => (endpoint.Value.Port ?? (endpoint.Value.Scheme.Equals("https", StringComparison.InvariantCultureIgnoreCase) ? 443 : 80)) == 80); var certs = new Dictionary <string, X509Certificate2>(); var acmeOptions = new AcmeOptions { AcmeSettings = config.GetSection(nameof(AcmeSettings)).Get <AcmeSettings>(), GetChallengeResponse = async(challenge) => { var cacheGrain = clusterClient.GetGrain <ICacheGrain <string> >(challenge); var response = await cacheGrain.Get(); return(response.Value); }, SetChallengeResponse = async(challenge, response) => { var cacheGrain = clusterClient.GetGrain <ICacheGrain <string> >(challenge); await cacheGrain.Set(new Immutable <string>(response), TimeSpan.FromHours(2)); }, StoreCertificate = async(string domainName, byte[] certData) => { var certGrain = clusterClient.GetGrain <ICertGrain>(domainName); await certGrain.UpdateCertificate(certData); }, RetrieveCertificate = async(domainName) => { var certGrain = clusterClient.GetGrain <ICertGrain>(domainName); var certData = await certGrain.GetCertificate(); return(certData.Value); } }; if (hasHttps) { logger.LogWarning($"At least one https endpoint is present. Initialize Acme endpoint."); var acmeHost = new WebHostBuilder() .UseEnvironment(environment) .UseConfiguration(config) .ConfigureServices(services => { services.AddSingleton <IClusterClient>(clusterClient); services.AddSingleton <ILoggerFactory>(loggerFactory); services.Configure <AcmeSettings>(config.GetSection(nameof(AcmeSettings))); // Register a certitificate manager, supplying methods to store and retreive certificates and acme challenge responses services.AddAcmeCertificateManager(acmeOptions); }) // .UseUrls("http://*:80") .PreferHostingUrls(false) .UseKestrel(options => { options.Listen(IPAddress.Any, 80); }) .Configure(app => { app.UseAcmeResponse(); }) .Build(); try { await acmeHost.StartAsync().ConfigureAwait(false); } catch (Exception e) { logger.LogError("Error: can't start web listener for acme certificate renewal, probably the web address is in use by another process. Exception message is: " + e.Message); logger.LogError("Ignoring noncritical error (stop W3SVC or Skype to fix this), continuing..."); } var certificateManager = acmeHost.Services.GetRequiredService <ICertificateManager>(); // var certificateManager = new AcmeCertificateManager(Options.Create(acmeOptions)); foreach (var endpoint in endpoints) { var endpointConfig = endpoint.Value; bool isHttpsEndpoint = endpointConfig.Scheme.Equals("https", StringComparison.InvariantCultureIgnoreCase); var port = endpointConfig.Port ?? (isHttpsEndpoint ? 443 : 80); X509Certificate2 certificate = null; if (isHttpsEndpoint) { try { var domains = new List <string> { endpointConfig.Domain } .Concat(endpointConfig.Domains) .Where(ep => !string.IsNullOrEmpty(ep)) .Distinct() .ToArray(); logger.LogInformation($"Getting certificate for domain {domains.First()} on port {port}"); // Request a new certificate with Let's Encrypt and store it for next time try { certificate = await certificateManager.GetCertificate(domains); } catch (Exception e) { logger.LogCritical(e, $"Exception getting certificate for domain {domains.First()}. PfxPassword configured incorrectly?"); } if (certificate == null) { // It didn't work - create a temporary certificate so that we can still start with an untrusted certificate logger.LogCritical($"Error getting certificate for domain {domains.First()} (endpoint '{endpoint.Key}'). Creating self-signed temporary certificate..."); certificate = CertHelper.BuildTlsSelfSignedServer(domains); } certs.Add(domains.First(), certificate); logger.LogInformation($"Certificate for domain {domains.First()}: {certificate != null}"); } catch (Exception e) { logger.LogCritical($"Kestrel startup: Exception getting certificate. {e.Message}"); } } } if (needPort80) { await acmeHost.StopAsync(); } } var webHost = new WebHostBuilder() .UseEnvironment(environment) .UseConfiguration(config) .ConfigureServices(services => { // services.AddSingleton<IConfiguration>(config); services.AddSingleton <IClusterClient>(clusterClient); services.AddSingleton <ILoggerFactory>(loggerFactory); services.Configure <AcmeSettings>(config.GetSection(nameof(AcmeSettings))); services.AddAcmeCertificateManager(acmeOptions); }) .UseContentRoot(Directory.GetCurrentDirectory()) // .UseUrls(listenUrls.ToArray()) .PreferHostingUrls(false) .Configure(app => { app.UseAcmeResponse(); }) .UseStartup <Startup>() .UseKestrel(options => { foreach (var endpoint in endpoints) { var endpointConfig = endpoint.Value; bool isHttpsEndpoint = endpointConfig.Scheme.Equals("https", StringComparison.InvariantCultureIgnoreCase); var port = endpointConfig.Port ?? (isHttpsEndpoint ? 443 : 80); var ipAddresses = new List <IPAddress>(); var hosts = new List <string> { endpointConfig.Host } .Concat(endpointConfig.Hosts) .Where(ep => !string.IsNullOrEmpty(ep)) .Distinct(); foreach (var host in hosts) { if (host == "localhost") { ipAddresses.Add(IPAddress.IPv6Loopback); ipAddresses.Add(IPAddress.Loopback); } else if (IPAddress.TryParse(host, out var address)) { ipAddresses.Add(address); } else { logger.LogError($"Error parsing endpoint host: {host}"); } } foreach (var address in ipAddresses) { options.Listen(address, port, listenOptions => { if (isHttpsEndpoint) { var domains = new List <string> { endpointConfig.Domain } .Concat(endpointConfig.Domains) .Where(ep => !string.IsNullOrEmpty(ep)) .Distinct() .ToArray(); if (certs.TryGetValue(domains.First(), out var certificate)) { logger.LogInformation($"Kestrel config: Listen on address {address.ToString()}:{port}, certificate {(certificate == null ? "NULL" : certificate.Subject.ToString())}"); listenOptions.UseHttps(certificate); listenOptions.NoDelay = false; // listenOptions.UseConnectionLogging(); } else { logger.LogError($"No certificate for domain: {domains.First()}"); } } }); } } }) .Build(); await webHost.RunAsync(); }
public EditLabelsHost() { _options = new AcmeOptions(); InitializeComponent(); }
public StackViewer(AcmeOptions options) { InitializeComponent(); SetOptions(options); }
public EditLabelsHost(AcmeOptions options) { _options = options; InitializeComponent(); }
public static void Main(string[] args) { string environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Development"; bool isDevelopment = "Development".Equals(environment, StringComparison.OrdinalIgnoreCase); var builder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{environment}.json", optional: true) .AddEnvironmentVariables(); if (builder.GetFileProvider().GetFileInfo("Webapp.csproj").Exists) { builder.AddUserSecrets <Program>(); } Configuration = builder.Build(); // Initialize the connection to the OrleansHost process var orleansClientConfig = ClientConfiguration.LocalhostSilo(); orleansClientConfig.DeploymentId = Configuration["DeploymentId"]; orleansClientConfig.DataConnectionString = Configuration.GetConnectionString("DataConnectionString"); orleansClientConfig.AddSimpleMessageStreamProvider("Default"); orleansClientConfig.DefaultTraceLevel = Severity.Warning; orleansClientConfig.TraceFileName = ""; IClusterClient orleansClient; do { orleansClient = new ClientBuilder().UseConfiguration(orleansClientConfig).Build(); try { orleansClient.Connect().Wait(); // GrainClient.Initialize(orleansClientConfig); } catch (Exception ex) when(ex is OrleansException || ex is SiloUnavailableException || (ex is AggregateException && ex.InnerException is SiloUnavailableException)) { orleansClient.Dispose(); // Wait for the Host to start Thread.Sleep(3000); } }while (!orleansClient.IsInitialized); // we use a single settings file, that also contains the hosting settings var urls = (Configuration[WebHostDefaults.ServerUrlsKey] ?? "http://localhost:5000") .Split(new[] { ',', ';' }) .Select(url => url.Trim()) .ToArray(); // find out if we run any secure urls var secureUrls = urls .Distinct() .Select(url => new Uri(url)) .Where(uri => uri.Scheme == "https") .ToArray(); // It is possible to request Acme certificates with subject alternative names, but this is not yet implemented. // Usually we'll need only a single address, so I'm taking the first one // string firstSecureHost = secureUrls.Any() ? secureUrls.First().Host : null; var listenUrls = urls .Distinct() .Where(url => url.StartsWith("http://")); // if so, start a listener to respond to Acme (Let's Encrypt) requests, using a response received via an Orleans Cache Grain string[] httpsDomains; IWebHost acmeHost; AcmeOptions acmeOptions; if (!secureUrls.Any()) { httpsDomains = new string[] { }; acmeOptions = null; acmeHost = null; } else { // Kestrel can only listen once to any given port, so we make sure multiple https addresses get only one listener var httpsListen = secureUrls.GroupBy(url => url.Port).Select(url => url.First()).Select(url => "https://*:" + url.Port); listenUrls = listenUrls.Union(httpsListen); httpsDomains = secureUrls.Select(url => url.Host).Distinct().ToArray(); acmeOptions = new AcmeOptions { DomainNames = httpsDomains, GetChallengeResponse = async(challenge) => { var cacheGrain = orleansClient.GetGrain <ICacheGrain <string> >(challenge); var response = await cacheGrain.Get(); return(response.Value); }, SetChallengeResponse = async(challenge, response) => { var cacheGrain = orleansClient.GetGrain <ICacheGrain <string> >(challenge); await cacheGrain.Set(new Immutable <string>(response), TimeSpan.FromHours(2)); }, StoreCertificate = async(string domainName, byte[] certData) => { var certGrain = orleansClient.GetGrain <ICertGrain>(domainName); await certGrain.UpdateCertificate(certData); }, RetrieveCertificate = async(domainName) => { var certGrain = orleansClient.GetGrain <ICertGrain>(domainName); var certData = await certGrain.GetCertificate(); return(certData.Value); } }; acmeHost = new WebHostBuilder() .UseConfiguration(Configuration) .ConfigureLogging((context, factory) => { factory.AddConfiguration(context.Configuration.GetSection("Logging")); factory.AddConsole(); factory.AddDebug(); }) .UseEnvironment(environment) .ConfigureServices(services => { services.AddSingleton <IClusterClient>(orleansClient); services.Configure <AcmeSettings>(Configuration.GetSection(nameof(AcmeSettings))); // Register a certitificate manager, supplying methods to store and retreive certificates and acme challenge responses services.AddAcmeCertificateManager(acmeOptions); }) .UseUrls("http://*:80/.well-known/acme-challenge/") .UseKestrel() // .UseLoggerFactory(loggerFactory) .Configure(app => { app.UseAcmeResponse(); }) .Build(); try { acmeHost.Start(); } catch (Exception e) { var logger = acmeHost.Services.GetService <ILogger <Program> >(); // var logger = loggerFactory.CreateLogger<Program>(); logger.LogError("Error: can't start web listener for acme certificate renewal, probably the web address is in use by another process. Exception message is: " + e.Message); logger.LogError("Ignoring noncritical error (stop W3SVC or Skype to fix this), continuing..."); } } var host = new WebHostBuilder() .UseConfiguration(Configuration) .ConfigureLogging((context, factory) => { factory.AddConfiguration(context.Configuration.GetSection("Logging")); factory.AddConsole(); factory.AddDebug(); }) .ConfigureServices(services => { services.AddSingleton <IClusterClient>(orleansClient); if (secureUrls.Any()) { services.AddAcmeCertificateManager(acmeOptions); } }) .UseContentRoot(Directory.GetCurrentDirectory()) .UseEnvironment(environment) .UseUrls(listenUrls.ToArray()) .UseSetting("baseUrl", urls.First()) .UseStartup <Startup>() .UseKestrel(async options => { // TODO: Make this into a nice Kestrel.Https.Acme nuget package if (secureUrls.Any()) { // Request a new certificate with Let's Encrypt and store it for next time var certificateManager = options.ApplicationServices.GetService <ICertificateManager>(); var certificate = await certificateManager.GetCertificate(httpsDomains); if (certificate != null) { options.Listen(IPAddress.Loopback, 443, listenOptions => { listenOptions.UseHttps(certificate); }); } } }) .Build(); host.Run(); }
public void SetOptions(AcmeOptions options) { _options = options; }
public NavigatorHost() { InitializeComponent(); _acmeOptions = new AcmeOptions(); }