Make vault storages work

This commit is contained in:
TheXamlGuy
2024-04-28 16:04:05 +01:00
parent 20840cbf9c
commit df26cd2a75
15 changed files with 143 additions and 112 deletions
+46 -6
View File
@@ -1,6 +1,8 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Toolkit.Avalonia;
@@ -17,7 +19,26 @@ public partial class App : Application
public override async void OnFrameworkInitializationCompleted()
{
IHost? host = DefaultBuilder.Create()
//var connectionString = new SqliteConnectionStringBuilder(@"Filename=C:\\Users\\dan_c\\source\\repos\\Bitvault\\Bitvault.Avalonia.Desktop\\bin\\Debug\\net8.0\\SQssLite.sql")
//{
// Mode = SqliteOpenMode.ReadWriteCreate,
// Password = "Test123"
//}.ToString();
//var connection = new SqliteConnection(connectionString);
//connection.Open();
//var command = connection.CreateCommand();
//command.CommandText = "SELECT quote($newPassword);";
//command.Parameters.AddWithValue("$newPassword", "Test123");
//var quotedNewPassword = (string)command.ExecuteScalar();
//command.CommandText = "PRAGMA rekey = " + quotedNewPassword;
//command.Parameters.Clear();
//command.ExecuteNonQuery();
IHost? host = DefaultHostBuilder.Create()
.AddConfiguration<VaultConfiguration>(args => args.Name = "Personal",
"Vault:*")
.ConfigureServices((context, services) =>
@@ -25,19 +46,38 @@ public partial class App : Application
services.AddAvalonia();
services.AddHandler<AppHandler>();
services.AddTransient<IVaultComponent, VaultComponent>();
services.AddTransient<IVaultFactory, VaultFactory>();
services.AddInitializer<VaultsInitializer>();
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime)
{
services.AddTemplate<MainWindowViewModel, MainWindow>("MainWindow");
}
services.AddTransient<IVaultComponent> (provider => Component.Create<VaultComponent>(provider, args =>
{
args.AddServices(services =>
{
services.AddDbContextFactory<VaultDbContext>(args =>
{
args.UseSqlite();
});
services.AddDbContextFactory<VaultDbContext>();
services.AddHandler<VaultStorageHandler>();
services.AddTemplate<AllNavigationViewModel, AllNavigationView>();
services.AddTemplate<StarredNavigationViewModel, StarredNavigationView>();
services.AddTemplate<CategoriesNavigationViewModel, CategoriesNavigationView>();
services.AddTemplate<ArchiveNavigationViewModel, ArchiveNavigationView>();
services.AddTemplate<VaultViewModel, VaultView>("Vault");
services.AddTemplate<LockViewModel, LockView>("Lock");
});
})!);
services.AddSingleton<IVaultHostCollection, VaultHostCollection>();
services.AddSingleton<IVaultFactory, VaultFactory>();
services.AddHandler<VaultHandler>();
//services.AddInitializer<VaultsInitializer>();
services.AddTemplate<MainViewModel, MainView>("Main");
services.AddTemplate<VaultNavigationViewModel, VaultNavigationView>();
@@ -17,6 +17,10 @@
<PackageReference Include="System.Reactive" Version="6.0.1-preview.1" />
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="11.1.0-beta1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0-preview.3.24172.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.0-preview.3.24172.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.1.0-beta1" />
</ItemGroup>
-22
View File
@@ -1,22 +0,0 @@
using Toolkit.Foundation;
namespace Bitvault.Avalonia;
public class VaultComponent :
IVaultComponent
{
public IComponentBuilder Create() =>
ComponentBuilder.Create()
.AddServices(services =>
{
// services.AddInitializer<VaultInitializer>();
services.AddTemplate<AllNavigationViewModel, AllNavigationView>();
services.AddTemplate<StarredNavigationViewModel, StarredNavigationView>();
services.AddTemplate<CategoriesNavigationViewModel, CategoriesNavigationView>();
services.AddTemplate<ArchiveNavigationViewModel, ArchiveNavigationView>();
services.AddTemplate<VaultViewModel, VaultView>("Vault");
services.AddTemplate<LockViewModel, LockView>("Lock");
});
}
+11 -2
View File
@@ -6,8 +6,17 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
<PackageReference Include="LiteDB" Version="5.0.19" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0-preview.3.24172.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.0-preview.3.24172.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.0-preview.3.24172.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="9.0.0-preview.3.24172.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.0-preview.3.24172.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlcipher" Version="2.1.8" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Toolkit\Toolkit.Avalonia\Toolkit.Avalonia.csproj" />
+1 -1
View File
@@ -19,6 +19,6 @@ public partial class CreateVaultViewModel(IServiceProvider provider,
public async Task<bool> Confirm()
{
return await Mediator.Handle<Create<Vault>, bool>(Create.As(new Vault(Name)));
return await Mediator.Handle<Create<Vault>, bool>(Create.As(new Vault(Name, "")));
}
}
+6 -1
View File
@@ -2,4 +2,9 @@
namespace Bitvault;
public interface IVaultComponent : IComponent;
public interface IVaultComponent : IComponent;
public class VaultComponent(IComponentBuilder builder) : Component(builder),
IVaultComponent
{
}
+3 -1
View File
@@ -4,6 +4,8 @@ namespace Bitvault
{
public interface IVaultFactory
{
IComponentHost? Create(string name, VaultConfiguration configuration);
IComponentHost? Create(string name,
string password,
VaultConfiguration configuration);
}
}
+11
View File
@@ -0,0 +1,11 @@
using System.ComponentModel.DataAnnotations;
namespace Bitvault;
public record Locker
{
[Key]
public int Id { get; set; }
public string? Name { get; set; }
}
+1 -1
View File
@@ -1,3 +1,3 @@
namespace Bitvault;
public record Vault(string Name);
public record Vault(string Name, string Password);
+13
View File
@@ -0,0 +1,13 @@
using Microsoft.EntityFrameworkCore;
namespace Bitvault;
public class VaultDbContext: DbContext
{
public DbSet<Locker> Lockers { get; set; }
public VaultDbContext(DbContextOptions<VaultDbContext> options): base(options)
{
}
}
-53
View File
@@ -1,53 +0,0 @@
using Microsoft.Extensions.DependencyInjection;
using Toolkit.Foundation;
namespace Bitvault;
public class VaultFactory(IServiceProvider provider,
IProxyServiceCollection<IComponentBuilder> proxy,
IComponentScopeCollection scopes,
IVaultHostCollection vaults) : IVaultFactory
{
public IComponentHost? Create(string name,
VaultConfiguration configuration)
{
if (provider.GetRequiredService<IVaultComponent>() is IVaultComponent component)
{
IComponentBuilder builder = component.Create();
builder.AddServices(services =>
{
services.AddTransient(_ =>
provider.GetRequiredService<IProxyService<IPublisher>>());
services.AddTransient(_ =>
provider.GetRequiredService<IProxyService<IComponentHostCollection>>());
services.AddScoped(_ =>
provider.GetRequiredService<INavigationContextCollection>());
services.AddScoped(_ =>
provider.GetRequiredService<INavigationContextProvider>());
services.AddScoped(_ =>
provider.GetRequiredService<IComponentScopeCollection>());
services.AddTransient(_ =>
provider.GetRequiredService<IComponentScopeProvider>());
services.AddRange(proxy.Services);
services.AddSingleton(new ComponentScope(name));
});
builder.AddConfiguration(name, configuration);
IComponentHost host = builder.Build();
scopes.Add(new ComponentScopeDescriptor(name,
host.Services.GetRequiredService<IServiceProvider>()));
vaults.Add(host);
return host;
}
return default;
}
}
+13 -21
View File
@@ -1,37 +1,29 @@
using LiteDB;
using Microsoft.Extensions.DependencyInjection;
using Toolkit.Foundation;
namespace Bitvault;
public class VaultStorageHandler :
IHandler<Create<VaultStorage>, bool>
{
public Task<bool> Handle(Create<VaultStorage> args, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
}
public class DatabaseFactory
{
}
public record VaultStorage(string Name);
public class VaultHandler(IVaultFactory factory) :
public class VaultHandler(IComponentFactory factory) :
IHandler<Create<Vault>, bool>
{
public async Task<bool> Handle(Create<Vault> args, CancellationToken cancellationToken)
public async Task<bool> Handle(Create<Vault> args,
CancellationToken cancellationToken)
{
if (args.Value is Vault vault)
{
if (factory.Create($"Vault:{vault.Name}", new VaultConfiguration { Name = vault.Name }) is IComponentHost host)
if (factory.Create<IVaultComponent>($"Vault:{vault.Name}", new VaultConfiguration { Name = vault.Name }) is IComponentHost host)
{
await host.StartAsync(cancellationToken);
if (host.Services.GetRequiredService<IMediator>() is IMediator mediator)
{
if (await mediator.Handle<Create<VaultStorage>, bool>(Create.As(new VaultStorage(vault.Name, vault.Password)), cancellationToken))
{
await host.StartAsync(cancellationToken);
}
}
}
}
return true;
return false;
}
}
+3
View File
@@ -0,0 +1,3 @@
namespace Bitvault;
public record VaultStorage(string Name, string Password);
+27
View File
@@ -0,0 +1,27 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Hosting;
using Toolkit.Foundation;
namespace Bitvault;
public class VaultStorageHandler(IHostEnvironment environment,
IDbContextFactory<VaultDbContext> dbContextFactory) :
IHandler<Create<VaultStorage>, bool>
{
public async Task<bool> Handle(Create<VaultStorage> args, CancellationToken cancellationToken)
{
if (args.Value is VaultStorage storage)
{
using VaultDbContext context = dbContextFactory.CreateDbContext();
await Task.Run(async () =>
{
context.Database.SetConnectionString($"Data Source={Path.Combine(environment.ContentRootPath, storage.Name)}.vault;Mode=ReadWriteCreate;Password={storage.Password}");
await context.Database.EnsureCreatedAsync(cancellationToken);
}, cancellationToken);
return true;
}
return false;
}
}
+4 -4
View File
@@ -9,10 +9,10 @@ public class VaultsInitializer(IEnumerable<IConfigurationDescriptor<VaultConfigu
{
foreach (IConfigurationDescriptor<VaultConfiguration> configuration in configurations)
{
if (factory.Create(configuration.Section, configuration.Value) is IComponentHost host)
{
await host.StartAsync();
}
//if (factory.Create(configuration.Section, configuration.Value) is IComponentHost host)
//{
// await host.StartAsync();
//}
}
}
}