Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proof of concept code for merging settings and config. #1789

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using System.Collections.Generic;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.Json;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SenseNet.ContentRepository;

namespace SenseNet.Configuration
{
internal class SettingsConfigurationProvider : JsonConfigurationProvider
{
public SettingsConfigurationProvider(SettingsConfigurationSource source): base(source)
{}

public override void Load()
{
if (!(Providers.Instance?.SearchManager?.ContentQueryIsAllowed ?? false))
{
Data = new Dictionary<string, string>();
return;
}

var settings = SettingsCache.Instance.GetSettings();

// build a JSON file containing all settings inside a 'sensenet' property
var allSettingsObject = new JObject();
var snObject = new JObject();
allSettingsObject.Add("sensenet", snObject);

//UNDONE: filter settings that must not be treated as configuration for security reasons. Whitelist?
foreach (var setting in settings)
{
var jo = setting.BinaryAsJObject;
if (jo == null)
continue;

var propertyName = setting.Name.Replace(".settings", string.Empty);
snObject.Add(propertyName, jo);
}

var allSettingsText = JsonConvert.SerializeObject(allSettingsObject, Formatting.Indented);

using var settingsStream = RepositoryTools.GetStreamFromString(allSettingsText);
base.Load(settingsStream);

OnReload();
}
}

internal class SettingsConfigurationSource : JsonConfigurationSource
{
public override IConfigurationProvider Build(IConfigurationBuilder builder)
{
EnsureDefaults(builder);
return new SettingsConfigurationProvider(this);
}
}

//UNDONE: temp class for testing the feature
public class PortalSettingsOptions
{
public int BinaryHandlerClientCacheMaxAge { get; set; }
public string PermittedAppsWithoutOpenPermission { get; set; }
public string[] AllowedOriginDomains { get; set; }
}

public static class ConfigurationBuilderExtensions
{
public static IConfigurationBuilder AddSenseNetSettingsConfiguration(
this IConfigurationBuilder builder)
{
// access other config values if necessary

//var tempConfig = builder.Build();
//var connectionString =
// tempConfig.GetConnectionString("WidgetConnectionString");

return builder.Add(new SettingsConfigurationSource());
}
}
}
1 change: 1 addition & 0 deletions src/ContentRepository/SenseNet.ContentRepository.csproj
Original file line number Diff line number Diff line change
@@ -36,6 +36,7 @@
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.16" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Nito.AsyncEx.Coordination" Version="5.0.0" />
<PackageReference Include="SenseNet.Security" Version="4.1.4" />
2 changes: 1 addition & 1 deletion src/ContentRepository/Settings.cs
Original file line number Diff line number Diff line change
@@ -164,7 +164,7 @@ protected XmlDocument BinaryAsXml
/// <summary>
/// Gets data as a <see cref="JObject"/> if it can be parsed, or null.
/// </summary>
protected JObject BinaryAsJObject
protected internal JObject BinaryAsJObject
{
get
{
30 changes: 30 additions & 0 deletions src/ContentRepository/SettingsCache.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using SenseNet.ContentRepository.Storage;
using System;
using System.Collections.Generic;
using System.Linq;
using SenseNet.Configuration;
using SenseNet.ContentRepository.Storage.Events;
using SenseNet.Diagnostics;

namespace SenseNet.ContentRepository
@@ -59,6 +62,33 @@ public static T GetSettingsByName<T>(string settingsName, string contextPath) wh
return null;
}

internal Settings[] GetSettings()
{
return Items.Keys.Select(Node.Load<Settings>).ToArray();
}
protected override void Invalidate()
{
base.Invalidate();

Providers.Instance.OnSettingsReloaded();
}

protected override void OnNodeModified(object sender, NodeEventArgs e)
{
//UNDONE: make sure settings-config invalidation happens
// only once but it happens on all web nodes.
base.OnNodeModified(sender, e);

if (e.SourceNode is not Settings)
return;

// invalidate only if the base method did not do it to avoid double reload
if (e.OriginalSourcePath == e.SourceNode.Path || !IsSubtreeContaining(e.OriginalSourcePath))
{
Providers.Instance.OnSettingsReloaded();
}
}

protected override List<TNode> LoadItems()
{
var settings = Tools.LoadItemsByContentType("Settings");
5 changes: 4 additions & 1 deletion src/Services.Core/ServicesExtensions.cs
Original file line number Diff line number Diff line change
@@ -65,7 +65,10 @@ internal static IServiceCollection ConfigureSenseNet(this IServiceCollection ser
services.Configure<MessagingOptions>(configuration.GetSection("sensenet:security:messaging"));
services.Configure<CryptographyOptions>(configuration.GetSection("sensenet:cryptography"));
services.Configure<RepositoryTypeOptions>(options => {});


// usage: GetService<IOptionsMonitor<PortalSettingsOptions>>
services.Configure<PortalSettingsOptions>(configuration.GetSection("sensenet:Portal"));

services.ConfigureConnectionStrings(configuration);

return services;
15 changes: 15 additions & 0 deletions src/Storage/Configuration/Providers.cs
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@
using SenseNet.Security.Messaging;
using SenseNet.Tools;
using System.Linq;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using SenseNet.ContentRepository.Search.Indexing;
using SenseNet.ContentRepository.Storage.AppModel;
@@ -81,6 +82,13 @@ public Providers(IServiceProvider services)
SearchManager = services.GetService<ISearchManager>();
IndexManager = services.GetService<IIndexManager>();
IndexPopulator = services.GetService<IIndexPopulator>();

//UNDONE: find our service correctly (marker interface?)
var conf = services.GetService<IConfiguration>() as ConfigurationRoot;
var settingsConf =
conf.Providers.LastOrDefault(c => c.GetType().FullName.EndsWith("SettingsConfigurationProvider"));

SettingsReloaded += (sender, args) => settingsConf.Load();
}

/// <summary>
@@ -119,6 +127,13 @@ public Providers(IServiceProvider services)
public IIndexManager IndexManager { get; }
public IIndexPopulator IndexPopulator { get; }

private event EventHandler SettingsReloaded;

public void OnSettingsReloaded()
{
SettingsReloaded?.Invoke(this, EventArgs.Empty);
}

/* ========================================================= Need to refactor */

public IEventLogger EventLogger { get; set; }
5 changes: 5 additions & 0 deletions src/WebApps/SnWebApplication.Api.Sql.TokenAuth/Program.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using SenseNet.Configuration;
using Serilog;

namespace SnWebApplication.Api.Sql.TokenAuth
@@ -14,6 +15,10 @@ public static void Main(string[] args)

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((_, configuration) =>
{
configuration.AddSenseNetSettingsConfiguration();
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>()