171 lines
6.4 KiB
C#
171 lines
6.4 KiB
C#
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using Microsoft.AspNetCore.Mvc.Filters;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using MySql.Data.MySqlClient;
|
|
using System.Text.Json;
|
|
using Aberwyn.Data;
|
|
using Aberwyn.Models;
|
|
|
|
namespace Aberwyn.Controllers
|
|
{
|
|
[Route("setup")]
|
|
public class SetupController : Controller
|
|
{
|
|
private readonly IWebHostEnvironment _env;
|
|
private readonly ILogger<SetupController> _logger;
|
|
|
|
public SetupController(IWebHostEnvironment env, ILogger<SetupController> logger)
|
|
{
|
|
_env = env;
|
|
_logger = logger;
|
|
}
|
|
|
|
public override void OnActionExecuting(ActionExecutingContext context)
|
|
{
|
|
ViewBag.IsSetupMode = true;
|
|
base.OnActionExecuting(context);
|
|
}
|
|
|
|
[HttpGet]
|
|
public IActionResult Index() => View(new SetupSettings());
|
|
|
|
[Authorize(Roles = "Admin")]
|
|
[HttpPost("reset")]
|
|
public IActionResult Reset()
|
|
{
|
|
var path = Path.Combine(_env.ContentRootPath, "infrastructure", "setup.json");
|
|
|
|
var resetSettings = new SetupSettings
|
|
{
|
|
IsConfigured = false,
|
|
DbHost = "",
|
|
DbPort = 3306,
|
|
DbName = "",
|
|
DbUser = "",
|
|
DbPassword = "",
|
|
AdminUsername = "admin",
|
|
AdminEmail = "admin@localhost",
|
|
AdminPassword = "Admin123!"
|
|
};
|
|
|
|
var json = JsonSerializer.Serialize(resetSettings, new JsonSerializerOptions { WriteIndented = true });
|
|
System.IO.File.WriteAllText(path, json);
|
|
|
|
return RedirectToAction("Index");
|
|
}
|
|
|
|
[HttpPost("")]
|
|
public async Task<IActionResult> Setup([FromBody] SetupSettings model)
|
|
{
|
|
if (!ModelState.IsValid)
|
|
{
|
|
var allErrors = ModelState
|
|
.Where(e => e.Value.Errors.Count > 0)
|
|
.Select(e => new { Field = e.Key, Errors = e.Value.Errors.Select(x => x.ErrorMessage) });
|
|
|
|
return BadRequest(new { error = "Modellen är ogiltig", details = allErrors });
|
|
}
|
|
|
|
try
|
|
{
|
|
// Bygg connection string säkert
|
|
var baseConnBuilder = new MySqlConnectionStringBuilder
|
|
{
|
|
Server = model.DbHost,
|
|
Port = (uint)model.DbPort,
|
|
UserID = model.DbUser,
|
|
Password = model.DbPassword,
|
|
Database = "information_schema"
|
|
};
|
|
|
|
// Kontrollera om databasen redan finns
|
|
using (var conn = new MySqlConnection(baseConnBuilder.ConnectionString))
|
|
{
|
|
conn.Open();
|
|
var cmd = new MySqlCommand("SELECT SCHEMA_NAME FROM SCHEMATA WHERE SCHEMA_NAME = @dbName", conn);
|
|
cmd.Parameters.AddWithValue("@dbName", model.DbName);
|
|
var exists = cmd.ExecuteScalar();
|
|
|
|
if (exists == null)
|
|
{
|
|
try
|
|
{
|
|
var createCmd = new MySqlCommand($"CREATE DATABASE `{model.DbName}`", conn);
|
|
createCmd.ExecuteNonQuery();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Kunde inte skapa databasen.");
|
|
return BadRequest(new { error = "Databasen finns inte och kunde inte skapas.", details = ex.Message });
|
|
}
|
|
}
|
|
}
|
|
|
|
// Bygg EF-connection
|
|
var efConnBuilder = new MySqlConnectionStringBuilder
|
|
{
|
|
Server = model.DbHost,
|
|
Port = (uint)model.DbPort,
|
|
UserID = model.DbUser,
|
|
Password = model.DbPassword,
|
|
Database = model.DbName
|
|
};
|
|
|
|
var tempProvider = SetupService.BuildTemporaryServices(efConnBuilder.ConnectionString);
|
|
using var scope = tempProvider.CreateScope();
|
|
|
|
// Skapa databastabeller
|
|
var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
|
await db.Database.MigrateAsync();
|
|
|
|
// Sätt konfig-flagga tidigt
|
|
model.IsConfigured = true;
|
|
|
|
// Spara setup.json
|
|
var filePath = Path.Combine(_env.ContentRootPath, "infrastructure", "setup.json");
|
|
var json = JsonSerializer.Serialize(model, new JsonSerializerOptions { WriteIndented = true });
|
|
System.IO.File.WriteAllText(filePath, json);
|
|
|
|
// Roller och admin
|
|
var userManager = scope.ServiceProvider.GetRequiredService<UserManager<ApplicationUser>>();
|
|
var roleManager = scope.ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>();
|
|
|
|
string[] roles = { "Admin", "Chef", "Budget" };
|
|
foreach (var role in roles)
|
|
{
|
|
if (!await roleManager.RoleExistsAsync(role))
|
|
await roleManager.CreateAsync(new IdentityRole(role));
|
|
}
|
|
|
|
var existingUser = await userManager.FindByNameAsync(model.AdminUsername);
|
|
if (existingUser == null)
|
|
{
|
|
var adminUser = new ApplicationUser
|
|
{
|
|
UserName = model.AdminUsername,
|
|
Email = model.AdminEmail,
|
|
EmailConfirmed = true
|
|
};
|
|
|
|
var result = await userManager.CreateAsync(adminUser, model.AdminPassword);
|
|
if (!result.Succeeded)
|
|
return BadRequest(new { error = "Kunde inte skapa administratör", details = result.Errors });
|
|
|
|
await userManager.AddToRoleAsync(adminUser, "Admin");
|
|
}
|
|
|
|
return Ok(new { message = "Installation slutförd!" });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Fel vid installation.");
|
|
return BadRequest(new { error = "Fel vid installation", details = ex.Message });
|
|
}
|
|
}
|
|
|
|
public IActionResult SetupComplete() => View();
|
|
}
|
|
}
|