From c4dee589ccead630d7d3f4a72b49eccb20af08b6 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Mon, 29 May 2017 23:35:41 -0400 Subject: [PATCH] notification hub migrator util --- bitwarden-core.sln | 13 ++- util/AnhMigrator/AnhMigrator.csproj | 18 +++ util/AnhMigrator/Program.cs | 166 ++++++++++++++++++++++++++++ 3 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 util/AnhMigrator/AnhMigrator.csproj create mode 100644 util/AnhMigrator/Program.cs diff --git a/bitwarden-core.sln b/bitwarden-core.sln index a405c0063f..6630550bf1 100644 --- a/bitwarden-core.sln +++ b/bitwarden-core.sln @@ -1,10 +1,14 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26403.7 +VisualStudioVersion = 15.0.26430.4 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "util", "util", "{DD5BD056-4AAE-43EF-BBD2-0B569B8DA84E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{DD5BD056-4AAE-43EF-BBD2-0B569B8DA84F}" +EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{458155D3-BCBC-481D-B37A-40D2ED10F0A4}" ProjectSection(SolutionItems) = preProject .gitignore = .gitignore @@ -24,6 +28,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Billing", "src\Billing\Bill EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Identity", "src\Identity\Identity.csproj", "{04148736-3C0B-445E-8B74-2020E7A53502}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AnhMigrator", "util\AnhMigrator\AnhMigrator.csproj", "{05C45D68-DAB9-40E6-9E2E-F81BBD2E0C42}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -56,6 +62,10 @@ Global {04148736-3C0B-445E-8B74-2020E7A53502}.Debug|Any CPU.Build.0 = Debug|Any CPU {04148736-3C0B-445E-8B74-2020E7A53502}.Release|Any CPU.ActiveCfg = Release|Any CPU {04148736-3C0B-445E-8B74-2020E7A53502}.Release|Any CPU.Build.0 = Release|Any CPU + {05C45D68-DAB9-40E6-9E2E-F81BBD2E0C42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {05C45D68-DAB9-40E6-9E2E-F81BBD2E0C42}.Debug|Any CPU.Build.0 = Debug|Any CPU + {05C45D68-DAB9-40E6-9E2E-F81BBD2E0C42}.Release|Any CPU.ActiveCfg = Release|Any CPU + {05C45D68-DAB9-40E6-9E2E-F81BBD2E0C42}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -67,5 +77,6 @@ Global {B78A6C74-1A24-48C6-802A-13BE3E4DAFF1} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D} {02BC2982-ED8D-4A6D-A41E-092B3DAEB98A} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D} {04148736-3C0B-445E-8B74-2020E7A53502} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D} + {05C45D68-DAB9-40E6-9E2E-F81BBD2E0C42} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84E} EndGlobalSection EndGlobal diff --git a/util/AnhMigrator/AnhMigrator.csproj b/util/AnhMigrator/AnhMigrator.csproj new file mode 100644 index 0000000000..434be5f69a --- /dev/null +++ b/util/AnhMigrator/AnhMigrator.csproj @@ -0,0 +1,18 @@ + + + + Exe + net461 + Bit.AnhMigrator + + + + + + + + + + + + \ No newline at end of file diff --git a/util/AnhMigrator/Program.cs b/util/AnhMigrator/Program.cs new file mode 100644 index 0000000000..a854a7dc14 --- /dev/null +++ b/util/AnhMigrator/Program.cs @@ -0,0 +1,166 @@ +using Bit.Core.Models.Table; +using Dapper; +using Microsoft.Azure.NotificationHubs; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.SqlClient; +using System.Linq; +using System.Threading.Tasks; +using Bit.Core.Enums; +using Newtonsoft.Json; + +namespace Bit.AnhMigrator +{ + class Program + { + private const string SqlConnectionString = ""; + private const string AnhConnectionString = ""; + private const string AnhHubName = ""; + + private static DateTime _startDate = DateTime.UtcNow.AddYears(-10); + private static string _viewId = ""; + + private static NotificationHubClient _client; + + static void Main(string[] args) + { + _client = NotificationHubClient.CreateClientFromConnectionString( + AnhConnectionString, + AnhHubName); + + //RegisterAsync(args).Wait(); + //ViewAsync(args).Wait(); + Console.Read(); + } + + private static async Task RegisterAsync(string[] args) + { + IDictionary> orgUsersDict; + using(var connection = new SqlConnection(SqlConnectionString)) + { + var results = await connection.QueryAsync( + "SELECT * FROM [dbo].[OrganizationUser] WHERE [Status] = 2 AND [UserId] IS NOT NULL", + commandType: CommandType.Text); + + orgUsersDict = results + .GroupBy(ou => ou.UserId.Value) + .ToDictionary(ou => ou.Key, ou => ou.ToList()); + } + + IEnumerable devices; + using(var connection = new SqlConnection(SqlConnectionString)) + { + devices = await connection.QueryAsync( + "SELECT * FROM [dbo].[Device] WHERE [PushToken] IS NOT NULL AND [RevisionDate] > @StartDate", + new { StartDate = _startDate }, + commandType: CommandType.Text); + } + + var i = 0; + foreach(var device in devices) + { + i++; + + var installation = new Installation + { + InstallationId = device.Id.ToString(), + PushChannel = device.PushToken, + Templates = new Dictionary() + }; + + installation.Tags = new List + { + $"userId:{device.UserId}" + }; + + if(!string.IsNullOrWhiteSpace(device.Identifier)) + { + installation.Tags.Add("deviceIdentifier:" + device.Identifier); + } + + if(orgUsersDict.ContainsKey(device.UserId)) + { + foreach(var orgUser in orgUsersDict[device.UserId]) + { + installation.Tags.Add("organizationId:" + orgUser.OrganizationId); + } + } + + string payloadTemplate = null, messageTemplate = null, badgeMessageTemplate = null; + switch(device.Type) + { + case DeviceType.Android: + payloadTemplate = "{\"data\":{\"type\":\"#(type)\",\"payload\":\"$(payload)\"}}"; + messageTemplate = "{\"data\":{\"type\":\"#(type)\"}," + + "\"notification\":{\"title\":\"$(title)\",\"body\":\"$(message)\"}}"; + + installation.Platform = NotificationPlatform.Gcm; + break; + case DeviceType.iOS: + payloadTemplate = "{\"data\":{\"type\":\"#(type)\",\"payload\":\"$(payload)\"}," + + "\"aps\":{\"alert\":null,\"badge\":null,\"content-available\":1}}"; + messageTemplate = "{\"data\":{\"type\":\"#(type)\"}," + + "\"aps\":{\"alert\":\"$(message)\",\"badge\":null,\"content-available\":1}}"; + badgeMessageTemplate = "{\"data\":{\"type\":\"#(type)\"}," + + "\"aps\":{\"alert\":\"$(message)\",\"badge\":\"#(badge)\",\"content-available\":1}}"; + + installation.Platform = NotificationPlatform.Apns; + break; + case DeviceType.AndroidAmazon: + payloadTemplate = "{\"data\":{\"type\":\"#(type)\",\"payload\":\"$(payload)\"}}"; + messageTemplate = "{\"data\":{\"type\":\"#(type)\",\"message\":\"$(message)\"}}"; + + installation.Platform = NotificationPlatform.Adm; + break; + default: + break; + } + + BuildInstallationTemplate(installation, "payload", payloadTemplate, device.UserId, device.Identifier); + BuildInstallationTemplate(installation, "message", messageTemplate, device.UserId, device.Identifier); + BuildInstallationTemplate(installation, "badgeMessage", badgeMessageTemplate ?? messageTemplate, device.UserId, + device.Identifier); + + await _client.CreateOrUpdateInstallationAsync(installation); + + Console.WriteLine("Added install #" + i + " (" + installation.InstallationId + ")"); + } + } + + private static void BuildInstallationTemplate(Installation installation, string templateId, string templateBody, + Guid userId, string deviceIdentifier) + { + if(templateBody == null) + { + return; + } + + var fullTemplateId = $"template:{templateId}"; + + var template = new InstallationTemplate + { + Body = templateBody, + Tags = new List + { + fullTemplateId, + $"{fullTemplateId}_userId:{userId}" + } + }; + + if(!string.IsNullOrWhiteSpace(deviceIdentifier)) + { + template.Tags.Add($"{fullTemplateId}_deviceIdentifier:{deviceIdentifier}"); + } + + installation.Templates.Add(fullTemplateId, template); + } + + private static async Task ViewAsync(string[] args) + { + var install = await _client.GetInstallationAsync(_viewId); + var json = JsonConvert.SerializeObject(install, Formatting.Indented); + Console.WriteLine(json); + } + } +}