diff --git a/CyberBoom/Controllers/UserWriteToMetingController.cs b/CyberBoom/Controllers/UserWriteToMetingController.cs index c5f2c00..8394a27 100644 --- a/CyberBoom/Controllers/UserWriteToMetingController.cs +++ b/CyberBoom/Controllers/UserWriteToMetingController.cs @@ -2,7 +2,10 @@ using Mapster; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; - +using Hangfire; +using MailKit.Net.Smtp; +using MailKit.Security; +using MimeKit; namespace CyberBoom.Controllers; [ApiController] @@ -32,16 +35,19 @@ public class UserWriteToMetingController : ControllerBase var user = await _applicationContext.Users.FirstAsync(u => u.Id == write.UserId); - var newStats = await _applicationContext.GetStatistic(write.UserId); + + var delay = meeting.Time - DateTime.UtcNow - new TimeSpan(2, 0, 0); + + BackgroundJob.Schedule((_emailService) => _emailService.SendEmailAsync(user.Email!, "Вход в Муза", $"Здравcтвуйте. У вас мероприятие через 2 часа под названием {meeting.Title}"), delay); // за начало до встречи - var achievments = await WriteAchievment(newStats, write.UserId); + BackgroundJob.Schedule((context) => AfterEnd(write.UserId, context), meeting.Time - DateTime.UtcNow); // за начало до встречи await _applicationContext.SaveChangesAsync(); - return Ok(new { dbWr.Id, Achievments = achievments }); + return Ok(new { dbWr.Id}); } - async Task> WriteAchievment(StatsData stats, string userId) + async Task> WriteAchievment(StatsData stats, string userId, ApplicationContext context) { List achievments = new List(); if (stats.Count > 0 && stats.Count % 5 == 0) @@ -54,8 +60,9 @@ public class UserWriteToMetingController : ControllerBase UserId = userId }; achievments.Add(achievment); - await _applicationContext.Achievments.AddAsync(achievment); + await context.Achievments.AddAsync(achievment); } + var achievedTags = stats.StatsByTag.Where(st => st.Count > 0 && st.Count % 5 == 0); if (achievedTags.Count() > 0 && stats.Count % 5 == 0) { @@ -69,7 +76,7 @@ public class UserWriteToMetingController : ControllerBase UserId = userId }; achievments.Add(achievment); - await _applicationContext.Achievments.AddAsync(achievment); + await context.Achievments.AddAsync(achievment); } } return achievments; @@ -93,6 +100,16 @@ public class UserWriteToMetingController : ControllerBase return Ok(); } + + async Task AfterEnd(string userId, ApplicationContext context) + { + var newStats = await context.GetStatistic(userId); + + await WriteAchievment(newStats, userId, context); + + await context.SaveChangesAsync(); + } + [HttpGet] public async Task Get(string id) { @@ -112,3 +129,45 @@ public class UserWriteToMetingController : ControllerBase return Ok(reviews); } } + + + +public interface IEmailService +{ + public Task SendEmailAsync(string email, string subject, string message); +} + +public class EmailService : IEmailService +{ + private readonly IConfiguration _configuration; + private ILogger _logger; + + public EmailService(IConfiguration configuration, ILogger logger) + { + _configuration = configuration; + _logger = logger; + } + + public async Task SendEmailAsync(string email, string subject, string message) + { + var emailMessage = new MimeMessage(); + + emailMessage.From.Add(new MailboxAddress(_configuration["Email:Name"], _configuration["Email:Address"])); + emailMessage.To.Add(new MailboxAddress("", email)); + emailMessage.Subject = subject; + emailMessage.Body = new TextPart(MimeKit.Text.TextFormat.Html) + { + Text = message + }; + + using var client = new SmtpClient(); + client.Timeout = 15000; + await client.ConnectAsync(_configuration["Email:Host"], int.Parse(_configuration["Email:Port"]!), SecureSocketOptions.None); + await client.AuthenticateAsync(_configuration["Email:Address"], _configuration["Email:Password"]); + await client.SendAsync(emailMessage); + + _logger.LogInformation("Письмо отправлено на почту {Email}", email); + + await client.DisconnectAsync(true); + } +} \ No newline at end of file diff --git a/CyberBoom/CyberBoom.csproj b/CyberBoom/CyberBoom.csproj index cb6c969..987ed4e 100644 --- a/CyberBoom/CyberBoom.csproj +++ b/CyberBoom/CyberBoom.csproj @@ -9,6 +9,11 @@ + + + + + diff --git a/CyberBoom/Program.cs b/CyberBoom/Program.cs index 01bff1a..0447fed 100644 --- a/CyberBoom/Program.cs +++ b/CyberBoom/Program.cs @@ -7,7 +7,9 @@ using Microsoft.Extensions.FileProviders; using Microsoft.OpenApi.Models; using Microsoft.AspNetCore.Authentication.Google; using Microsoft.AspNetCore.HttpOverrides; - +using Hangfire; +using Hangfire.PostgreSql; +using Hangfire.Dashboard; TypeAdapterConfig.NewConfig().Map(d => d.SpeackerImage, s => s.SpeackerImage.JoinFileNames()); TypeAdapterConfig.NewConfig().Map(d => d.SpeackerImage, s => s.SpeackerImage.JoinFileNames()); @@ -50,6 +52,16 @@ builder.Services.AddAuthentication(opt => { }); +builder.Services.AddHangfire(configuration => configuration + .SetDataCompatibilityLevel(CompatibilityLevel.Version_180) + .UseSimpleAssemblyNameTypeSerializer() + .UseRecommendedSerializerSettings() + .UsePostgreSqlStorage(c => + c.UseNpgsqlConnection(builder.Configuration["CONNECTION_STRING"]))); + //.UseSqlServerStorage(Configuration.GetConnectionString("HangfireConnection"))); + + // Add the processing server as IHostedService +builder.Services.AddHangfireServer(); builder.Services.AddControllers(); @@ -87,12 +99,16 @@ builder.Services.AddCors(); var app = builder.Build(); + + app.UseCors(builder => builder.AllowAnyMethod()); app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedProto }); + + app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider( @@ -100,18 +116,44 @@ app.UseStaticFiles(new StaticFileOptions RequestPath = "/api/cyber-boom-files" }); + + // Configure the HTTP request pipeline. app.UseSwagger(); app.UseSwaggerUI(); + app.UseAuthentication(); // подключение аутентификации app.UseAuthorization(); +app.UseHangfireDashboard("/workers", new DashboardOptions +{ + Authorization = new [] { new AdminAuthorizationFilter() } +}); + + + + app.MapControllers(); +app.MapHangfireDashboard(); //app.MapRazorPages(); app.Run(); + + +public class AdminAuthorizationFilter : IDashboardAuthorizationFilter +{ + public bool Authorize(DashboardContext context) + { + var user = context.GetHttpContext().User; + + if (user.IsInRole("модератор")) + return true; + + return false; + } +} diff --git a/CyberBoom/appsettings.json b/CyberBoom/appsettings.json index 4cf5405..0a349e5 100644 --- a/CyberBoom/appsettings.json +++ b/CyberBoom/appsettings.json @@ -8,5 +8,4 @@ }, "CONNECTION_STRING": "Host=localhost; Database=CyberBoomWellBeing; Username=postgres; Password=supper_password_123" - }