135 lines
4.2 KiB
C#
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();
|
|
}
|
|
}
|