using System.Text; using API.APIEndpointRecords; using API.Schema.NotificationsContext; using API.Schema.NotificationsContext.NotificationConnectors; using Asp.Versioning; using Microsoft.AspNetCore.Mvc; using static Microsoft.AspNetCore.Http.StatusCodes; // ReSharper disable InconsistentNaming namespace API.Controllers; [ApiVersion(2)] [ApiController] [Produces("application/json")] [Route("v{v:apiVersion}/[controller]")] public class NotificationConnectorController(IServiceScope scope) : Controller { /// /// Gets all configured /// /// [HttpGet] [ProducesResponseType(Status200OK, "application/json")] public IActionResult GetAllConnectors() { NotificationsContext context = scope.ServiceProvider.GetRequiredService(); return Ok(context.NotificationConnectors.ToArray()); } /// /// Returns with requested Name /// /// .Name /// /// with not found [HttpGet("{Name}")] [ProducesResponseType(Status200OK, "application/json")] [ProducesResponseType(Status404NotFound)] public IActionResult GetConnector(string Name) { NotificationsContext context = scope.ServiceProvider.GetRequiredService(); if(context.NotificationConnectors.Find(Name) is not { } connector) return NotFound(); return Ok(connector); } /// /// Creates a new /// /// Formatting placeholders: "%title" and "%text" can be placed in url, header-values and body and will be replaced when notifications are sent /// /// Error during Database Operation [HttpPut] [ProducesResponseType(Status201Created)] [ProducesResponseType(Status409Conflict)] [ProducesResponseType(Status500InternalServerError, "text/plain")] public IActionResult CreateConnector([FromBody]NotificationConnector notificationConnector) { NotificationsContext context = scope.ServiceProvider.GetRequiredService(); context.NotificationConnectors.Add(notificationConnector); if(context.Sync().Result is { success: false } result) return StatusCode(Status500InternalServerError, result.exceptionMessage); return Created(); } /// /// Creates a new Gotify- /// /// Priority needs to be between 0 and 10 /// /// Error during Database Operation [HttpPut("Gotify")] [ProducesResponseType(Status201Created, "application/json")] [ProducesResponseType(Status500InternalServerError, "text/plain")] public IActionResult CreateGotifyConnector([FromBody]GotifyRecord gotifyData) { //TODO Validate Data NotificationConnector gotifyConnector = new (gotifyData.Name, gotifyData.Endpoint, new Dictionary() { { "X-Gotify-IDOnConnector", gotifyData.AppToken } }, "POST", $"{{\"message\": \"%text\", \"title\": \"%title\", \"Priority\": {gotifyData.Priority}}}"); return CreateConnector(gotifyConnector); } /// /// Creates a new Ntfy- /// /// Priority needs to be between 1 and 5 /// /// Error during Database Operation [HttpPut("Ntfy")] [ProducesResponseType(Status201Created, "application/json")] [ProducesResponseType(Status500InternalServerError, "text/plain")] public IActionResult CreateNtfyConnector([FromBody]NtfyRecord ntfyRecord) { //TODO Validate Data string authHeader = "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes($"{ntfyRecord.Username}:{ntfyRecord.Password}")); string auth = Convert.ToBase64String(Encoding.UTF8.GetBytes(authHeader)).Replace("=",""); NotificationConnector ntfyConnector = new (ntfyRecord.Name, $"{ntfyRecord.Endpoint}/{ntfyRecord.Topic}?auth={auth}", new Dictionary() { {"Title", "%title"}, {"Priority", ntfyRecord.Priority.ToString()}, }, "POST", "%text"); return CreateConnector(ntfyConnector); } /// /// Creates a new Pushover- /// /// https://pushover.net/api /// ID of new connector /// Error during Database Operation [HttpPut("Pushover")] [ProducesResponseType(Status201Created, "application/json")] [ProducesResponseType(Status500InternalServerError, "text/plain")] public IActionResult CreatePushoverConnector([FromBody]PushoverRecord pushoverRecord) { //TODO Validate Data NotificationConnector pushoverConnector = new (pushoverRecord.Name, $"https://api.pushover.net/1/messages.json", new Dictionary(), "POST", $"{{\"token\": \"{pushoverRecord.AppToken}\", \"user\": \"{pushoverRecord.User}\", \"message:\":\"%text\", \"%title\" }}"); return CreateConnector(pushoverConnector); } /// /// Deletes the with the requested Name /// /// .Name /// /// with Name not found /// Error during Database Operation [HttpDelete("{Name}")] [ProducesResponseType(Status200OK)] [ProducesResponseType(Status404NotFound)] [ProducesResponseType(Status500InternalServerError, "text/plain")] public IActionResult DeleteConnector(string Name) { NotificationsContext context = scope.ServiceProvider.GetRequiredService(); if(context.NotificationConnectors.Find(Name) is not { } connector) return NotFound(); context.NotificationConnectors.Remove(connector); if(context.Sync().Result is { success: false } result) return StatusCode(Status500InternalServerError, result.exceptionMessage); return Created(); } }