Files
timelog/backendCS/routes/CreateLog.cs
T
2024-12-09 18:43:03 +02:00

135 lines
4.2 KiB
C#

using System.IdentityModel.Tokens.Jwt;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.IdentityModel.Tokens;
using MySql.Data.MySqlClient;
using Newtonsoft.Json.Linq;
namespace TimelogBackend;
public class CreateLog : Route
{
private static readonly string secretKey =
"stronk-key-much-sercret-much-more-stronk-stronk-key-much-sercret-much-more-stronk";
public static void HandleRequest(HttpListenerRequest request, HttpListenerResponse response)
{
try
{
// check header
var headers = request.Headers;
string token = headers["token"] ?? "";
if (!string.IsNullOrEmpty(token) && !ValidateToken(token))
{
throw new Exception("Invalid token");
}
MySqlCommand cmd = new();
string body;
using (StreamReader bodyReader = new(request.InputStream, request.ContentEncoding))
{
body = bodyReader.ReadToEnd();
}
JObject jsonObject = JObject.Parse(body);
string project = jsonObject["project"]?.ToString() ?? "";
string time = jsonObject["time"]?.ToString() ?? "";
string date = jsonObject["date"]?.ToString() ?? "";
// TODO check if the hours on given date don't combine to more
// than 8
if (!ValidateTime(time))
{
throw new Exception("Incorrect date format");
}
if (!ValidateDate(date))
{
throw new Exception("Incorrect date format");
}
// validate user
string? usernameClaim = GetUserFromToken(token);
if (string.IsNullOrEmpty(usernameClaim))
{
throw new Exception("wrong user id");
}
// validate project
// TODO better project validation
if (string.IsNullOrEmpty(project))
{
throw new Exception("wrong project");
}
SaveTimeLogToDatabase(usernameClaim, project, date, time);
SendSuccess(response);
}
catch (Exception ex)
{
SendError(response, ex);
}
}
private static bool ValidateToken(string token)
{
try
{
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey));
var tokenHandler = new JwtSecurityTokenHandler();
var validationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidIssuer = "TimeLogServer",
ValidAudience = "TimeLogWebsite",
IssuerSigningKey = key,
};
var principal = tokenHandler.ValidateToken(
token,
validationParameters,
out SecurityToken validatedToken
);
return validatedToken != null;
}
catch
{
return false;
}
}
private static bool ValidateTime(string time)
{
return int.TryParse(time, out int myInt) && myInt >= 0 && myInt <= 8;
}
private static string GetUserFromToken(string token)
{
var handler = new JwtSecurityTokenHandler();
var jwtToken = handler.ReadJwtToken(token);
string? usernameClaim = jwtToken.Claims.FirstOrDefault(c => c.Type == "user")?.Value;
return string.IsNullOrEmpty(usernameClaim) ? "" : usernameClaim;
}
private static void SaveTimeLogToDatabase(
string username,
string project,
string date,
string time
)
{
using MySqlConnection conn = new(connectionString);
conn.Open();
using MySqlCommand cmd = new(
@"INSERT INTO Timelog(user, project, date, time)
VALUES(@user, @project, @date, @time);",
conn
);
cmd.Parameters.AddWithValue("@user", username);
cmd.Parameters.AddWithValue("@project", project);
cmd.Parameters.AddWithValue("@date", date);
cmd.Parameters.AddWithValue("@time", time);
cmd.ExecuteNonQuery();
}
}