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.Security;
using BTCPayServer.Services.Notifications;
using BTCPayServer.Services.Notifications.Blobs;
using Google;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
@ -57,9 +58,7 @@ namespace BTCPayServer.Controllers
[HttpGet]
public async Task<IActionResult> Generate(string version)
{
await _notificationSender.NoticeNewVersionAsync(version);
// waiting for event handler to catch up
await Task.Delay(500);
await _notificationSender.SendNotification(new AdminScope(), new NewVersionNotification(version));
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
// because of dependent initialization and parsing to view models logic
// 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);
}
}

View File

@ -7,7 +7,14 @@ namespace BTCPayServer.Services.Notifications.Blobs
internal class NewVersionNotification : BaseNotification
{
internal override string NotificationType => "NewVersionNotification";
public NewVersionNotification()
{
}
public NewVersionNotification(string version)
{
Version = version;
}
public string Version { get; set; }
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 BTCPayServer.Data;
using BTCPayServer.Events;
using BTCPayServer.Services.Notifications.Blobs;
using Microsoft.AspNetCore.Identity;
using Newtonsoft.Json;
namespace BTCPayServer.Services.Notifications
{
@ -20,32 +22,38 @@ namespace BTCPayServer.Services.Notifications
_eventAggregator = eventAggregator;
}
internal async Task NoticeNewVersionAsync(string version)
public async Task SendNotification(NotificationScope scope, BaseNotification notification)
{
var admins = await _userManager.GetUsersInRoleAsync(Roles.ServerAdmin);
var adminUids = admins.Select(a => a.Id).ToArray();
var notif = new NewVersionNotification
{
Version = version
};
var users = await GetUsers(scope);
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);
}
await db.SaveChangesAsync();
}
}
// propagate notification
_eventAggregator.Publish(new NotificationEvent
private async Task<string[]> GetUsers(NotificationScope scope)
{
if (scope is AdminScope)
{
ApplicationUserIds = adminUids,
Notification = notif
});
var admins = await _userManager.GetUsersInRoleAsync(Roles.ServerAdmin);
return admins.Select(a => a.Id).ToArray();
}
throw new NotSupportedException("Notification scope not supported");
}
}
}