using System.Text.Json; using System.Text.RegularExpressions; namespace perubahan; public static partial class APIHandler { public static void Handle(IApplicationBuilder App) { App //============MISC================= .Map("/updatecache",cache=>{ cache.Run(async runner=>{ _ = await UpdateCache(); await WriteJsonResponse(runner,StatusCodes.Status200OK,"Cache Updated."); }); }) //===========UNITS================= .Map("/getunits", units =>{ units.Run(async runner=>{ if (!await RequestValidated(runner,2)) return; await WriteJsonResponse(runner,StatusCodes.Status200OK,"Success",Deployments); }); }) .Map("/chunit", unit =>{ unit.Run(async runner=>{ if (!await RequestValidated(runner, 2, "POST", true)) return; if(await TryGetBodyJsonAsync(runner, ["deplid", "unitkerja"], CTS.Token) is Dictionary InElement) { Deployment CorrectDeployment = new( InElement["deplid"].GetInt16(), InElement["unitkerja"].GetString() ?? "" ); if (CorrectDeployment.UnitKerja.Length < 1) { await WriteJsonResponse(runner,StatusCodes.Status400BadRequest, "Unit Kerja can't be empty string."); return; } int i = Deployments.FindIndex(depl=>depl.DeplID == CorrectDeployment.DeplID); if(i<0) { await WriteJsonResponse(runner,StatusCodes.Status404NotFound,"Deployment ID not found."); return; } _ = await RunNonQueryAsync(CS,"UPDATE deployment SET unitkerja = @uk WHERE deplid = @id",Comm=>{ Comm.Parameters.AddWithValue("@id", CorrectDeployment.DeplID); Comm.Parameters.AddWithValue("@uk", CorrectDeployment.UnitKerja); },CTS.Token); Deployments[i] = CorrectDeployment; await WriteJsonResponse(runner,StatusCodes.Status202Accepted,"Data updated.",Deployments[i]); } }); }) .Map("/addunit", unit =>{ unit.Run(async runner=>{ if (!await RequestValidated(runner, 2, "POST", true)) return; if(await TryGetBodyJsonAsync(runner, ["unitkerja"], CTS.Token) is Dictionary InElement) { string UnitKerja = InElement["unitkerja"].GetString() ?? ""; if (UnitKerja.Length < 1) { await WriteJsonResponse(runner,StatusCodes.Status400BadRequest, "Unit Kerja can't be empty string."); return; } short DeplID = (short)await RunScalarAsync(CS,"INSERT INTO deployment OUTPUT INSERTED.deplid VALUES (@uk)",Comm=>{ Comm.Parameters.AddWithValue("@uk", UnitKerja); },CTS.Token); Deployment Inserted = new(DeplID,UnitKerja); Deployments.Add(Inserted); // EventsMarker.CacheUpdates = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString("X"); await WriteJsonResponse(runner,StatusCodes.Status201Created,"Data Created.",Inserted); } }); }) //============AGENTS============== .Map("/getagents", agents=>{ agents.Run(async runner=>{ if (!await RequestValidated(runner,2)) return; await WriteJsonResponse(runner,StatusCodes.Status200OK,"Success",Agents); }); }) .Map("/addagent", agent=>{ agent.Run(async runner=>{ if (!await RequestValidated(runner, 1, "POST", true)) return; if (await TryGetBodyJsonAsync(runner, ["agentid", "name", "jabatan", "deplid", "skangkat", "tmt", "skper", "tgper", "vision", "mission", "photo", "createuser", "uname", "pass", "level"], CTS.Token) is Dictionary InElement) { string AgentID = InElement["agentid"].GetString() ?? string.Empty; string Name = InElement["nama"].GetString() ?? string.Empty; string Jabatan = InElement["jabatan"].GetString() ?? string.Empty; short DeploymentID = InElement["deplid"].GetInt16(); string SKAngkat = InElement["skangkat"].GetString() ?? string.Empty; DateTime TMT = DateTime.Parse(InElement["tmt"].GetString() ?? "1970-01-01"); string SKPer = InElement["skper"].GetString() ?? string.Empty; DateTime? TGPer = InElement["tgper"].GetString()?.Length > 0 ? DateTime.Parse(InElement["tgper"].GetString()!) : null; string Vision = InElement["vision"].GetString() ?? "-"; string Mission = InElement["mission"].GetString() ?? "-"; string Photo = InElement["photo"].GetString() ?? string.Empty; string PhotoURL = string.Empty; bool CreateUser = InElement["createuser"].GetBoolean(); string UName = InElement["uname"].GetString() ?? string.Empty; string PlainPass = InElement["pass"].GetString() ?? string.Empty; byte Level = InElement["level"].GetByte(); Match PhotoMatch = Base64Regex().Match(Photo.ToLower()); if (AgentID.Equals(string.Empty) || Name.Equals(string.Empty) || Jabatan.Equals(string.Empty) || DeploymentID.Equals(0) || SKAngkat.Equals(string.Empty) || TMT.Equals(DateOnly.Parse("1970-01-01")) || (!SKPer.Equals(string.Empty) && TGPer is null) || (CreateUser && UName.Equals(string.Empty)) || (CreateUser && PlainPass.Equals(string.Empty)) || (!Photo.Equals(string.Empty) && !PhotoMatch.Success) || (await RequestValidated(runner, Level, "POST"))) { await WriteJsonResponse(runner, StatusCodes.Status400BadRequest, "One or more input(s) are not acceptable, in an unsupported format, or an attempt to create user account of a higher level than the creator is made."); return; } if (!Photo.Equals(string.Empty)) { string Format = PhotoMatch.Groups["format"].Value.ToLowerInvariant(); string Data = PhotoMatch.Groups["data"].Value; byte[] ImageBytes = Convert.FromBase64String(Data); uint CRC32Hash = Crc32.Compute(ImageBytes); string PhotoFileName = $"{CRC32Hash:X8}.{(Format == "jpeg" ? "jpg" : Format)}"; string PhotoPath = Path.Combine(AppContext.BaseDirectory, "/wwwroot/assets/images/uploads", PhotoFileName); if (!File.Exists(PhotoPath)) await File.WriteAllBytesAsync(PhotoPath, ImageBytes, CTS.Token); PhotoURL = Path.Combine("/assets/images/uploads", PhotoFileName); } await RunTransactionAsync(CS, async (Conn, Trans) => { using (SqlCommand CreateAgent = Conn.CreateCommand()) { CreateAgent.Transaction = Trans; CreateAgent.CommandText = "INSERT INTO agents VALUE(@agid, @nama, @jabt, @deid, @skng, @tmt, @skpr, @tmpr, @visi, @misi, @poto)"; CreateAgent.Parameters.AddWithValue("@agid", AgentID); CreateAgent.Parameters.AddWithValue("@nama", Name); CreateAgent.Parameters.AddWithValue("@jabt", Jabatan); CreateAgent.Parameters.AddWithValue("@deid", DeploymentID); CreateAgent.Parameters.AddWithValue("@skng", SKAngkat); CreateAgent.Parameters.AddWithValue("@tmt", TMT); CreateAgent.Parameters.AddWithValue("@skpr", SKPer.Equals(string.Empty) ? DBNull.Value : SKPer); CreateAgent.Parameters.AddWithValue("@tmpr", SKPer.Equals(string.Empty) ? DBNull.Value : TGPer); CreateAgent.Parameters.AddWithValue("@visi", Vision); CreateAgent.Parameters.AddWithValue("@misi", Mission); CreateAgent.Parameters.AddWithValue("@poto", PhotoURL.Equals(string.Empty) ? DBNull.Value : PhotoURL); _ = await CreateAgent.ExecuteNonQueryAsync(); } if (CreateUser) { string HashedPass = Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(PlainPass))); using (SqlCommand CreateUser = Conn.CreateCommand()) { CreateUser.Transaction = Trans; CreateUser.CommandText = "INSERT INTO useraccounts VALUES(@unam, @pass, @agid, @levl, 1)"; CreateUser.Parameters.AddWithValue("@unam", UName); CreateUser.Parameters.AddWithValue("@pass", HashedPass); CreateUser.Parameters.AddWithValue("@agid", AgentID); CreateUser.Parameters.AddWithValue("@levl", Level); _ = await CreateUser.ExecuteNonQueryAsync(); } } }, CTS.Token ); string OutMessage = CreateUser ? "New Agent and respective User Account created" : "New Agent created. User account creation is possible."; await WriteJsonResponse(runner, StatusCodes.Status201Created, OutMessage); } }); }) ; } }