using System.Text; using API.APIEndpointRecords; using API.Schema.NotificationsContext; using API.Schema.NotificationsContext.NotificationConnectors; using Asp.Versioning; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; 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(NotificationsContext context) : Controller { /// /// Gets all configured /// /// /// Error during Database Operation [HttpGet] [ProducesResponseType(Status200OK, "application/json")] public async Task GetAllConnectors () { if(await context.NotificationConnectors.ToArrayAsync(HttpContext.RequestAborted) is not { } result) return StatusCode(Status500InternalServerError); return Ok(result); } /// /// Returns with requested Name /// /// .Name /// /// with not found [HttpGet("{Name}")] [ProducesResponseType(Status200OK, "application/json")] [ProducesResponseType(Status404NotFound)] public async Task GetConnector (string Name) { if (await context.NotificationConnectors.FirstOrDefaultAsync(c => c.Name == Name, HttpContext.RequestAborted) is not { } connector) return NotFound(nameof(Name)); 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 /// ID of the new /// Error during Database Operation [HttpPut] [ProducesResponseType(Status200OK, "text/plain")] [ProducesResponseType(Status500InternalServerError, "text/plain")] public async Task CreateConnector ([FromBody]NotificationConnector notificationConnector) { context.NotificationConnectors.Add(notificationConnector); context.Notifications.Add(new ("Added new Notification Connector!", notificationConnector.Name, NotificationUrgency.High)); if(await context.Sync(HttpContext.RequestAborted) is { success: false } result) return StatusCode(Status500InternalServerError, result.exceptionMessage); return Ok(notificationConnector.Name); } /// /// Creates a new Gotify- /// /// Priority needs to be between 0 and 10 /// ID of the new /// Error during Database Operation [HttpPut("Gotify")] [ProducesResponseType(Status200OK, "text/plain")] [ProducesResponseType(Status500InternalServerError, "text/plain")] public async Task CreateGotifyConnector ([FromBody]GotifyRecord gotifyData) { //TODO Validate Data NotificationConnector gotifyConnector = new (gotifyData.Name, gotifyData.Endpoint, new Dictionary() { { "X-Gotify-Key", gotifyData.AppToken } }, "POST", $"{{\"message\": \"%text\", \"title\": \"%title\", \"Priority\": {gotifyData.Priority}}}"); return await CreateConnector(gotifyConnector); } /// /// Creates a new Ntfy- /// /// Priority needs to be between 1 and 5 /// ID of the new /// Error during Database Operation [HttpPut("Ntfy")] [ProducesResponseType(Status200OK, "text/plain")] [ProducesResponseType(Status500InternalServerError, "text/plain")] public async Task 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}?auth={auth}", new Dictionary() { {"Authorization", auth} }, "POST", $"{{\"message\": \"%text\", \"title\": \"%title\", \"Priority\": {ntfyRecord.Priority} \"Topic\": \"{ntfyRecord.Topic}\"}}"); return await CreateConnector(ntfyConnector); } /// /// Creates a new Pushover- /// /// https://pushover.net/api /// ID of the new /// Error during Database Operation [HttpPut("Pushover")] [ProducesResponseType(Status200OK, "text/plain")] [ProducesResponseType(Status500InternalServerError, "text/plain")] public async Task 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 await 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 async Task DeleteConnector (string Name) { if (await context.NotificationConnectors.FirstOrDefaultAsync(c => c.Name == Name, HttpContext.RequestAborted) is not { } connector) return NotFound(nameof(Name)); context.NotificationConnectors.Remove(connector); if(await context.Sync(HttpContext.RequestAborted) is { success: false } result) return StatusCode(Status500InternalServerError, result.exceptionMessage); return Ok(); } }