├── .gitignore
├── PusherRESTDotNet.1.2.dotCover
├── PusherRESTDotNet.Tests
├── AcceptanceTests
│ └── PusherProviderTests.cs
├── App.config.template
├── Properties
│ └── AssemblyInfo.cs
├── PusherRESTDotNet.Tests.csproj
└── UnitTests
│ ├── ObjectPusherRequestTests.cs
│ └── PusherProviderTests.cs
├── PusherRESTDotNet.sln
├── PusherRESTDotNet
├── Authentication
│ ├── AuthData.cs
│ ├── AuthSignatureHelper.cs
│ ├── BasicUserInfo.cs
│ ├── PresenceChannelData.cs
│ └── PusherAuthenticationHelper.cs
├── IPusherProvider.cs
├── ObjectPusherRequest.cs
├── Properties
│ └── AssemblyInfo.cs
├── PusherProvider.cs
├── PusherRESTDotNet.csproj
├── PusherRESTDotNet.nuspec
├── PusherRequest.cs
└── SimplePusherRequest.cs
├── README.md
└── lib
├── Newtonsoft.Json.dll
├── Newtonsoft.Json.pdb
├── Newtonsoft.Json.xml
├── Rhino.Mocks.dll
├── Rhino.Mocks.xml
├── nunit.framework.dll
└── nunit.framework.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | _ReSharper.*/
2 | _UpgradeReport_Files
3 | UpgradeLog.XML
4 | Backup
5 | [Bb]in
6 | [Oo]bj
7 | *.suo
8 | *.user
9 | PusherDotNet.Tests/App.config
10 | PusherRESTDotNet/PusherRESTDotNet.1.0.nupkg
11 | packages/
12 | PusherRESTDotNet.sln.docstates
--------------------------------------------------------------------------------
/PusherRESTDotNet.1.2.dotCover:
--------------------------------------------------------------------------------
1 |
2 |
3 | C:\projects\pusherrestdotnet
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/PusherRESTDotNet.Tests/AcceptanceTests/PusherProviderTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Configuration;
3 | using System.Net;
4 | using NUnit.Framework;
5 | using PusherRESTDotNet.Authentication;
6 |
7 | namespace PusherRESTDotNet.Tests.AcceptanceTests
8 | {
9 | [TestFixture]
10 | public class PusherProviderTests
11 | {
12 | private PusherProvider _defaultProvider;
13 | string applicationId = ConfigurationManager.AppSettings["applicationId"];
14 | string applicationKey = ConfigurationManager.AppSettings["applicationKey"];
15 | string applicationSecret = ConfigurationManager.AppSettings["applicationSecret"];
16 |
17 | public void SetupDefaultProvider()
18 | {
19 | if (String.IsNullOrEmpty(applicationId))
20 | Assert.Fail("applicationId not specified in app.config appSettings");
21 | if (String.IsNullOrEmpty(applicationKey))
22 | Assert.Fail("applicationKey not specified in app.config appSettings");
23 | if (String.IsNullOrEmpty(applicationSecret))
24 | Assert.Fail("applicationSecret not specified in app.config appSettings");
25 |
26 | _defaultProvider = new PusherProvider(applicationId, applicationKey, applicationSecret);
27 | }
28 |
29 | [Test]
30 | [Explicit("Set your credentials in app.config for this test to pass")]
31 | public void CanTriggerPush()
32 | {
33 | SetupDefaultProvider();
34 | var request = new TestPusherRequest("test_channel", "my_event", @"{""some"":""data""}");
35 |
36 | _defaultProvider.Trigger(request);
37 | }
38 |
39 | [Test]
40 | [Explicit("Set your credentials in app.config for this test to pass")]
41 | public void CanTriggerPushWithAnonymousObject()
42 | {
43 | SetupDefaultProvider();
44 | var request = new ObjectPusherRequest("test_channel", "my_event", new
45 | {
46 | some = "data"
47 | });
48 |
49 | _defaultProvider.Trigger(request);
50 | }
51 |
52 | [Test]
53 | [ExpectedException(typeof(WebException))]
54 | public void BlowsUpOnTriggerPushWithBadCredentials()
55 | {
56 | var request = new TestPusherRequest("test_channel", "my_event", @"{""some"":""data""}");
57 |
58 | var provider = new PusherProvider("meh", "foo", "bar");
59 | provider.Trigger(request);
60 | }
61 |
62 | public class TestPusherRequest : PusherRequest
63 | {
64 | private readonly string _jsonData;
65 |
66 | public TestPusherRequest(string channelName, string eventName, string jsonData)
67 | : base(channelName, eventName)
68 | {
69 | _jsonData = jsonData;
70 | }
71 |
72 | public override string JsonData
73 | {
74 | get { return _jsonData; }
75 | }
76 | }
77 | }
78 | }
--------------------------------------------------------------------------------
/PusherRESTDotNet.Tests/App.config.template:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/PusherRESTDotNet.Tests/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("PusherRESTDotNet.Tests")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Microsoft")]
12 | [assembly: AssemblyProduct("PusherRESTDotNet.Tests")]
13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("423a5655-b69c-4668-86dc-f7d3f57bd0de")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/PusherRESTDotNet.Tests/PusherRESTDotNet.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 9.0.30729
7 | 2.0
8 | {29ADB209-999D-4A86-A006-01609B6B670D}
9 | Library
10 | Properties
11 | PusherRESTDotNet.Tests
12 | PusherDotNet.Tests
13 | v4.0
14 | 512
15 | false
16 | publish\
17 | true
18 | Disk
19 | false
20 | Foreground
21 | 7
22 | Days
23 | false
24 | false
25 | true
26 | 0
27 | 1.0.0.%2a
28 | false
29 | true
30 |
31 |
32 | true
33 | full
34 | false
35 | bin\Debug\
36 | DEBUG;TRACE
37 | prompt
38 | 4
39 | AllRules.ruleset
40 |
41 |
42 | pdbonly
43 | true
44 | bin\Release\
45 | TRACE
46 | prompt
47 | 4
48 | AllRules.ruleset
49 |
50 |
51 |
52 | ..\lib\nunit.framework.dll
53 |
54 |
55 | ..\lib\Rhino.Mocks.dll
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | False
78 | Microsoft .NET Framework 4 %28x86 and x64%29
79 | true
80 |
81 |
82 | False
83 | .NET Framework 3.5 SP1 Client Profile
84 | false
85 |
86 |
87 | False
88 | .NET Framework 3.5 SP1
89 | false
90 |
91 |
92 | False
93 | Windows Installer 3.1
94 | true
95 |
96 |
97 |
98 |
99 | {FEDAD44D-208E-4F99-BE08-6C1257B59D4A}
100 | PusherRESTDotNet
101 |
102 |
103 |
104 |
111 |
--------------------------------------------------------------------------------
/PusherRESTDotNet.Tests/UnitTests/ObjectPusherRequestTests.cs:
--------------------------------------------------------------------------------
1 | using NUnit.Framework;
2 |
3 | namespace PusherRESTDotNet.Tests
4 | {
5 | [TestFixture]
6 | public class ObjectPusherRequestTests
7 | {
8 | [Test]
9 | public void SerializesObjectToJsonData()
10 | {
11 | var request = new ObjectPusherRequest("test_channel", "my_event", new { some = "data" });
12 |
13 | Assert.That(request.JsonData, Is.EqualTo(@"{""some"":""data""}"));
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/PusherRESTDotNet.Tests/UnitTests/PusherProviderTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Configuration;
3 | using System.Net;
4 | using NUnit.Framework;
5 | using PusherRESTDotNet.Authentication;
6 |
7 | namespace PusherRESTDotNet.Tests.UnitTests
8 | {
9 | [TestFixture]
10 | public class PusherProviderTests
11 | {
12 | [Test]
13 | public void AuthenticationStringIsCorrectlyFormedForPrivateChannel()
14 | {
15 | var appId = "1000";
16 | var appKey = "myAppKey";
17 | var appSecret = "myAppSecret";
18 | var channelName = "private-channel";
19 | var socketId = "socket_id";
20 | var helper = new PusherAuthenticationHelper(appId, appKey, appSecret);
21 | var expected = helper.CreateAuthenticatedString(socketId, channelName);
22 |
23 | IPusherProvider provider = new PusherProvider(appId, appKey, appSecret);
24 | string auth = provider.Authenticate(channelName, socketId);
25 |
26 | Assert.IsNotNullOrEmpty(auth);
27 | Assert.AreEqual(expected, auth);
28 | }
29 |
30 | [Test]
31 | public void AuthenticationStringIsCorrectlyFormedForPresenceChannel()
32 | {
33 | var appId = "1000";
34 | var appKey = "myAppKey";
35 | var appSecret = "myAppSecret";
36 | var channelName = "presence-channel";
37 | var presenceChannelData = new PresenceChannelData()
38 | {
39 | user_id = "leggetter",
40 | user_info = new { name = "Phil Leggetter", twitter = "@leggetter" }
41 | };
42 | var socketId = "socket_id";
43 | var helper = new PusherAuthenticationHelper(appId, appKey, appSecret);
44 | string expected = helper.CreateAuthenticatedString(socketId, channelName, presenceChannelData);
45 |
46 | IPusherProvider provider = new PusherProvider(appId, appKey, appSecret);
47 | string auth = provider.Authenticate(channelName, socketId, presenceChannelData);
48 |
49 | Assert.IsNotNullOrEmpty(auth);
50 | Assert.AreEqual(expected, auth);
51 | }
52 | }
53 | }
--------------------------------------------------------------------------------
/PusherRESTDotNet.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 11.00
3 | # Visual Studio 2010
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PusherRESTDotNet", "PusherRESTDotNet\PusherRESTDotNet.csproj", "{FEDAD44D-208E-4F99-BE08-6C1257B59D4A}"
5 | EndProject
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PusherRESTDotNet.Tests", "PusherRESTDotNet.Tests\PusherRESTDotNet.Tests.csproj", "{29ADB209-999D-4A86-A006-01609B6B670D}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Files", "Files", "{13FCFB53-1898-4AE9-B229-F917B8F52DB2}"
9 | ProjectSection(SolutionItems) = preProject
10 | PusherRESTDotNet\PusherRESTDotNet.nuspec = PusherRESTDotNet\PusherRESTDotNet.nuspec
11 | README.md = README.md
12 | EndProjectSection
13 | EndProject
14 | Global
15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
16 | Debug|Any CPU = Debug|Any CPU
17 | Release|Any CPU = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
20 | {FEDAD44D-208E-4F99-BE08-6C1257B59D4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {FEDAD44D-208E-4F99-BE08-6C1257B59D4A}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {FEDAD44D-208E-4F99-BE08-6C1257B59D4A}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {FEDAD44D-208E-4F99-BE08-6C1257B59D4A}.Release|Any CPU.Build.0 = Release|Any CPU
24 | {29ADB209-999D-4A86-A006-01609B6B670D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
25 | {29ADB209-999D-4A86-A006-01609B6B670D}.Debug|Any CPU.Build.0 = Debug|Any CPU
26 | {29ADB209-999D-4A86-A006-01609B6B670D}.Release|Any CPU.ActiveCfg = Release|Any CPU
27 | {29ADB209-999D-4A86-A006-01609B6B670D}.Release|Any CPU.Build.0 = Release|Any CPU
28 | EndGlobalSection
29 | GlobalSection(SolutionProperties) = preSolution
30 | HideSolutionNode = FALSE
31 | EndGlobalSection
32 | EndGlobal
33 |
--------------------------------------------------------------------------------
/PusherRESTDotNet/Authentication/AuthData.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Runtime.Serialization;
6 |
7 | namespace PusherRESTDotNet.Authentication
8 | {
9 | [DataContract]
10 | internal class AuthData
11 | {
12 | [DataMember]
13 | public string auth { get; set; }
14 |
15 | [DataMember]
16 | public string channel_data { get; set; }
17 | }
18 | }
--------------------------------------------------------------------------------
/PusherRESTDotNet/Authentication/AuthSignatureHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Security.Cryptography;
6 |
7 | namespace PusherRESTDotNet.Authentication
8 | {
9 | internal static class AuthSignatureHelper
10 | {
11 | public static string GetAuthString(string authData, string applicationSecretKey)
12 | {
13 | var hmacsha256 = new HMACSHA256(Encoding.UTF8.GetBytes(applicationSecretKey));
14 | var hash = hmacsha256.ComputeHash(Encoding.UTF8.GetBytes(authData));
15 |
16 | return BytesToHex(hash);
17 | }
18 |
19 | private static string BytesToHex(IEnumerable byteArray)
20 | {
21 | return String.Concat(byteArray.Select(bytes => bytes.ToString("x2")).ToArray());
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/PusherRESTDotNet/Authentication/BasicUserInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Runtime.Serialization;
6 |
7 | namespace PusherRESTDotNet.Authentication
8 | {
9 | [DataContract]
10 | public class BasicUserInfo
11 | {
12 | [DataMember]
13 | public string name { get; set; }
14 | }
15 | }
--------------------------------------------------------------------------------
/PusherRESTDotNet/Authentication/PresenceChannelData.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Runtime.Serialization;
6 |
7 | namespace PusherRESTDotNet.Authentication
8 | {
9 | [DataContract]
10 | public class PresenceChannelData
11 | {
12 | [DataMember]
13 | public string user_id { get; set; }
14 |
15 | [DataMember]
16 | public object user_info { get; set; }
17 | }
18 | }
--------------------------------------------------------------------------------
/PusherRESTDotNet/Authentication/PusherAuthenticationHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using Newtonsoft.Json;
6 |
7 | namespace PusherRESTDotNet.Authentication
8 | {
9 | public class PusherAuthenticationHelper
10 | {
11 | private string applicationId;
12 | private string applicationKey;
13 | private string applicationSecret;
14 |
15 | public PusherAuthenticationHelper(string applicationId, string applicationKey, string applicationSecret)
16 | {
17 | this.applicationId = applicationId;
18 | this.applicationKey = applicationKey;
19 | this.applicationSecret = applicationSecret;
20 | }
21 |
22 | public string CreateAuthenticatedString(string socketID, string channelName)
23 | {
24 | string auth = AuthSignatureHelper.GetAuthString(socketID + ":" + channelName, applicationSecret);
25 |
26 | AuthData data = new AuthData();
27 | data.auth = applicationKey + ":" + auth;
28 |
29 | string json = JsonConvert.SerializeObject(data);
30 | return json;
31 | }
32 |
33 | public string CreateAuthenticatedString(string socketID, string channelName, PresenceChannelData channelData)
34 | {
35 | string channel = (channelData == null?"":JsonConvert.SerializeObject(channelData));
36 | string auth = AuthSignatureHelper.GetAuthString(socketID + ":" + channelName + ":" + channel, applicationSecret);
37 |
38 | AuthData data = new AuthData();
39 | data.auth = applicationKey + ":" + auth;
40 | data.channel_data = channel;
41 |
42 | string json = JsonConvert.SerializeObject(data);
43 | return json;
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/PusherRESTDotNet/IPusherProvider.cs:
--------------------------------------------------------------------------------
1 | using PusherRESTDotNet.Authentication;
2 | namespace PusherRESTDotNet
3 | {
4 | public interface IPusherProvider
5 | {
6 | ///
7 | /// Sends the request. Will throw a WebException if anything other than a 202 response is encountered
8 | ///
9 | ///
10 | void Trigger(PusherRequest request);
11 |
12 | ///
13 | /// Creates and authenticated string for the given channel name and socket ID
14 | ///
15 | /// The channel to be authenticated
16 | /// The socket ID to be authenticated
17 | /// An authenticated string
18 | string Authenticate(string channelName, string socketId);
19 |
20 | ///
21 | /// Creates and authenticated string for the given channel name, socket ID and channel data
22 | ///
23 | /// The channel to be authenticated
24 | /// The socket ID to be authenticated
25 | /// The presence channel data
26 | /// An authenticated string
27 | string Authenticate(string channelName, string socketId, PresenceChannelData presenceChannelData);
28 | }
29 | }
--------------------------------------------------------------------------------
/PusherRESTDotNet/ObjectPusherRequest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Web.Script.Serialization;
3 |
4 | namespace PusherRESTDotNet
5 | {
6 | ///
7 | /// Provides a simple wrapper that provides JsonData by serializing an object using a
8 | ///
9 | public class ObjectPusherRequest : PusherRequest
10 | {
11 | private readonly string _serializedData;
12 |
13 | public ObjectPusherRequest(string channelName, string eventName, object data)
14 | : base(channelName, eventName)
15 | {
16 | _serializedData = new JavaScriptSerializer().Serialize(data);
17 | }
18 |
19 | public override string JsonData
20 | {
21 | get { return _serializedData; }
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/PusherRESTDotNet/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("PusherRESTDotNet")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Microsoft")]
12 | [assembly: AssemblyProduct("PusherRESTDotNet")]
13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("0508dca3-1235-4d46-b7e5-e9051e71c6a2")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | [assembly: AssemblyVersion("1.1.0.*")]
33 | [assembly: AssemblyFileVersion("1.1.*.*")]
34 |
--------------------------------------------------------------------------------
/PusherRESTDotNet/PusherProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Net;
5 | using System.Security.Cryptography;
6 | using System.Text;
7 | using PusherRESTDotNet.Authentication;
8 |
9 | namespace PusherRESTDotNet
10 | {
11 | public class PusherProvider : IPusherProvider
12 | {
13 | private const string _host = "api.pusherapp.com";
14 | private readonly string _applicationId;
15 | private readonly string _applicationKey;
16 | private readonly string _applicationSecret;
17 | private readonly PusherAuthenticationHelper _authHelper;
18 | private readonly IWebProxy _webProxy;
19 |
20 | public PusherProvider(string applicationId, string applicationKey, string applicationSecret, IWebProxy webProxy = null)
21 | {
22 | if (String.IsNullOrEmpty(applicationId))
23 | throw new ArgumentNullException("applicationId");
24 | if (String.IsNullOrEmpty(applicationKey))
25 | throw new ArgumentNullException("applicationKey");
26 | if (String.IsNullOrEmpty(applicationSecret))
27 | throw new ArgumentNullException("applicationSecret");
28 |
29 | _applicationSecret = applicationSecret;
30 | _applicationKey = applicationKey;
31 | _applicationId = applicationId;
32 | _webProxy = webProxy;
33 | _authHelper = new PusherAuthenticationHelper(_applicationId, _applicationKey, _applicationSecret);
34 | }
35 |
36 | ///
37 | /// Sends the request. Will throw a WebException if anything other than a 202 response is encountered
38 | ///
39 | ///
40 | public void Trigger(PusherRequest request)
41 | {
42 | var requestUrl = String.Format("http://{0}{1}?{2}&auth_signature={3}",
43 | _host,
44 | GetBaseUri(request),
45 | GetQueryString(request),
46 | GetHmac256(request));
47 |
48 | using(var client = new WebClient())
49 | {
50 | if(_webProxy != null)
51 | {
52 | client.Proxy = _webProxy;
53 | }
54 | client.Encoding = Encoding.UTF8;
55 | client.UploadString(requestUrl, request.JsonData);
56 | }
57 | }
58 |
59 | private string GetBaseUri(PusherRequest request)
60 | {
61 | return String.Format("/apps/{0}/channels/{1}/events", _applicationId, request.ChannelName);
62 | }
63 |
64 | private string GetQueryString(PusherRequest request)
65 | {
66 | var output = String.Format("auth_key={0}&auth_timestamp={1}&auth_version=1.0&body_md5={2}&name={3}",
67 | _applicationKey,
68 | (int)((DateTime.UtcNow - new DateTime(1970,1,1)).TotalSeconds),
69 | GetMd5Hash(request.JsonData),
70 | request.EventName);
71 |
72 | return String.IsNullOrEmpty(request.SocketId) ? output : String.Format("{0}&socket_id={1}", output, request.SocketId);
73 | }
74 |
75 | private static string GetMd5Hash(string jsonData)
76 | {
77 | var hash = new MD5CryptoServiceProvider().ComputeHash(Encoding.UTF8.GetBytes(jsonData));
78 | return BytesToHex(hash);
79 | }
80 |
81 | private string GetHmac256(PusherRequest request)
82 | {
83 | var data = String.Format("POST\n{0}\n{1}", GetBaseUri(request), GetQueryString(request));
84 | var hmacsha256 = new HMACSHA256(Encoding.UTF8.GetBytes(_applicationSecret));
85 | var hash = hmacsha256.ComputeHash(Encoding.UTF8.GetBytes(data));
86 |
87 | return BytesToHex(hash);
88 | }
89 |
90 | private static string BytesToHex(IEnumerable byteArray)
91 | {
92 | return String.Concat(byteArray.Select(bytes => bytes.ToString("x2")).ToArray());
93 | }
94 |
95 |
96 | public string Authenticate(string channelName, string socketId)
97 | {
98 | return _authHelper.CreateAuthenticatedString(socketId, channelName);
99 | }
100 |
101 |
102 | public string Authenticate(string channelName, string socketId, PresenceChannelData presenceChannelData)
103 | {
104 | return _authHelper.CreateAuthenticatedString(socketId, channelName, presenceChannelData);
105 | }
106 | }
107 | }
--------------------------------------------------------------------------------
/PusherRESTDotNet/PusherRESTDotNet.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 8.0.30703
7 | 2.0
8 | {FEDAD44D-208E-4F99-BE08-6C1257B59D4A}
9 | Library
10 | Properties
11 | PusherRESTDotNet
12 | PusherRESTDotNet
13 | v3.5
14 | 512
15 | publish\
16 | true
17 | Disk
18 | false
19 | Foreground
20 | 7
21 | Days
22 | false
23 | false
24 | true
25 | 0
26 | 1.0.0.%2a
27 | false
28 | false
29 | true
30 |
31 |
32 | true
33 | full
34 | false
35 | bin\Debug\
36 | DEBUG;TRACE
37 | prompt
38 | 4
39 | AllRules.ruleset
40 |
41 |
42 | pdbonly
43 | true
44 | bin\Release\
45 | TRACE
46 | prompt
47 | 4
48 | AllRules.ruleset
49 |
50 |
51 |
52 | ..\lib\Newtonsoft.Json.dll
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 | False
80 | .NET Framework 3.5 SP1 Client Profile
81 | false
82 |
83 |
84 | False
85 | .NET Framework 3.5 SP1
86 | true
87 |
88 |
89 | False
90 | Windows Installer 3.1
91 | true
92 |
93 |
94 |
95 |
102 |
--------------------------------------------------------------------------------
/PusherRESTDotNet/PusherRESTDotNet.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $id$
5 | $version$
6 | Graham Scott, Phil Leggetter
7 | $author$
8 | https://github.com/leggetter/pusher-rest-dotnet
9 | false
10 | The Pusher (http://pusher.com) REST library provides a simple way of pushing realtime messages into Pusher via the Pusher REST API.
11 | realtime push websockets REST API Pusher
12 |
13 |
--------------------------------------------------------------------------------
/PusherRESTDotNet/PusherRequest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace PusherRESTDotNet
4 | {
5 | ///
6 | /// Abstract base class for pusher requests
7 | ///
8 | public abstract class PusherRequest
9 | {
10 | protected PusherRequest(string channelName, string eventName)
11 | {
12 | ChannelName = channelName;
13 | EventName = eventName;
14 | }
15 |
16 | public string EventName { get; private set; }
17 | public string ChannelName { get; private set; }
18 | public string SocketId { get; set; }
19 |
20 | public abstract string JsonData { get; }
21 | }
22 | }
--------------------------------------------------------------------------------
/PusherRESTDotNet/SimplePusherRequest.cs:
--------------------------------------------------------------------------------
1 | namespace PusherRESTDotNet
2 | {
3 | public class SimplePusherRequest : PusherRequest
4 | {
5 | private readonly string _jsonData;
6 |
7 | public SimplePusherRequest(string channelName, string eventName, string jsonData)
8 | : base(channelName, eventName)
9 | {
10 | _jsonData = jsonData;
11 | }
12 |
13 | public override string JsonData
14 | {
15 | get { return _jsonData; }
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | THIS PROJECT IS DORMANT, PLEASE USE https://github.com/leggetter/pusher-dotnet-server INSTEAD
2 |
3 |
4 | The Pusher REST .NET project is implementation of the Pusher REST API in C#.
5 |
6 | It provides functionality to let you trigger events using the Pusher REST API in addition to
7 | [authenticating](http://pusher.com/docs/authenticating_users) user subscription request to
8 | [private](http://pusher.com/docs/private_channels) and [presence](http://pusher.com/docs/presence) channels.
9 |
10 | ## Trigger events
11 |
12 | Events can be triggered with any type of data which is then serialized to JSON.
13 |
14 | var provider = new PusherProvider(applicationId, applicationKey, applicationSecret);
15 | var request = new ObjectPusherRequest("test_channel", "my_event", new
16 | {
17 | some = "data"
18 | });
19 |
20 | provider.Trigger(request);
21 |
22 | ## Authenticate Private Channels
23 |
24 | Assuming that the running application is an ASP.NET app then the private channels are
25 | authenticated using the `IPusherProvider.Authenticate` method with the values for the
26 | channel name and the socket ID retrieved from the `Request` object.
27 |
28 | var provider = new PusherProvider(appId, appKey, appSecret);
29 | string auth = provider.Authenticate(Request["channel_name"], Request["socket_id");
30 | Response.Write(auth);
31 |
32 | ## Authenticate Presence Channels
33 |
34 | Presence channels are authenticated in much the same way as private channels. The only difference
35 | is that the channel data must also be passed to the `IPusherProvider.Authenticate` method so
36 | that it can be hashed within the authentication string.
37 |
38 | var provider = new PusherProvider(appId, appKey, appSecret);
39 | string auth = provider.Authenticate(Request["channel_name"], Request["socket_id");
40 | Response.Write(auth);
41 |
--------------------------------------------------------------------------------
/lib/Newtonsoft.Json.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grahamscott/pusherrestdotnet/f2af4bd6e0cddbedeb7b53928e323b3d883794a2/lib/Newtonsoft.Json.dll
--------------------------------------------------------------------------------
/lib/Newtonsoft.Json.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grahamscott/pusherrestdotnet/f2af4bd6e0cddbedeb7b53928e323b3d883794a2/lib/Newtonsoft.Json.pdb
--------------------------------------------------------------------------------
/lib/Rhino.Mocks.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grahamscott/pusherrestdotnet/f2af4bd6e0cddbedeb7b53928e323b3d883794a2/lib/Rhino.Mocks.dll
--------------------------------------------------------------------------------
/lib/nunit.framework.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grahamscott/pusherrestdotnet/f2af4bd6e0cddbedeb7b53928e323b3d883794a2/lib/nunit.framework.dll
--------------------------------------------------------------------------------