Make the NotificationSender more generic

This commit is contained in:
nicolas.dorier 2020-06-15 16:45:29 +09:00
parent 43a99bfef2
commit 9070b475ea
No known key found for this signature in database
GPG Key ID: 6618763EF09186FE
6 changed files with 64 additions and 48 deletions

View File

@ -10,6 +10,7 @@ using BTCPayServer.HostedServices;
using BTCPayServer.Models.NotificationViewModels; using BTCPayServer.Models.NotificationViewModels;
using BTCPayServer.Security; using BTCPayServer.Security;
using BTCPayServer.Services.Notifications; using BTCPayServer.Services.Notifications;
using BTCPayServer.Services.Notifications.Blobs;
using Google; using Google;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
@ -57,9 +58,7 @@ namespace BTCPayServer.Controllers
[HttpGet] [HttpGet]
public async Task<IActionResult> Generate(string version) public async Task<IActionResult> Generate(string version)
{ {
await _notificationSender.NoticeNewVersionAsync(version); await _notificationSender.SendNotification(new AdminScope(), new NewVersionNotification(version));
// waiting for event handler to catch up
await Task.Delay(500);
return RedirectToAction(nameof(Index)); return RedirectToAction(nameof(Index));
} }

View File

@ -1,10 +0,0 @@
using BTCPayServer.Services.Notifications.Blobs;
namespace BTCPayServer.Events
{
internal class NotificationEvent
{
internal string[] ApplicationUserIds { get; set; }
internal BaseNotification Notification { get; set; }
}
}

View File

@ -8,26 +8,8 @@ namespace BTCPayServer.Services.Notifications.Blobs
// Make sure to keep all Blob Notification classes in same namespace // Make sure to keep all Blob Notification classes in same namespace
// because of dependent initialization and parsing to view models logic // because of dependent initialization and parsing to view models logic
// IndexViewModel.cs#32 // IndexViewModel.cs#32
internal abstract class BaseNotification public abstract class BaseNotification
{ {
internal virtual string NotificationType { get { return GetType().Name; } }
public NotificationData ToData(string applicationUserId)
{
var obj = JsonConvert.SerializeObject(this);
var data = new NotificationData
{
Id = Guid.NewGuid().ToString(),
Created = DateTimeOffset.UtcNow,
ApplicationUserId = applicationUserId,
NotificationType = NotificationType,
Blob = ZipUtils.Zip(obj),
Seen = false
};
return data;
}
public abstract void FillViewModel(ref NotificationViewModel data); public abstract void FillViewModel(ref NotificationViewModel data);
} }
} }

View File

@ -7,7 +7,14 @@ namespace BTCPayServer.Services.Notifications.Blobs
internal class NewVersionNotification : BaseNotification internal class NewVersionNotification : BaseNotification
{ {
internal override string NotificationType => "NewVersionNotification"; internal override string NotificationType => "NewVersionNotification";
public NewVersionNotification()
{
}
public NewVersionNotification(string version)
{
Version = version;
}
public string Version { get; set; } public string Version { get; set; }
public override void FillViewModel(ref NotificationViewModel vm) public override void FillViewModel(ref NotificationViewModel vm)

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BTCPayServer.Data;
using Microsoft.EntityFrameworkCore;
namespace BTCPayServer.Services.Notifications
{
public class AdminScope : NotificationScope
{
public AdminScope()
{
}
}
public class StoreScope : NotificationScope
{
public StoreScope(string storeId)
{
if (storeId == null)
throw new ArgumentNullException(nameof(storeId));
StoreId = storeId;
}
public string StoreId { get; }
}
public interface NotificationScope
{
}
}

View File

@ -1,9 +1,11 @@
using System.Linq; using System;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using BTCPayServer.Data; using BTCPayServer.Data;
using BTCPayServer.Events; using BTCPayServer.Events;
using BTCPayServer.Services.Notifications.Blobs; using BTCPayServer.Services.Notifications.Blobs;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Newtonsoft.Json;
namespace BTCPayServer.Services.Notifications namespace BTCPayServer.Services.Notifications
{ {
@ -20,32 +22,38 @@ namespace BTCPayServer.Services.Notifications
_eventAggregator = eventAggregator; _eventAggregator = eventAggregator;
} }
internal async Task NoticeNewVersionAsync(string version) public async Task SendNotification(NotificationScope scope, BaseNotification notification)
{ {
var admins = await _userManager.GetUsersInRoleAsync(Roles.ServerAdmin); var users = await GetUsers(scope);
var adminUids = admins.Select(a => a.Id).ToArray();
var notif = new NewVersionNotification
{
Version = version
};
using (var db = _contextFactory.CreateContext()) using (var db = _contextFactory.CreateContext())
{ {
foreach (var uid in adminUids) foreach (var uid in users)
{ {
var data = notif.ToData(uid); var obj = JsonConvert.SerializeObject(this);
var data = new NotificationData
{
Id = Guid.NewGuid().ToString(),
Created = DateTimeOffset.UtcNow,
ApplicationUserId = uid,
NotificationType = notification.NotificationType,
Blob = ZipUtils.Zip(obj),
Seen = false
};
db.Notifications.Add(data); db.Notifications.Add(data);
} }
await db.SaveChangesAsync(); await db.SaveChangesAsync();
} }
}
// propagate notification private async Task<string[]> GetUsers(NotificationScope scope)
_eventAggregator.Publish(new NotificationEvent
{ {
ApplicationUserIds = adminUids, if (scope is AdminScope)
Notification = notif {
}); var admins = await _userManager.GetUsersInRoleAsync(Roles.ServerAdmin);
return admins.Select(a => a.Id).ToArray();
}
throw new NotSupportedException("Notification scope not supported");
} }
} }
} }