enable users to have their own config file.
This commit is contained in:
@@ -15,12 +15,12 @@ namespace CarCareTracker.Controllers
|
|||||||
private readonly ILogger<HomeController> _logger;
|
private readonly ILogger<HomeController> _logger;
|
||||||
private readonly IVehicleDataAccess _dataAccess;
|
private readonly IVehicleDataAccess _dataAccess;
|
||||||
private readonly IUserLogic _userLogic;
|
private readonly IUserLogic _userLogic;
|
||||||
private readonly IConfiguration _config;
|
private readonly IConfigHelper _config;
|
||||||
|
|
||||||
public HomeController(ILogger<HomeController> logger,
|
public HomeController(ILogger<HomeController> logger,
|
||||||
IVehicleDataAccess dataAccess,
|
IVehicleDataAccess dataAccess,
|
||||||
IUserLogic userLogic,
|
IUserLogic userLogic,
|
||||||
IConfiguration configuration)
|
IConfigHelper configuration)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_dataAccess = dataAccess;
|
_dataAccess = dataAccess;
|
||||||
@@ -46,49 +46,14 @@ namespace CarCareTracker.Controllers
|
|||||||
}
|
}
|
||||||
public IActionResult Settings()
|
public IActionResult Settings()
|
||||||
{
|
{
|
||||||
var userConfig = new UserConfig
|
var userConfig = _config.GetUserConfig(User);
|
||||||
{
|
|
||||||
EnableCsvImports = bool.Parse(_config[nameof(UserConfig.EnableCsvImports)]),
|
|
||||||
UseDarkMode = bool.Parse(_config[nameof(UserConfig.UseDarkMode)]),
|
|
||||||
UseMPG = bool.Parse(_config[nameof(UserConfig.UseMPG)]),
|
|
||||||
UseDescending = bool.Parse(_config[nameof(UserConfig.UseDescending)]),
|
|
||||||
EnableAuth = bool.Parse(_config[nameof(UserConfig.EnableAuth)]),
|
|
||||||
HideZero = bool.Parse(_config[nameof(UserConfig.HideZero)]),
|
|
||||||
UseUKMPG = bool.Parse(_config[nameof(UserConfig.UseUKMPG)])
|
|
||||||
};
|
|
||||||
return PartialView("_Settings", userConfig);
|
return PartialView("_Settings", userConfig);
|
||||||
}
|
}
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public IActionResult WriteToSettings(UserConfig userConfig)
|
public IActionResult WriteToSettings(UserConfig userConfig)
|
||||||
{
|
{
|
||||||
try
|
var result = _config.SaveUserConfig(User.IsInRole(nameof(UserData.IsRootUser)), GetUserID(), userConfig);
|
||||||
{
|
return Json(result);
|
||||||
if (!System.IO.File.Exists(StaticHelper.UserConfigPath))
|
|
||||||
{
|
|
||||||
//if file doesn't exist it might be because it's running on a mounted volume in docker.
|
|
||||||
System.IO.File.WriteAllText(StaticHelper.UserConfigPath, System.Text.Json.JsonSerializer.Serialize(new UserConfig()));
|
|
||||||
}
|
|
||||||
var configFileContents = System.IO.File.ReadAllText(StaticHelper.UserConfigPath);
|
|
||||||
var existingUserConfig = System.Text.Json.JsonSerializer.Deserialize<UserConfig>(configFileContents);
|
|
||||||
if (existingUserConfig is not null)
|
|
||||||
{
|
|
||||||
//copy over settings that are off limits on the settings page.
|
|
||||||
userConfig.EnableAuth = existingUserConfig.EnableAuth;
|
|
||||||
userConfig.UserNameHash = existingUserConfig.UserNameHash;
|
|
||||||
userConfig.UserPasswordHash = existingUserConfig.UserPasswordHash;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
userConfig.EnableAuth = false;
|
|
||||||
userConfig.UserNameHash = string.Empty;
|
|
||||||
userConfig.UserPasswordHash = string.Empty;
|
|
||||||
}
|
|
||||||
System.IO.File.WriteAllText(StaticHelper.UserConfigPath, System.Text.Json.JsonSerializer.Serialize(userConfig));
|
|
||||||
return Json(true);
|
|
||||||
} catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "Error on saving config file.");
|
|
||||||
}
|
|
||||||
return Json(false);
|
|
||||||
}
|
}
|
||||||
public IActionResult Privacy()
|
public IActionResult Privacy()
|
||||||
{
|
{
|
||||||
|
|||||||
38
External/Implementations/UserConfigDataAccess.cs
vendored
Normal file
38
External/Implementations/UserConfigDataAccess.cs
vendored
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
using CarCareTracker.External.Interfaces;
|
||||||
|
using CarCareTracker.Helper;
|
||||||
|
using CarCareTracker.Models;
|
||||||
|
using LiteDB;
|
||||||
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||||
|
|
||||||
|
namespace CarCareTracker.External.Implementations
|
||||||
|
{
|
||||||
|
public class UserConfigDataAccess: IUserConfigDataAccess
|
||||||
|
{
|
||||||
|
private static string dbName = StaticHelper.DbName;
|
||||||
|
private static string tableName = "userconfigrecords";
|
||||||
|
public UserConfigData GetUserConfig(int userId)
|
||||||
|
{
|
||||||
|
using (var db = new LiteDatabase(dbName))
|
||||||
|
{
|
||||||
|
var table = db.GetCollection<UserConfigData>(tableName);
|
||||||
|
return table.FindById(userId);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public bool SaveUserConfig(UserConfigData userConfigData)
|
||||||
|
{
|
||||||
|
using (var db = new LiteDatabase(dbName))
|
||||||
|
{
|
||||||
|
var table = db.GetCollection<UserConfigData>(tableName);
|
||||||
|
return table.Upsert(userConfigData);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public bool DeleteUserConfig(int userId)
|
||||||
|
{
|
||||||
|
using (var db = new LiteDatabase(dbName))
|
||||||
|
{
|
||||||
|
var table = db.GetCollection<UserConfigData>(tableName);
|
||||||
|
return table.Delete(userId);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
External/Interfaces/IUserConfigDataAccess.cs
vendored
Normal file
11
External/Interfaces/IUserConfigDataAccess.cs
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using CarCareTracker.Models;
|
||||||
|
|
||||||
|
namespace CarCareTracker.External.Interfaces
|
||||||
|
{
|
||||||
|
public interface IUserConfigDataAccess
|
||||||
|
{
|
||||||
|
public UserConfigData GetUserConfig(int userId);
|
||||||
|
public bool SaveUserConfig(UserConfigData userConfigData);
|
||||||
|
public bool DeleteUserConfig(int userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,36 +1,104 @@
|
|||||||
using CarCareTracker.Models;
|
using CarCareTracker.External.Interfaces;
|
||||||
|
using CarCareTracker.Models;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
namespace CarCareTracker.Helper
|
namespace CarCareTracker.Helper
|
||||||
{
|
{
|
||||||
public interface IConfigHelper
|
public interface IConfigHelper
|
||||||
{
|
{
|
||||||
UserConfig GetUserConfig(bool userIsAdmin, int userId);
|
UserConfig GetUserConfig(ClaimsPrincipal user);
|
||||||
|
bool SaveUserConfig(bool isRootUser, int userId, UserConfig configData);
|
||||||
|
public bool DeleteUserConfig(int userId);
|
||||||
}
|
}
|
||||||
public class ConfigHelper : IConfigHelper
|
public class ConfigHelper : IConfigHelper
|
||||||
{
|
{
|
||||||
private readonly IConfiguration _config;
|
private readonly IConfiguration _config;
|
||||||
public ConfigHelper(IConfiguration serverConfiguration)
|
private readonly IUserConfigDataAccess _userConfig;
|
||||||
|
public ConfigHelper(IConfiguration serverConfig, IUserConfigDataAccess userConfig)
|
||||||
{
|
{
|
||||||
_config = serverConfiguration;
|
_config = serverConfig;
|
||||||
|
_userConfig = userConfig;
|
||||||
}
|
}
|
||||||
public UserConfig GetUserConfig(bool isRootUser, int userId)
|
public bool SaveUserConfig(bool isRootUser, int userId, UserConfig configData)
|
||||||
{
|
{
|
||||||
if (isRootUser)
|
if (isRootUser)
|
||||||
{
|
{
|
||||||
var serverConfig = new UserConfig
|
try
|
||||||
{
|
{
|
||||||
EnableCsvImports = bool.Parse(_config[nameof(UserConfig.EnableCsvImports)]),
|
if (!File.Exists(StaticHelper.UserConfigPath))
|
||||||
UseDarkMode = bool.Parse(_config[nameof(UserConfig.UseDarkMode)]),
|
{
|
||||||
UseMPG = bool.Parse(_config[nameof(UserConfig.UseMPG)]),
|
//if file doesn't exist it might be because it's running on a mounted volume in docker.
|
||||||
UseDescending = bool.Parse(_config[nameof(UserConfig.UseDescending)]),
|
File.WriteAllText(StaticHelper.UserConfigPath, System.Text.Json.JsonSerializer.Serialize(new UserConfig()));
|
||||||
EnableAuth = bool.Parse(_config[nameof(UserConfig.EnableAuth)]),
|
}
|
||||||
HideZero = bool.Parse(_config[nameof(UserConfig.HideZero)]),
|
var configFileContents = File.ReadAllText(StaticHelper.UserConfigPath);
|
||||||
UseUKMPG = bool.Parse(_config[nameof(UserConfig.UseUKMPG)])
|
var existingUserConfig = System.Text.Json.JsonSerializer.Deserialize<UserConfig>(configFileContents);
|
||||||
|
if (existingUserConfig is not null)
|
||||||
|
{
|
||||||
|
//copy over settings that are off limits on the settings page.
|
||||||
|
configData.EnableAuth = existingUserConfig.EnableAuth;
|
||||||
|
configData.UserNameHash = existingUserConfig.UserNameHash;
|
||||||
|
configData.UserPasswordHash = existingUserConfig.UserPasswordHash;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
configData.EnableAuth = false;
|
||||||
|
configData.UserNameHash = string.Empty;
|
||||||
|
configData.UserPasswordHash = string.Empty;
|
||||||
|
}
|
||||||
|
File.WriteAllText(StaticHelper.UserConfigPath, System.Text.Json.JsonSerializer.Serialize(configData));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
var userConfig = new UserConfigData()
|
||||||
|
{
|
||||||
|
Id = userId,
|
||||||
|
UserConfig = configData
|
||||||
};
|
};
|
||||||
|
var result = _userConfig.SaveUserConfig(userConfig);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public bool DeleteUserConfig(int userId)
|
||||||
|
{
|
||||||
|
var result = _userConfig.DeleteUserConfig(userId);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
public UserConfig GetUserConfig(ClaimsPrincipal user)
|
||||||
|
{
|
||||||
|
var serverConfig = new UserConfig
|
||||||
|
{
|
||||||
|
EnableCsvImports = bool.Parse(_config[nameof(UserConfig.EnableCsvImports)]),
|
||||||
|
UseDarkMode = bool.Parse(_config[nameof(UserConfig.UseDarkMode)]),
|
||||||
|
UseMPG = bool.Parse(_config[nameof(UserConfig.UseMPG)]),
|
||||||
|
UseDescending = bool.Parse(_config[nameof(UserConfig.UseDescending)]),
|
||||||
|
EnableAuth = bool.Parse(_config[nameof(UserConfig.EnableAuth)]),
|
||||||
|
HideZero = bool.Parse(_config[nameof(UserConfig.HideZero)]),
|
||||||
|
UseUKMPG = bool.Parse(_config[nameof(UserConfig.UseUKMPG)])
|
||||||
|
};
|
||||||
|
if (!user.Identity.IsAuthenticated)
|
||||||
|
{
|
||||||
|
return serverConfig;
|
||||||
|
}
|
||||||
|
bool isRootUser = user.IsInRole(nameof(UserData.IsRootUser));
|
||||||
|
int userId = int.Parse(user.FindFirstValue(ClaimTypes.NameIdentifier));
|
||||||
|
if (isRootUser)
|
||||||
|
{
|
||||||
return serverConfig;
|
return serverConfig;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
return new UserConfig();
|
var result = _userConfig.GetUserConfig(userId);
|
||||||
|
if (result == null)
|
||||||
|
{
|
||||||
|
return serverConfig;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
return result.UserConfig;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
11
Models/User/UserConfigData.cs
Normal file
11
Models/User/UserConfigData.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
namespace CarCareTracker.Models
|
||||||
|
{
|
||||||
|
public class UserConfigData
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// User ID
|
||||||
|
/// </summary>
|
||||||
|
public int Id { get; set; }
|
||||||
|
public UserConfig UserConfig { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@ builder.Services.AddSingleton<IUpgradeRecordDataAccess, UpgradeRecordDataAccess>
|
|||||||
builder.Services.AddSingleton<IUserRecordDataAccess, UserRecordDataAccess>();
|
builder.Services.AddSingleton<IUserRecordDataAccess, UserRecordDataAccess>();
|
||||||
builder.Services.AddSingleton<ITokenRecordDataAccess, TokenRecordDataAccess>();
|
builder.Services.AddSingleton<ITokenRecordDataAccess, TokenRecordDataAccess>();
|
||||||
builder.Services.AddSingleton<IUserAccessDataAccess, UserAccessDataAccess>();
|
builder.Services.AddSingleton<IUserAccessDataAccess, UserAccessDataAccess>();
|
||||||
|
builder.Services.AddSingleton<IUserConfigDataAccess, UserConfigDataAccess>();
|
||||||
|
|
||||||
//configure helpers
|
//configure helpers
|
||||||
builder.Services.AddSingleton<IFileHelper, FileHelper>();
|
builder.Services.AddSingleton<IFileHelper, FileHelper>();
|
||||||
@@ -28,6 +29,7 @@ builder.Services.AddSingleton<IGasHelper, GasHelper>();
|
|||||||
builder.Services.AddSingleton<IReminderHelper, ReminderHelper>();
|
builder.Services.AddSingleton<IReminderHelper, ReminderHelper>();
|
||||||
builder.Services.AddSingleton<IReportHelper, ReportHelper>();
|
builder.Services.AddSingleton<IReportHelper, ReportHelper>();
|
||||||
builder.Services.AddSingleton<IMailHelper, MailHelper>();
|
builder.Services.AddSingleton<IMailHelper, MailHelper>();
|
||||||
|
builder.Services.AddSingleton<IConfigHelper, ConfigHelper>();
|
||||||
|
|
||||||
//configure logic
|
//configure logic
|
||||||
builder.Services.AddSingleton<ILoginLogic, LoginLogic>();
|
builder.Services.AddSingleton<ILoginLogic, LoginLogic>();
|
||||||
|
|||||||
@@ -32,10 +32,13 @@
|
|||||||
<input class="form-check-input" onChange="updateSettings()" type="checkbox" role="switch" id="hideZero" checked="@Model.HideZero">
|
<input class="form-check-input" onChange="updateSettings()" type="checkbox" role="switch" id="hideZero" checked="@Model.HideZero">
|
||||||
<label class="form-check-label" for="hideZero">Replace @(0.ToString("C")) Costs with ---</label>
|
<label class="form-check-label" for="hideZero">Replace @(0.ToString("C")) Costs with ---</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check form-switch">
|
@if (User.IsInRole(nameof(UserData.IsRootUser)))
|
||||||
<input class="form-check-input" onChange="enableAuthCheckChanged()" type="checkbox" role="switch" id="enableAuth" checked="@Model.EnableAuth">
|
{
|
||||||
<label class="form-check-label" for="enableAuth">Enable Authentication</label>
|
<div class="form-check form-switch">
|
||||||
</div>
|
<input class="form-check-input" onChange="enableAuthCheckChanged()" type="checkbox" role="switch" id="enableAuth" checked="@Model.EnableAuth">
|
||||||
|
<label class="form-check-label" for="enableAuth">Enable Authentication</label>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
<!DOCTYPE html>
|
@using CarCareTracker.Helper
|
||||||
@inject IConfiguration Configuration
|
<!DOCTYPE html>
|
||||||
|
@inject IConfigHelper config
|
||||||
@{
|
@{
|
||||||
var useDarkMode = bool.Parse(Configuration["UseDarkMode"]);
|
var userConfig = config.GetUserConfig(User);
|
||||||
var enableCsvImports = bool.Parse(Configuration["EnableCsvImports"]);
|
var useDarkMode = userConfig.UseDarkMode;
|
||||||
|
var enableCsvImports = userConfig.EnableCsvImports;
|
||||||
var shortDatePattern = System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern;
|
var shortDatePattern = System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern;
|
||||||
shortDatePattern = shortDatePattern.ToLower();
|
shortDatePattern = shortDatePattern.ToLower();
|
||||||
if (!shortDatePattern.Contains("dd"))
|
if (!shortDatePattern.Contains("dd"))
|
||||||
|
|||||||
Reference in New Issue
Block a user