mirror of
https://github.com/C9Glax/tranga.git
synced 2025-09-10 03:48:19 +02:00
NotificationConnector DTO and RequestRecords
This commit is contained in:
@@ -1,16 +0,0 @@
|
||||
namespace API.APIEndpointRecords;
|
||||
|
||||
public record GotifyRecord(string Name, string Endpoint, string AppToken, int Priority)
|
||||
{
|
||||
public bool Validate()
|
||||
{
|
||||
if (Endpoint == string.Empty)
|
||||
return false;
|
||||
if (AppToken == string.Empty)
|
||||
return false;
|
||||
if (Priority < 0 || Priority > 10)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -1,17 +0,0 @@
|
||||
namespace API.APIEndpointRecords;
|
||||
|
||||
public record NtfyRecord(string Name, string Endpoint, string Username, string Password, string Topic, int Priority)
|
||||
{
|
||||
public bool Validate()
|
||||
{
|
||||
if (Endpoint == string.Empty)
|
||||
return false;
|
||||
if (Username == string.Empty)
|
||||
return false;
|
||||
if (Password == string.Empty)
|
||||
return false;
|
||||
if (Priority < 1 || Priority > 5)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -1,13 +0,0 @@
|
||||
namespace API.APIEndpointRecords;
|
||||
|
||||
public record PushoverRecord(string Name, string AppToken, string User)
|
||||
{
|
||||
public bool Validate()
|
||||
{
|
||||
if (AppToken == string.Empty)
|
||||
return false;
|
||||
if (User == string.Empty)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
46
API/Controllers/DTOs/NotificationConnector.cs
Normal file
46
API/Controllers/DTOs/NotificationConnector.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace API.Controllers.DTOs;
|
||||
|
||||
public record NotificationConnector(string Name, string Url, string HttpMethod, string Body, Dictionary<string, string> Headers) : Identifiable(Name)
|
||||
{
|
||||
/// <summary>
|
||||
/// The Name of the Notification Connector
|
||||
/// </summary>
|
||||
[Required]
|
||||
[Description("The Name of the Notification Connector")]
|
||||
public string Name { get; init; } = Name;
|
||||
|
||||
/// <summary>
|
||||
/// The Url of the Instance
|
||||
/// </summary>
|
||||
/// <remarks>Formatting placeholders: "%title" and "%text" will be replaced when notifications are sent</remarks>
|
||||
[Required]
|
||||
[Url]
|
||||
[Description("The Url of the Instance")]
|
||||
public string Url { get; internal set; } = Url;
|
||||
|
||||
/// <summary>
|
||||
/// The HTTP Request Method to use for notifications
|
||||
/// </summary>
|
||||
[Required]
|
||||
[Description("The HTTP Request Method to use for notifications")]
|
||||
public string HttpMethod { get; internal set; } = HttpMethod;
|
||||
|
||||
/// <summary>
|
||||
/// The Request Body to use to send notifications
|
||||
/// </summary>
|
||||
/// <remarks>Formatting placeholders: "%title" and "%text" will be replaced when notifications are sent</remarks>
|
||||
[Required]
|
||||
[Description("The Request Body to use to send notifications")]
|
||||
public string Body { get; internal set; } = Body;
|
||||
|
||||
/// <summary>
|
||||
/// The Request Headers to use to send notifications
|
||||
/// </summary>
|
||||
/// <remarks>Formatting placeholders: "%title" and "%text" will be replaced when notifications are sent</remarks>
|
||||
[Required]
|
||||
[Description("The Request Headers to use to send notifications")]
|
||||
public Dictionary<string, string> Headers { get; internal set; } = Headers;
|
||||
}
|
@@ -1,7 +1,7 @@
|
||||
using System.Text;
|
||||
using API.APIEndpointRecords;
|
||||
using API.Controllers.DTOs;
|
||||
using API.Controllers.Requests;
|
||||
using API.Schema.NotificationsContext;
|
||||
using API.Schema.NotificationsContext.NotificationConnectors;
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http.HttpResults;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -30,7 +30,9 @@ public class NotificationConnectorController(NotificationsContext context) : Con
|
||||
if(await context.NotificationConnectors.ToListAsync(HttpContext.RequestAborted) is not { } result)
|
||||
return TypedResults.InternalServerError();
|
||||
|
||||
return TypedResults.Ok(result);
|
||||
List<NotificationConnector> notificationConnectors = result.Select(n => new NotificationConnector(n.Name, n.Url, n.HttpMethod, n.Body, n.Headers)).ToList();
|
||||
|
||||
return TypedResults.Ok(notificationConnectors);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -47,7 +49,9 @@ public class NotificationConnectorController(NotificationsContext context) : Con
|
||||
if (await context.NotificationConnectors.FirstOrDefaultAsync(c => c.Name == Name, HttpContext.RequestAborted) is not { } connector)
|
||||
return TypedResults.NotFound(nameof(Name));
|
||||
|
||||
return TypedResults.Ok(connector);
|
||||
NotificationConnector notificationConnector = new NotificationConnector(connector.Name, connector.Url, connector.HttpMethod, connector.Body, connector.Headers);
|
||||
|
||||
return TypedResults.Ok(notificationConnector);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -57,16 +61,20 @@ public class NotificationConnectorController(NotificationsContext context) : Con
|
||||
/// <response code="200">ID of the new <see cref="NotificationConnector"/></response>
|
||||
/// <response code="500">Error during Database Operation</response>
|
||||
[HttpPut]
|
||||
[ProducesResponseType<string>(Status200OK, "text/plain")]
|
||||
[ProducesResponseType<string>(Status201Created, "text/plain")]
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public async Task<Results<Ok<string>, InternalServerError<string>>> CreateConnector ([FromBody]NotificationConnector notificationConnector)
|
||||
public async Task<Results<Created<string>, InternalServerError<string>>> CreateConnector ([FromBody]CreateNotificationConnectorRecord requestData)
|
||||
{
|
||||
context.NotificationConnectors.Add(notificationConnector);
|
||||
context.Notifications.Add(new ("Added new Notification Connector!", notificationConnector.Name, NotificationUrgency.High));
|
||||
// TODO validate data
|
||||
API.Schema.NotificationsContext.NotificationConnectors.NotificationConnector newConnector =
|
||||
new(requestData.Name, requestData.Url, requestData.Headers, requestData.HttpMethod, requestData.Body);
|
||||
|
||||
context.NotificationConnectors.Add(newConnector);
|
||||
context.Notifications.Add(new ("Added new Notification Connector!", newConnector.Name, NotificationUrgency.High));
|
||||
|
||||
if(await context.Sync(HttpContext.RequestAborted) is { success: false } result)
|
||||
return TypedResults.InternalServerError(result.exceptionMessage);
|
||||
return TypedResults.Ok(notificationConnector.Name);
|
||||
return TypedResults.Created(string.Empty, newConnector.Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -76,17 +84,16 @@ public class NotificationConnectorController(NotificationsContext context) : Con
|
||||
/// <response code="200">ID of the new <see cref="NotificationConnector"/></response>
|
||||
/// <response code="500">Error during Database Operation</response>
|
||||
[HttpPut("Gotify")]
|
||||
[ProducesResponseType<string>(Status200OK, "text/plain")]
|
||||
[ProducesResponseType<string>(Status201Created, "text/plain")]
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public async Task<Results<Ok<string>, InternalServerError<string>>> CreateGotifyConnector ([FromBody]GotifyRecord gotifyData)
|
||||
public async Task<Results<Created<string>, InternalServerError<string>>> CreateGotifyConnector ([FromBody]CreateGotifyConnectorRecord createGotifyConnectorData)
|
||||
{
|
||||
//TODO Validate Data
|
||||
|
||||
NotificationConnector gotifyConnector = new (gotifyData.Name,
|
||||
gotifyData.Endpoint,
|
||||
new Dictionary<string, string>() { { "X-Gotify-Key", gotifyData.AppToken } },
|
||||
CreateNotificationConnectorRecord gotifyConnector = new (createGotifyConnectorData.Name,
|
||||
createGotifyConnectorData.Url,
|
||||
"POST",
|
||||
$"{{\"message\": \"%text\", \"title\": \"%title\", \"Priority\": {gotifyData.Priority}}}");
|
||||
$"{{\"message\": \"%text\", \"title\": \"%title\", \"Priority\": {createGotifyConnectorData.Priority}}}",
|
||||
new () { { "X-Gotify-Key", createGotifyConnectorData.AppToken } });
|
||||
return await CreateConnector(gotifyConnector);
|
||||
}
|
||||
|
||||
@@ -97,23 +104,19 @@ public class NotificationConnectorController(NotificationsContext context) : Con
|
||||
/// <response code="200">ID of the new <see cref="NotificationConnector"/></response>
|
||||
/// <response code="500">Error during Database Operation</response>
|
||||
[HttpPut("Ntfy")]
|
||||
[ProducesResponseType<string>(Status200OK, "text/plain")]
|
||||
[ProducesResponseType<string>(Status201Created, "text/plain")]
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public async Task<Results<Ok<string>, InternalServerError<string>>> CreateNtfyConnector ([FromBody]NtfyRecord ntfyRecord)
|
||||
public async Task<Results<Created<string>, InternalServerError<string>>> CreateNtfyConnector ([FromBody]CreateNtfyConnectorRecord createNtfyConnectorRecord)
|
||||
{
|
||||
//TODO Validate Data
|
||||
|
||||
string authHeader = "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes($"{ntfyRecord.Username}:{ntfyRecord.Password}"));
|
||||
string authHeader = "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes($"{createNtfyConnectorRecord.Username}:{createNtfyConnectorRecord.Password}"));
|
||||
string auth = Convert.ToBase64String(Encoding.UTF8.GetBytes(authHeader)).Replace("=","");
|
||||
|
||||
NotificationConnector ntfyConnector = new (ntfyRecord.Name,
|
||||
$"{ntfyRecord.Endpoint}?auth={auth}",
|
||||
new Dictionary<string, string>()
|
||||
{
|
||||
{"Authorization", auth}
|
||||
},
|
||||
CreateNotificationConnectorRecord ntfyConnector = new (createNtfyConnectorRecord.Name,
|
||||
$"{createNtfyConnectorRecord.Url}?auth={auth}",
|
||||
"POST",
|
||||
$"{{\"message\": \"%text\", \"title\": \"%title\", \"Priority\": {ntfyRecord.Priority} \"Topic\": \"{ntfyRecord.Topic}\"}}");
|
||||
$"{{\"message\": \"%text\", \"title\": \"%title\", \"Priority\": {createNtfyConnectorRecord.Priority} \"Topic\": \"{createNtfyConnectorRecord.Topic}\"}}",
|
||||
new () {{"Authorization", auth}});
|
||||
return await CreateConnector(ntfyConnector);
|
||||
}
|
||||
|
||||
@@ -124,17 +127,16 @@ public class NotificationConnectorController(NotificationsContext context) : Con
|
||||
/// <response code="200">ID of the new <see cref="NotificationConnector"/></response>
|
||||
/// <response code="500">Error during Database Operation</response>
|
||||
[HttpPut("Pushover")]
|
||||
[ProducesResponseType<string>(Status200OK, "text/plain")]
|
||||
[ProducesResponseType<string>(Status201Created, "text/plain")]
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public async Task<Results<Ok<string>, InternalServerError<string>>> CreatePushoverConnector ([FromBody]PushoverRecord pushoverRecord)
|
||||
public async Task<Results<Created<string>, InternalServerError<string>>> CreatePushoverConnector ([FromBody]CreatePushoverConnectorRecord createPushoverConnectorRecord)
|
||||
{
|
||||
//TODO Validate Data
|
||||
|
||||
NotificationConnector pushoverConnector = new (pushoverRecord.Name,
|
||||
CreateNotificationConnectorRecord pushoverConnector = new (createPushoverConnectorRecord.Name,
|
||||
$"https://api.pushover.net/1/messages.json",
|
||||
new Dictionary<string, string>(),
|
||||
"POST",
|
||||
$"{{\"token\": \"{pushoverRecord.AppToken}\", \"user\": \"{pushoverRecord.User}\", \"message:\":\"%text\", \"%title\" }}");
|
||||
$"{{\"token\": \"{createPushoverConnectorRecord.AppToken}\", \"user\": \"{createPushoverConnectorRecord.Username}\", \"message:\":\"%text\", \"%title\" }}",
|
||||
new ());
|
||||
return await CreateConnector(pushoverConnector);
|
||||
}
|
||||
|
||||
|
37
API/Controllers/Requests/CreateGotifyConnectorRecord.cs
Normal file
37
API/Controllers/Requests/CreateGotifyConnectorRecord.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace API.Controllers.Requests;
|
||||
|
||||
public record CreateGotifyConnectorRecord(string Name, string Url, string AppToken, int Priority)
|
||||
{
|
||||
/// <summary>
|
||||
/// The Name of the Notification Connector
|
||||
/// </summary>
|
||||
[Required]
|
||||
[Description("The Name of the Notification Connector")]
|
||||
public string Name { get; init; } = Name;
|
||||
|
||||
/// <summary>
|
||||
/// The Url of the Instance
|
||||
/// </summary>
|
||||
/// <remarks>Formatting placeholders: "%title" and "%text" will be replaced when notifications are sent</remarks>
|
||||
[Required]
|
||||
[Url]
|
||||
[Description("The Url of the Instance")]
|
||||
public string Url { get; internal set; } = Url;
|
||||
|
||||
/// <summary>
|
||||
/// The Apptoken used for authentication
|
||||
/// </summary>
|
||||
[Required]
|
||||
[Description("The Apptoken used for authentication")]
|
||||
public string AppToken { get; init; } = AppToken;
|
||||
|
||||
/// <summary>
|
||||
/// The Priority of Notifications
|
||||
/// </summary>
|
||||
[Required]
|
||||
[Description("The Priority of Notifications")]
|
||||
public int Priority { get; init; } = Priority;
|
||||
}
|
@@ -0,0 +1,46 @@
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace API.Controllers.Requests;
|
||||
|
||||
public record CreateNotificationConnectorRecord(string Name, string Url, string HttpMethod, string Body, Dictionary<string, string> Headers)
|
||||
{
|
||||
/// <summary>
|
||||
/// The Name of the Notification Connector
|
||||
/// </summary>
|
||||
[Required]
|
||||
[Description("The Name of the Notification Connector")]
|
||||
public string Name { get; init; } = Name;
|
||||
|
||||
/// <summary>
|
||||
/// The Url of the Instance
|
||||
/// </summary>
|
||||
/// <remarks>Formatting placeholders: "%title" and "%text" will be replaced when notifications are sent</remarks>
|
||||
[Required]
|
||||
[Url]
|
||||
[Description("The Url of the Instance")]
|
||||
public string Url { get; internal set; } = Url;
|
||||
|
||||
/// <summary>
|
||||
/// The HTTP Request Method to use for notifications
|
||||
/// </summary>
|
||||
[Required]
|
||||
[Description("The HTTP Request Method to use for notifications")]
|
||||
public string HttpMethod { get; internal set; } = HttpMethod;
|
||||
|
||||
/// <summary>
|
||||
/// The Request Body to use to send notifications
|
||||
/// </summary>
|
||||
/// <remarks>Formatting placeholders: "%title" and "%text" will be replaced when notifications are sent</remarks>
|
||||
[Required]
|
||||
[Description("The Request Body to use to send notifications")]
|
||||
public string Body { get; internal set; } = Body;
|
||||
|
||||
/// <summary>
|
||||
/// The Request Headers to use to send notifications
|
||||
/// </summary>
|
||||
/// <remarks>Formatting placeholders: "%title" and "%text" will be replaced when notifications are sent</remarks>
|
||||
[Required]
|
||||
[Description("The Request Headers to use to send notifications")]
|
||||
public Dictionary<string, string> Headers { get; internal set; } = Headers;
|
||||
}
|
51
API/Controllers/Requests/CreateNtfyConnectorRecord.cs
Normal file
51
API/Controllers/Requests/CreateNtfyConnectorRecord.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace API.Controllers.Requests;
|
||||
|
||||
public record CreateNtfyConnectorRecord(string Name, string Url, string Username, string Password, string Topic, int Priority)
|
||||
{
|
||||
/// <summary>
|
||||
/// The Name of the Notification Connector
|
||||
/// </summary>
|
||||
[Required]
|
||||
[Description("The Name of the Notification Connector")]
|
||||
public string Name { get; init; } = Name;
|
||||
|
||||
/// <summary>
|
||||
/// The Url of the Instance
|
||||
/// </summary>
|
||||
/// <remarks>Formatting placeholders: "%title" and "%text" will be replaced when notifications are sent</remarks>
|
||||
[Required]
|
||||
[Url]
|
||||
[Description("The Url of the Instance")]
|
||||
public string Url { get; internal set; } = Url;
|
||||
|
||||
/// <summary>
|
||||
/// The Priority of Notifications
|
||||
/// </summary>
|
||||
[Required]
|
||||
[Description("The Priority of Notifications")]
|
||||
public int Priority { get; init; } = Priority;
|
||||
|
||||
/// <summary>
|
||||
/// The Username used for authentication
|
||||
/// </summary>
|
||||
[Required]
|
||||
[Description("The Username used for authentication")]
|
||||
public string Username { get; init; } = Username;
|
||||
|
||||
/// <summary>
|
||||
/// The Password used for authentication
|
||||
/// </summary>
|
||||
[Required]
|
||||
[Description("The Password used for authentication")]
|
||||
public string Password { get; init; } = Password;
|
||||
|
||||
/// <summary>
|
||||
/// The Topic of Notifications
|
||||
/// </summary>
|
||||
[Required]
|
||||
[Description("The Topic of Notifications")]
|
||||
public string Topic { get; init; } = Topic;
|
||||
}
|
28
API/Controllers/Requests/CreatePushoverConnectorRecord.cs
Normal file
28
API/Controllers/Requests/CreatePushoverConnectorRecord.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace API.Controllers.Requests;
|
||||
|
||||
public record CreatePushoverConnectorRecord(string Name, string AppToken, string Username)
|
||||
{
|
||||
/// <summary>
|
||||
/// The Name of the Notification Connector
|
||||
/// </summary>
|
||||
[Required]
|
||||
[Description("The Name of the Notification Connector")]
|
||||
public string Name { get; init; } = Name;
|
||||
|
||||
/// <summary>
|
||||
/// The Apptoken used for authentication
|
||||
/// </summary>
|
||||
[Required]
|
||||
[Description("The Apptoken used for authentication")]
|
||||
public string AppToken { get; init; } = AppToken;
|
||||
|
||||
/// <summary>
|
||||
/// The Username used for authentication
|
||||
/// </summary>
|
||||
[Required]
|
||||
[Description("The Username used for authentication")]
|
||||
public string Username { get; init; } = Username;
|
||||
}
|
@@ -10,36 +10,22 @@ namespace API.Schema.NotificationsContext.NotificationConnectors;
|
||||
[PrimaryKey("Name")]
|
||||
public class NotificationConnector(string name, string url, Dictionary<string, string> headers, string httpMethod, string body)
|
||||
{
|
||||
[StringLength(64)]
|
||||
[Required]
|
||||
public string Name { get; init; } = name;
|
||||
[StringLength(64)] public string Name { get; init; } = name;
|
||||
|
||||
[StringLength(2048)]
|
||||
[Required]
|
||||
[Url]
|
||||
public string Url { get; internal set; } = url;
|
||||
[StringLength(2048)] [Url] public string Url { get; internal set; } = url;
|
||||
|
||||
[Required]
|
||||
public Dictionary<string, string> Headers { get; internal set; } = headers;
|
||||
[Required] public Dictionary<string, string> Headers { get; internal set; } = headers;
|
||||
|
||||
[StringLength(8)]
|
||||
[Required]
|
||||
public string HttpMethod { get; internal set; } = httpMethod;
|
||||
[StringLength(8)] public string HttpMethod { get; internal set; } = httpMethod;
|
||||
|
||||
[StringLength(4096)]
|
||||
[Required]
|
||||
public string Body { get; internal set; } = body;
|
||||
[StringLength(4096)] public string Body { get; internal set; } = body;
|
||||
|
||||
[JsonIgnore]
|
||||
[NotMapped]
|
||||
private readonly HttpClient Client = new()
|
||||
[NotMapped] private readonly HttpClient Client = new()
|
||||
{
|
||||
DefaultRequestHeaders = { { "User-Agent", Tranga.Settings.UserAgent } }
|
||||
};
|
||||
|
||||
[JsonIgnore]
|
||||
[NotMapped]
|
||||
protected ILog Log = LogManager.GetLogger(name);
|
||||
[JsonIgnore] protected ILog Log = LogManager.GetLogger(name);
|
||||
|
||||
public void SendNotification(string title, string notificationText)
|
||||
{
|
||||
|
Reference in New Issue
Block a user