mirror of
https://github.com/hargata/lubelog.git
synced 2026-02-03 17:53:02 -06:00
add migration and api key based auth method.
This commit is contained in:
parent
9403ea437e
commit
05aa49171f
@ -56,7 +56,8 @@ namespace CarCareTracker.Controllers
|
||||
"CREATE TABLE IF NOT EXISTS app.inspectionrecords (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)",
|
||||
"CREATE TABLE IF NOT EXISTS app.inspectionrecordtemplates (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)",
|
||||
"CREATE TABLE IF NOT EXISTS app.equipmentrecords (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)",
|
||||
"CREATE TABLE IF NOT EXISTS app.userhouseholdrecords (parentUserId INT, childUserId INT, data jsonb not null, PRIMARY KEY(parentUserId, childUserId))"
|
||||
"CREATE TABLE IF NOT EXISTS app.userhouseholdrecords (parentUserId INT, childUserId INT, data jsonb not null, PRIMARY KEY(parentUserId, childUserId))",
|
||||
"CREATE TABLE IF NOT EXISTS app.apikeyrecords (id INT GENERATED BY DEFAULT AS IDENTITY primary key, userId INT not null, apiKey TEXT not null, data jsonb not null)"
|
||||
};
|
||||
foreach(string cmd in cmds)
|
||||
{
|
||||
@ -108,6 +109,7 @@ namespace CarCareTracker.Controllers
|
||||
var equipmentrecords = new List<EquipmentRecord>();
|
||||
|
||||
var userhouseholdrecords = new List<UserHousehold>();
|
||||
var apikeyrecords = new List<APIKey>();
|
||||
#region "Part1"
|
||||
string cmd = $"SELECT data FROM app.vehicles";
|
||||
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||
@ -499,6 +501,25 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
;
|
||||
}
|
||||
cmd = $"SELECT data FROM app.apikeyrecords";
|
||||
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||
{
|
||||
using (NpgsqlDataReader reader = ctext.ExecuteReader())
|
||||
while (reader.Read())
|
||||
{
|
||||
APIKey result = JsonSerializer.Deserialize<APIKey>(reader["data"] as string);
|
||||
apikeyrecords.Add(result);
|
||||
}
|
||||
}
|
||||
foreach (var record in apikeyrecords)
|
||||
{
|
||||
using (var db = new LiteDatabase(fullFileName))
|
||||
{
|
||||
var table = db.GetCollection<APIKey>("apikeyrecords");
|
||||
table.Upsert(record);
|
||||
}
|
||||
;
|
||||
}
|
||||
#endregion
|
||||
var destFilePath = $"{fullFolderPath}.zip";
|
||||
ZipFile.CreateFromDirectory(fullFolderPath, destFilePath);
|
||||
@ -552,6 +573,7 @@ namespace CarCareTracker.Controllers
|
||||
var equipmentrecords = new List<EquipmentRecord>();
|
||||
|
||||
var userhouseholdrecords = new List<UserHousehold>();
|
||||
var apikeyrecords = new List<APIKey>();
|
||||
#region "Part1"
|
||||
using (var db = new LiteDatabase(fullFileName))
|
||||
{
|
||||
@ -899,6 +921,24 @@ namespace CarCareTracker.Controllers
|
||||
ctext.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
using (var db = new LiteDatabase(fullFileName))
|
||||
{
|
||||
var table = db.GetCollection<APIKey>("apikeyrecords");
|
||||
apikeyrecords = table.FindAll().ToList();
|
||||
}
|
||||
;
|
||||
foreach (var record in apikeyrecords)
|
||||
{
|
||||
string cmd = $"INSERT INTO app.apikeyrecords (id, userId, apiKey, data) VALUES(@id, @userId, @apiKey, CAST(@data AS jsonb)); SELECT setval('app.apikeyrecords_id_seq', (SELECT MAX(id) from app.apikeyrecords));";
|
||||
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||
{
|
||||
ctext.Parameters.AddWithValue("id", record.Id);
|
||||
ctext.Parameters.AddWithValue("userId", record.UserId);
|
||||
ctext.Parameters.AddWithValue("apiKey", record.Key);
|
||||
ctext.Parameters.AddWithValue("data", JsonSerializer.Serialize(record));
|
||||
ctext.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
return Json(OperationResponse.Succeed("Data Imported Successfully"));
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@ namespace CarCareTracker.Logic
|
||||
OperationResponse SendRegistrationToken(LoginModel credentials);
|
||||
UserData ValidateUserCredentials(LoginModel credentials);
|
||||
UserData ValidateOpenIDUser(LoginModel credentials);
|
||||
UserData ValidateAPIKey(string apiKey);
|
||||
bool CheckIfUserIsValid(int userId);
|
||||
bool CreateRootUserCredentials(LoginModel credentials);
|
||||
bool DeleteRootUserCredentials();
|
||||
@ -36,17 +37,20 @@ namespace CarCareTracker.Logic
|
||||
{
|
||||
private readonly IUserRecordDataAccess _userData;
|
||||
private readonly ITokenRecordDataAccess _tokenData;
|
||||
private readonly IApiKeyRecordDataAccess _apiKeyData;
|
||||
private readonly IMailHelper _mailHelper;
|
||||
private readonly IConfigHelper _configHelper;
|
||||
private IMemoryCache _cache;
|
||||
public LoginLogic(IUserRecordDataAccess userData,
|
||||
ITokenRecordDataAccess tokenData,
|
||||
IApiKeyRecordDataAccess apiKeyData,
|
||||
IMailHelper mailHelper,
|
||||
IConfigHelper configHelper,
|
||||
IMemoryCache memoryCache)
|
||||
{
|
||||
_userData = userData;
|
||||
_tokenData = tokenData;
|
||||
_apiKeyData = apiKeyData;
|
||||
_mailHelper = mailHelper;
|
||||
_configHelper = configHelper;
|
||||
_cache = memoryCache;
|
||||
@ -293,6 +297,26 @@ namespace CarCareTracker.Logic
|
||||
return new UserData();
|
||||
}
|
||||
}
|
||||
public UserData ValidateAPIKey(string apiKey)
|
||||
{
|
||||
var hashedAPIKey = StaticHelper.GetHash(apiKey);
|
||||
var apiKeyUser = _apiKeyData.GetAPIKeyByKey(hashedAPIKey);
|
||||
if (apiKeyUser.UserId != default)
|
||||
{
|
||||
if (apiKeyUser.UserId == -1)
|
||||
{
|
||||
var rootUserData = GetRootUserData(apiKeyUser.Name);
|
||||
return rootUserData;
|
||||
}
|
||||
var result = _userData.GetUserRecordById(apiKeyUser.UserId);
|
||||
if (result.Id != default)
|
||||
{
|
||||
result.Password = string.Empty;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return new UserData();
|
||||
}
|
||||
#region "Admin Functions"
|
||||
public bool MakeUserAdmin(int userId, bool isAdmin)
|
||||
{
|
||||
|
||||
@ -53,7 +53,13 @@ namespace CarCareTracker.Middleware
|
||||
var access_token = _httpContext.HttpContext.Request.Cookies[StaticHelper.LoginCookieName];
|
||||
//auth using Basic Auth for API.
|
||||
var request_header = _httpContext.HttpContext.Request.Headers["Authorization"];
|
||||
if (string.IsNullOrWhiteSpace(access_token) && string.IsNullOrWhiteSpace(request_header))
|
||||
//auth using API Key for API.
|
||||
var apikey_header = _httpContext.HttpContext.Request.Headers["x-api-key"];
|
||||
if (string.IsNullOrWhiteSpace(apikey_header))
|
||||
{
|
||||
apikey_header = _httpContext.HttpContext.Request.Query["apiKey"];
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(access_token) && string.IsNullOrWhiteSpace(request_header) && string.IsNullOrWhiteSpace(apikey_header))
|
||||
{
|
||||
return AuthenticateResult.Fail("Cookie is invalid or does not exist.");
|
||||
}
|
||||
@ -146,20 +152,45 @@ namespace CarCareTracker.Middleware
|
||||
{
|
||||
return AuthenticateResult.Fail("Corrupted credentials");
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(apikey_header) && _httpContext.HttpContext.Request.Path.StartsWithSegments("/api"))
|
||||
{
|
||||
//only do API Key Auth for API methods
|
||||
var userData = _loginLogic.ValidateAPIKey(apikey_header);
|
||||
if (userData.Id != default)
|
||||
{
|
||||
var appIdentity = new ClaimsIdentity("Custom");
|
||||
var userIdentity = new List<Claim>
|
||||
{
|
||||
new(ClaimTypes.Name, userData.UserName),
|
||||
new(ClaimTypes.NameIdentifier, userData.Id.ToString()),
|
||||
new(ClaimTypes.Email, userData.EmailAddress),
|
||||
new(ClaimTypes.Role, "APIAuth"),
|
||||
new(ClaimTypes.Role, "APIKeyAuth")
|
||||
};
|
||||
if (userData.IsAdmin)
|
||||
{
|
||||
userIdentity.Add(new(ClaimTypes.Role, nameof(UserData.IsAdmin)));
|
||||
}
|
||||
if (userData.IsRootUser)
|
||||
{
|
||||
userIdentity.Add(new(ClaimTypes.Role, nameof(UserData.IsRootUser)));
|
||||
}
|
||||
appIdentity.AddClaims(userIdentity);
|
||||
AuthenticationTicket ticket = new AuthenticationTicket(new ClaimsPrincipal(appIdentity), Scheme.Name);
|
||||
return AuthenticateResult.Success(ticket);
|
||||
}
|
||||
}
|
||||
return AuthenticateResult.Fail("Invalid credentials");
|
||||
}
|
||||
}
|
||||
protected override Task HandleChallengeAsync(AuthenticationProperties properties)
|
||||
{
|
||||
if (Request.RouteValues.TryGetValue("controller", out object value))
|
||||
if (Request.RouteValues.TryGetValue("controller", out object value) && value?.ToString()?.ToLower() == "api")
|
||||
{
|
||||
if (value.ToString().ToLower() == "api")
|
||||
{
|
||||
Response.StatusCode = 401;
|
||||
Response.Headers.Append("WWW-Authenticate", "Basic");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
Response.StatusCode = 401;
|
||||
Response.Headers.Append("WWW-Authenticate", "Basic");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
if (Request.Path.Value == "/Vehicle/Index" && Request.QueryString.HasValue)
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user