Skip to content

Commit

Permalink
Merge pull request #77 from pusher/develop
Browse files Browse the repository at this point in the history
End to end encryption
  • Loading branch information
Jon Elverkilde authored Apr 13, 2021
2 parents cc03c50 + 31cda17 commit 52388bc
Show file tree
Hide file tree
Showing 42 changed files with 1,431 additions and 860 deletions.
65 changes: 64 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1 +1,64 @@
*.sh eol=lf
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
*.sh eol=lf

###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp

###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary

###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary

###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain
3 changes: 1 addition & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ jobs:
PUSHER_APP_ID: ${{ secrets.CI_APP_ID }}
PUSHER_APP_KEY: ${{ secrets.CI_APP_KEY }}
PUSHER_APP_SECRET: ${{ secrets.CI_APP_SECRET }}
PUSHER_APP_HOST: api-${{ secrets.CI_APP_CLUSTER }}.pusher.com
PUSHER_APP_WEB_SOCKET_HOST: ws-${{ secrets.CI_APP_CLUSTER }}.pusher.com
PUSHER_APP_CLUSTER: ${{ secrets.CI_APP_CLUSTER }}
run: vstest.console.exe "./PusherServer.Tests/bin/Release/net45/PusherServer.Tests.dll" /TestAdapterPath:"./PusherServer.Tests/bin/Release/net45/"
- name: Test pack
run: msbuild /t:Pack /p:configuration=release PusherServer/PusherServer.csproj
3 changes: 1 addition & 2 deletions AppConfig.sample.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@
"AppId": "",
"AppKey": "",
"AppSecret": "",
"HttpHost": "api-{Cluster}.pusher.com",
"WebSocketHost": "ws-{Cluster}.pusher.com"
"Cluster": "mt1"
}
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## 4.5.0
* [ADDED] End-to-end encryption using NaCl.Net.
* [ADDED] EncryptionMasterKey and RestClientTimeout properties to IPusherOptions.
* [ADDED] Cluster property to test application settings.
* [CHANGED] Default timeout from 100 to 30 seconds.

## 4.4.0
* [REMOVED] PusherServer.Core project
* [FIXED] Use .ConfigureAwait(false) on every await
Expand Down
123 changes: 47 additions & 76 deletions PusherServer.Tests/AcceptanceTests/Authenticate.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;
using PusherServer.Tests.Helpers;

Expand All @@ -9,108 +7,81 @@ namespace PusherServer.Tests.AcceptanceTests
[TestFixture]
public class When_authenticating_a_private_subscription
{
[OneTimeSetUp]
public void Setup()
{
PusherClient.Pusher.Trace.Listeners.Add(new ConsoleTraceListener(true));
}

[Test]
public void the_authentication_token_for_a_private_channel_should_be_accepted_by_Pusher()
public async Task the_authentication_token_for_a_private_channel_should_be_accepted_by_Pusher()
{
PusherServer.Pusher pusherServer = new Pusher(Config.AppId, Config.AppKey, Config.AppSecret, new PusherOptions()
{
HostName = Config.HttpHost
});
PusherClient.Pusher pusherClient =
new PusherClient.Pusher(Config.AppKey, new PusherClient.PusherOptions()
{
Authorizer = new InMemoryAuthorizer(pusherServer)
});
pusherClient.Host = Config.WebSocketHost;

string channelName = "private-channel";

bool subscribed = false;
AutoResetEvent reset = new AutoResetEvent(false);

pusherClient.Connected += new PusherClient.ConnectedEventHandler(delegate(object sender)
PusherClient.Pusher pusherClient = new PusherClient.Pusher(Config.AppKey, new PusherClient.PusherOptions
{
Debug.WriteLine("connected");
reset.Set();
Authorizer = new InMemoryAuthorizer(pusherServer),
Cluster = Config.Cluster,
TraceLogger = new PusherClient.TraceLogger(),
});

Debug.WriteLine("connecting");
pusherClient.Connect();
string channelName = "private-channel";

Debug.WriteLine("waiting to connect");
reset.WaitOne(TimeSpan.FromSeconds(5));
await pusherClient.ConnectAsync().ConfigureAwait(false);

Debug.WriteLine("subscribing");
var channel = pusherClient.Subscribe(channelName);
channel.Subscribed += new PusherClient.SubscriptionEventHandler(delegate(object s)
{
Debug.WriteLine("subscribed");
subscribed = true;
reset.Set();
});
var channel = await pusherClient.SubscribeAsync(channelName).ConfigureAwait(false);

Debug.WriteLine("waiting to subscribe");
reset.WaitOne(TimeSpan.FromSeconds(5));

Assert.IsTrue(subscribed);
Assert.IsTrue(channel.IsSubscribed, nameof(channel.IsSubscribed));
}

[Test]
public void the_authentication_token_for_a_presence_channel_should_be_accepted_by_Pusher()
public async Task the_authentication_token_for_a_private_encrypted_channel_should_be_accepted_by_Pusher()
{
PusherServer.Pusher pusherServer = new Pusher(Config.AppId, Config.AppKey, Config.AppSecret, new PusherOptions()
{
HostName = Config.HttpHost
HostName = Config.HttpHost,
EncryptionMasterKey = DataHelper.GenerateEncryptionMasterKey(),
});
PusherClient.Pusher pusherClient =
new PusherClient.Pusher(Config.AppKey, new PusherClient.PusherOptions()
{
Authorizer = new InMemoryAuthorizer(
pusherServer,
new PresenceChannelData()
{
user_id = "leggetter",
user_info = new { twitter_id = "@leggetter" }
})
});
pusherClient.Host = Config.WebSocketHost;

string channelName = "presence-channel";

bool subscribed = false;
AutoResetEvent reset = new AutoResetEvent(false);

pusherClient.Connected += new PusherClient.ConnectedEventHandler(delegate(object sender)
PusherClient.Pusher pusherClient = new PusherClient.Pusher(Config.AppKey, new PusherClient.PusherOptions
{
Debug.WriteLine("connected");
reset.Set();
Authorizer = new InMemoryAuthorizer(pusherServer),
Cluster = Config.Cluster,
TraceLogger = new PusherClient.TraceLogger(),
});

Debug.WriteLine("connecting");
pusherClient.Connect();
string channelName = "private-encrypted-channel";

Debug.WriteLine("waiting to connect");
reset.WaitOne(TimeSpan.FromSeconds(10));
await pusherClient.ConnectAsync().ConfigureAwait(false);

Debug.WriteLine("subscribing");
var channel = pusherClient.Subscribe(channelName);
channel.Subscribed += new PusherClient.SubscriptionEventHandler(delegate(object s)
var channel = await pusherClient.SubscribeAsync(channelName).ConfigureAwait(false);

Assert.IsTrue(channel.IsSubscribed, nameof(channel.IsSubscribed));
}

[Test]
public async Task the_authentication_token_for_a_presence_channel_should_be_accepted_by_Pusher()
{
Pusher pusherServer = new Pusher(Config.AppId, Config.AppKey, Config.AppSecret, new PusherOptions
{
Debug.WriteLine("subscribed");
subscribed = true;
reset.Set();
HostName = Config.HttpHost,
});
PusherClient.Pusher pusherClient = new PusherClient.Pusher(Config.AppKey, new PusherClient.PusherOptions
{
Authorizer = new InMemoryAuthorizer(
pusherServer,
new PresenceChannelData()
{
user_id = "leggetter",
user_info = new { twitter_id = "@leggetter" }
}),
Cluster = Config.Cluster,
TraceLogger = new PusherClient.TraceLogger(),
});

string channelName = "presence-channel";

await pusherClient.ConnectAsync().ConfigureAwait(false);

Debug.WriteLine("waiting to subscribe");
reset.WaitOne(TimeSpan.FromSeconds(5));
var channel = await pusherClient.SubscribePresenceAsync<PresenceChannelData>(channelName).ConfigureAwait(false);

Assert.IsTrue(subscribed);
Assert.IsTrue(channel.IsSubscribed, nameof(channel.IsSubscribed));
}
}
}
51 changes: 15 additions & 36 deletions PusherServer.Tests/AcceptanceTests/ChannelState.cs
Original file line number Diff line number Diff line change
@@ -1,42 +1,36 @@
using System;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks;
using NUnit.Framework;
using PusherServer.Tests.Helpers;

namespace PusherServer.Tests.AcceptanceTests
{
[TestFixture]
public class When_querying_a_Channel
public class When_querying_a_channel
{
[Test]
public async Task It_should_return_the_state_asynchronously_When_given_a_channel_name_that_exists()
public async Task It_should_return_the_state_asynchronously_when_given_a_channel_name_that_exists()
{
var channelName = "presence-state-channel-async-1";
var reset = new AutoResetEvent(false);

var pusherServer = ClientServerFactory.CreateServer();
var pusherClient = ClientServerFactory.CreateClient(pusherServer, reset, channelName);
await ClientServerFactory.CreateClientAsync(pusherServer, channelName).ConfigureAwait(false);

var info = new { info = "user_count" };
var response = await pusherServer.FetchStateForChannelAsync<ChannelStateMessage>(channelName, info).ConfigureAwait(false);

reset.Set();

Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
Assert.AreEqual(1, response.Data.User_Count);
}

[Test]
public async Task It_should_return_the_state_asynchronously_When_given_a_channel_name_that_exists_and_no_info_object_is_provided()
public async Task It_should_return_the_state_asynchronously_when_given_a_channel_name_that_exists_and_no_info_object_is_provided()
{
var reset = new AutoResetEvent(false);

var channelName = "presence-state-channel-async-1";

var pusherServer = ClientServerFactory.CreateServer();
var pusherClient = ClientServerFactory.CreateClient(pusherServer, reset, channelName);
await ClientServerFactory.CreateClientAsync(pusherServer, channelName).ConfigureAwait(false);

var response = await pusherServer.FetchStateForChannelAsync<ChannelStateMessage>(channelName).ConfigureAwait(false);

Expand All @@ -45,14 +39,12 @@ public async Task It_should_return_the_state_asynchronously_When_given_a_channel
}

[Test]
public async Task It_should_not_return_the_state_based_asynchronously_When_given_a_channel_name_that_exists_an_bad_attributes()
public async Task It_should_not_return_the_state_based_asynchronously_when_given_a_channel_name_that_exists_an_bad_attributes()
{
var reset = new AutoResetEvent(false);

var channelName = "presence-state-channel-async-2";

var pusherServer = ClientServerFactory.CreateServer();
var pusherClient = ClientServerFactory.CreateClient(pusherServer, reset, channelName);
await ClientServerFactory.CreateClientAsync(pusherServer, channelName).ConfigureAwait(false);

var info = new { info = "does-not-exist" };

Expand Down Expand Up @@ -111,62 +103,49 @@ private class ChannelStateMessage
}

[TestFixture]
public class When_querying_Multiple_Channels
public class When_querying_multiple_channels
{
[Test]
public async Task It_should_return_the_state_asynchronously_When_given_a_channel_name_that_exists()
public async Task It_should_return_the_state_asynchronously_when_given_a_channel_name_that_exists()
{
var reset = new AutoResetEvent(false);

var channelName = "presence-multiple-state-channel-async-3";

var pusherServer = ClientServerFactory.CreateServer();
var pusherClient = ClientServerFactory.CreateClient(pusherServer, reset, channelName);
await ClientServerFactory.CreateClientAsync(pusherServer, channelName).ConfigureAwait(false);

var info = new { info = "user_count", filter_by_prefix = "presence-" };

var result = await pusherServer.FetchStateForChannelsAsync<object>(info).ConfigureAwait(false);

reset.Set();

Assert.AreEqual(HttpStatusCode.OK, result.StatusCode);

Assert.AreEqual(1, ((Newtonsoft.Json.Linq.JValue)((result.Data as Newtonsoft.Json.Linq.JObject)["channels"]["presence-multiple-state-channel-async-3"]["user_count"])).Value);
}

[Test]
public async Task It_should_return_the_state_asynchronously_When_given_a_channel_name_that_exists_and_no_info_object_is_provided()
public async Task It_should_return_the_state_asynchronously_when_given_a_channel_name_that_exists_and_no_info_object_is_provided()
{
var reset = new AutoResetEvent(false);

var channelName = "presence-multiple-state-channel-async-3";

var pusherServer = ClientServerFactory.CreateServer();
var pusherClient = ClientServerFactory.CreateClient(pusherServer, reset, channelName);
await ClientServerFactory.CreateClientAsync(pusherServer, channelName).ConfigureAwait(false);

var result = await pusherServer.FetchStateForChannelsAsync<object>().ConfigureAwait(false);

reset.Set();

Assert.AreEqual(HttpStatusCode.OK, result.StatusCode);
}

[Test]
public async Task It_should_not_return_the_state_asynchronously_based_When_given_a_channel_name_that_exists_an_bad_attributes()
public async Task It_should_not_return_the_state_asynchronously_based_when_given_a_channel_name_that_exists_an_bad_attributes()
{
AutoResetEvent reset = new AutoResetEvent(false);

string channelName = "presence-multiple-state-channel-async-4";

var pusherServer = ClientServerFactory.CreateServer();
var pusherClient = ClientServerFactory.CreateClient(pusherServer, reset, channelName);
await ClientServerFactory.CreateClientAsync(pusherServer, channelName).ConfigureAwait(false);

var info = new { info = "does-not-exist" };

var result = await pusherServer.FetchStateForChannelsAsync<object>(info).ConfigureAwait(false);

reset.Set();

Assert.AreEqual(HttpStatusCode.BadRequest, result.StatusCode);
StringAssert.IsMatch("info should be a comma separated list of attributes", result.Body);
}
Expand Down
Loading

0 comments on commit 52388bc

Please sign in to comment.