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 Server; public class CreateLog : Route { private static string secretKey = "stronk-key-much-sercret-much-more-stronk-stronk-key-much-sercret-much-more-stronk"; 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; } } public static void HandleRequest( HttpListenerRequest request, HttpListenerResponse response, HttpListenerContext context ) { try { // check header var headers = request.Headers; string? token = headers["token"]; if (!string.IsNullOrEmpty(token) && !ValidateToken(token)) { throw new Exception("Invalid token"); } // prepare SQL query MySqlCommand cmd = new MySqlCommand(); // extact data from body string body; using ( StreamReader bodyReader = new StreamReader( 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 // validate time if (!int.TryParse(time, out int myInt) || myInt < 0 || myInt > 8) throw new Exception("Incorect ammount of hours"); // validate date Regex regex = new Regex(@"^\d{4}-\d{2}-\d{2}$"); if (string.IsNullOrEmpty(date) || !regex.IsMatch(date)) { throw new Exception("Incorrect date format"); } // validate user // extract user from jwt var handler = new JwtSecurityTokenHandler(); var jwtToken = handler.ReadJwtToken(token); string? usernameClaim = jwtToken.Claims.FirstOrDefault(c => c.Type == "user")?.Value ?? ""; 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"); } using (MySqlConnection conn = new MySqlConnection(connectionString)) { conn.Open(); cmd.Connection = conn; cmd.CommandText = @"INSERT INTO Timelog(user,project,date,time) VALUES(@user,@project,@date,@time);"; cmd.Parameters.AddWithValue("@user", usernameClaim); cmd.Parameters.AddWithValue("@project", project); cmd.Parameters.AddWithValue("@time", time); cmd.Parameters.AddWithValue("@date", date); // execute query and read results cmd.ExecuteNonQuery(); SendSuccess(response); } } catch (Exception ex) { SendError(response, ex); } } }