using Newtonsoft.Json.Linq; using OI.Metrology.Shared.DataModels; using OI.Metrology.Shared.Models; using OI.Metrology.Shared.Models.Stateless; using OI.Metrology.Shared.Services; using System.Net; namespace OI.Metrology.Viewer.Repository; public class InboundRepository : IInboundRepository { private readonly Serilog.ILogger _Log; public InboundRepository() => _Log = Serilog.Log.ForContext(); bool IInboundRepository.IsIPAddressAllowed(string inboundApiAllowedIPList, IPAddress? remoteIP) { if (string.IsNullOrWhiteSpace(inboundApiAllowedIPList)) return true; if (remoteIP is null) return false; byte[] remoteIPBytes = remoteIP.GetAddressBytes(); string[] allowedIPs = inboundApiAllowedIPList.Split(';'); foreach (string ip in allowedIPs) { IPAddress? parsedIP; if (IPAddress.TryParse(ip, out parsedIP)) { if (parsedIP.GetAddressBytes().SequenceEqual(remoteIPBytes)) return true; } } return false; } // this is the main endpoint, it accepts a JSON message that contains both the header and data records together // tooltype is the ToolTypeName column from the ToolType table // JToken is how you can accept a JSON message without deserialization. // Using "string" doesn't work because ASP.NET Core will expect a json encoded string, not give you the actual string. DataResponse IInboundRepository.Data(IMetrologyRepository metrologyRepository, IInboundDataService inboundDataService, string tooltype, JToken jsonbody) { DataResponse result = new(); ToolType? toolType = metrologyRepository.GetToolTypeByName(tooltype); if (toolType is null) result.Errors.Add("Invalid tool type: " + tooltype); else { List metaData = metrologyRepository.GetToolTypeMetadataByToolTypeID(toolType.ID).ToList(); if (metaData is null) result.Errors.Add("Invalid metadata for tool type: " + tooltype); else if (jsonbody is null) result.Errors.Add("Invalid json"); else inboundDataService.ValidateJSONFields(jsonbody, 0, metaData, result.Errors, result.Warnings); if (metaData is not null && jsonbody is not null && !result.Errors.Any()) { try { result.HeaderID = inboundDataService.DoSQLInsert(jsonbody, toolType, metaData); result.Success = result.HeaderID > 0; } catch (Exception ex) { result.Errors.Add(ex.Message); } } } return result; } // this is the endpoint for attaching a field. It is not JSON, it is form-data/multipart like an HTML form because that's the normal way. // header ID is the ID value from the Header table // datauniqueid is the Title value from the Data/Detail table string? IInboundRepository.AttachFile(IMetrologyRepository metrologyRepository, IAttachmentsService attachmentsService, string tooltype, long headerid, string datauniqueid, string fileName, object uploadedFile) { string? result = null; ToolType toolType = metrologyRepository.GetToolTypeByName(tooltype); if (toolType is null) result = $"Invalid tool type: {tooltype}"; string filename = Path.GetFileName(fileName); if (string.IsNullOrWhiteSpace(filename)) result = "Empty filename"; if (filename.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0) result = "Invalid filename"; if (result is null && toolType is not null) attachmentsService.SaveAttachment(toolType, headerid, datauniqueid, filename, uploadedFile); return result; } }