feat(admincli): add command for creating a user

This commit is contained in:
Stevan Freeborn
2026-02-03 04:38:40 -06:00
parent 0ce97cdec8
commit fcc1356d69
11 changed files with 114 additions and 14 deletions
+1
View File
@@ -1,3 +1,4 @@
[*.cs]
dotnet_diagnostic.CA1303.severity = none
dotnet_diagnostic.CA2007.severity = none
+52
View File
@@ -0,0 +1,52 @@
namespace FiscalOS.AdminCLI;
internal sealed class App(
IAnsiConsole console,
IPasswordHasher passwordHasher,
IServiceScopeFactory serviceScopeFactory
) : IHostedService
{
private readonly IAnsiConsole _console = console;
private readonly IServiceScopeFactory _serviceScopeFactory = serviceScopeFactory;
public async Task StartAsync(CancellationToken cancellationToken)
{
using var scope = _serviceScopeFactory.CreateScope();
var config = scope.ServiceProvider.GetRequiredService<IConfiguration>();
var appDbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
var selectionPrompt = new SelectionPrompt<string>()
.Title("What do you want to do?")
.AddChoices(Commands.All);
var command = await _console.PromptAsync(selectionPrompt, cancellationToken);
switch (command)
{
case Commands.CreateUser:
var username = await _console.AskAsync<string>("Enter the [green]username[/]:", cancellationToken);
var password = _console.Prompt(
new TextPrompt<string>("Enter the [green]password[/]:")
.PromptStyle("red")
.Secret()
);
var hashedPassword = passwordHasher.Hash(password);
var user = User.From(username, hashedPassword);
await appDbContext.Users.AddAsync(user, cancellationToken);
await appDbContext.SaveChangesAsync(cancellationToken);
_console.MarkupLine($"User [green]{username}[/] created successfully.");
break;
case Commands.Exit:
default:
break;
}
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}
+9
View File
@@ -0,0 +1,9 @@
namespace FiscalOS.AdminCLI;
internal static class Commands
{
public const string CreateUser = "Create User";
public const string Exit = "Exit";
public static readonly string[] All = [CreateUser, Exit];
}
@@ -4,4 +4,20 @@
<OutputType>Exe</OutputType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" />
<PackageReference Include="Spectre.Console" />
</ItemGroup>
<ItemGroup>
<None Update="appsettings*.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FiscalOS.Infra\FiscalOS.Infra.csproj" />
<ProjectReference Include="..\FiscalOS.Core\FiscalOS.Core.csproj" />
</ItemGroup>
</Project>
+15 -11
View File
@@ -1,11 +1,15 @@
// TODO: We need a way to add
// a user to the system with
// a properly hashed password
// so need something like this:
//
// 1. Ask for username
// 2. Ask for user password
// 3. Hash user password
// 4. Save user to database
Console.WriteLine("Hello, World!");
await Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration(
static c => c.SetBasePath(AppContext.BaseDirectory)
.AddJsonFile("appsettings.json")
.AddEnvironmentVariables()
)
.ConfigureLogging(static c => c.ClearProviders())
.ConfigureServices(static (_, services) =>
{
services.AddSingleton(AnsiConsole.Console);
services.AddInfrastructure();
services.AddHostedService<App>();
})
.Build()
.StartAsync();
+12
View File
@@ -0,0 +1,12 @@
global using FiscalOS.AdminCLI;
global using FiscalOS.Core.Authentication;
global using FiscalOS.Core.Identity;
global using FiscalOS.Infra.Data;
global using FiscalOS.Infra.DependencyInjection;
global using Microsoft.Extensions.Configuration;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.Hosting;
global using Microsoft.Extensions.Logging;
global using Spectre.Console;
@@ -0,0 +1,5 @@
{
"AppDbContextOptions": {
"DatabaseFilePath": "DatabaseFilePath"
}
}