mirror of
https://github.com/BZmHackTeam/BezpiecznaZywnosc
synced 2024-12-22 14:46:58 +01:00
Minimum Viable Mailsender
This commit is contained in:
parent
f6f6c17555
commit
b77acdb322
6 changed files with 147 additions and 11 deletions
15
src/Nyanlabs.SFood.Api/Controllers/ApiController.cs
Normal file
15
src/Nyanlabs.SFood.Api/Controllers/ApiController.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Nyanlabs.SFood.Api.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("/api")]
|
||||
public class ApiController : ControllerBase
|
||||
{
|
||||
[HttpGet("version")]
|
||||
public string Version() => "1.0.0E";
|
||||
}
|
39
src/Nyanlabs.SFood.Api/Controllers/IncidentController.cs
Normal file
39
src/Nyanlabs.SFood.Api/Controllers/IncidentController.cs
Normal file
|
@ -0,0 +1,39 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Net.Mail;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Nyanlabs.SFood.Api.Models;
|
||||
using Nyanlabs.SFood.Api.Services;
|
||||
|
||||
namespace Nyanlabs.SFood.Api.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/incident")]
|
||||
public class IncidentController : ControllerBase
|
||||
{
|
||||
public IncidentController(EmailClient mail)
|
||||
{
|
||||
_mail = mail;
|
||||
}
|
||||
|
||||
private readonly EmailClient _mail;
|
||||
|
||||
[HttpPost("submit")]
|
||||
public async Task<IActionResult> SubmitIncident([FromForm] IncidentSubmission incident)
|
||||
{
|
||||
string body = $@"<p>Dziękujemy za zgłoszenie incydentu.<p>
|
||||
<p>Dane zgłoszenia:<br/>
|
||||
<b>Identyfikator zgłoszenia:</b> {Random.Shared.NextInt64()}<br/>
|
||||
<b>Produkt:</b> {incident.ProductName}<br/>
|
||||
<b>Producent:</b> {incident.Producer}<br/>
|
||||
<b>Opis incydentu:</b> {incident.Description}<br/>
|
||||
<b>Miejsce zdarzenia:</b> {incident.Location}<br/>
|
||||
<b>Data zgłoszenia:</b> {incident.Submitted.ToLongDateString()}
|
||||
</p>";
|
||||
|
||||
return (await _mail.SendRawAsync(incident.SubmitterAddress, body)) ? NoContent() : BadRequest();
|
||||
}
|
||||
}
|
|
@ -10,13 +10,11 @@ namespace Nyanlabs.SFood.Api.Models;
|
|||
public class IncidentSubmission
|
||||
{
|
||||
//TODO: Validation
|
||||
[Key]
|
||||
public long Id { get; set; }
|
||||
public required string Name { get; set; }
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public DateTime Submitted { get; set; }
|
||||
public DateTime Submitted { get; set; } = DateTime.Now;
|
||||
[EmailAddress]
|
||||
public string? SubmitterAddress { get; set; }
|
||||
public required string SubmitterAddress { get; set; }
|
||||
public required string ProductName { get; set; }
|
||||
public required string Producer { get; set; }
|
||||
public required string Description { get; set; }
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MailKit" Version="4.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.12" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.12" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.12">
|
||||
|
|
|
@ -1,19 +1,23 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Nyanlabs.SFood.Api;
|
||||
using Nyanlabs.SFood.Api.Services;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
builder.Services.Configure<EmailClientOptions>(o => builder.Configuration.GetSection("EmailClient").Bind(o));
|
||||
|
||||
builder.Services.AddControllers();
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen();
|
||||
builder.Services.AddScoped<EmailClient>();
|
||||
|
||||
builder.Services.AddDbContext<DataContext>(o =>
|
||||
{
|
||||
if (builder.Environment.IsDevelopment())
|
||||
{
|
||||
o.UseSqlite("Data Source=/data/store.db;");
|
||||
}
|
||||
});
|
||||
// builder.Services.AddDbContext<DataContext>(o =>
|
||||
// {
|
||||
// if (builder.Environment.IsDevelopment())
|
||||
// {
|
||||
// o.UseSqlite("Data Source=/data/store.db;");
|
||||
// }
|
||||
// });
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
|
|
79
src/Nyanlabs.SFood.Api/Services/EmailClient.cs
Normal file
79
src/Nyanlabs.SFood.Api/Services/EmailClient.cs
Normal file
|
@ -0,0 +1,79 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using MailKit.Net.Smtp;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MimeKit;
|
||||
|
||||
namespace Nyanlabs.SFood.Api.Services;
|
||||
|
||||
public class EmailClient : IDisposable
|
||||
{
|
||||
public EmailClient(IOptions<EmailClientOptions> opts)
|
||||
{
|
||||
_opts = opts.Value;
|
||||
_cli = new();
|
||||
_cli.Connect(_opts.Host, _opts.Port, true);
|
||||
|
||||
if (!_cli.IsConnected)
|
||||
{
|
||||
throw new DataException($"Cannot connect to {_opts.Host}:{_opts.Port}...");
|
||||
}
|
||||
|
||||
var credentials = new NetworkCredential(_opts.User, _opts.Password);
|
||||
_cli.Authenticate(credentials);
|
||||
if (!_cli.IsAuthenticated)
|
||||
{
|
||||
throw new DataException($"{_opts.Host}:{_opts.Port}: Cannot authenticate user {_opts.User}.");
|
||||
}
|
||||
}
|
||||
|
||||
private readonly EmailClientOptions _opts;
|
||||
private readonly SmtpClient _cli;
|
||||
|
||||
public async Task<bool> SendAsync([EmailAddress] string addr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
internal async Task<bool> SendRawAsync([EmailAddress] string addr, string html)
|
||||
{
|
||||
MimeMessage msg = new();
|
||||
msg.From.Add(new MailboxAddress(_opts.FromName, _opts.FromAddr));
|
||||
|
||||
var recipient = new MailboxAddress(addr, addr);
|
||||
|
||||
if (recipient is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
msg.To.Add(recipient);
|
||||
|
||||
msg.Subject = "Zgłoszenie przyjęte";
|
||||
msg.Body = new TextPart("html", html);
|
||||
|
||||
string result = await _cli.SendAsync(msg);
|
||||
return result.StartsWith("2.") && result.Contains("ok", StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_cli.Disconnect(true);
|
||||
_cli.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public record EmailClientOptions
|
||||
{
|
||||
public required string Host { get; set; }
|
||||
public required string User { get; set; }
|
||||
public required string Password { get; set; }
|
||||
public required string FromName { get; set; }
|
||||
public required string FromAddr { get; set; }
|
||||
public int Port { get; set; } = 465;
|
||||
};
|
Loading…
Reference in a new issue