public override async Task <string> Authenticate(JsonClient client) { // step1 request: User -> Host: I, A = g^a (identifies self, a = random number) var clientEphemeral = SrpClient.GenerateEphemeral(); var request1 = new AuthRequest(); request1.Parameters[SrpProtocolConstants.UserNameKey] = UserName; request1.Parameters[SrpProtocolConstants.ClientPublicEphemeralKey] = clientEphemeral.Public; // step1 response: Host -> User: s, B = kv + g^b (sends salt, b = random number) var response1 = await client.Call(request1); var salt = response1.GetSalt(); var serverPublicEphemeral = response1.GetServerPublicEphemeral(); if (string.IsNullOrWhiteSpace(salt) || string.IsNullOrWhiteSpace(serverPublicEphemeral)) { throw new AuthFailedException("Server doesn't support SRP authentication protocol"); } // step2 request: User -> Host: M = H(H(N) xor H(g), H(I), s, A, B, K) var privateKey = SrpClient.DerivePrivateKey(salt, UserName, Password); var clientSession = SrpClient.DeriveSession(clientEphemeral.Secret, serverPublicEphemeral, salt, UserName, privateKey); var request2 = new AuthRequest(); request2.Parameters[SrpProtocolConstants.ClientSessionProofKey] = clientSession.Proof; // step2 response: Host -> User: H(A, M, K) var response2 = await client.Call(request2); var serverSessionProof = response2.GetServerSessionProof(); SrpClient.VerifySession(clientEphemeral.Public, clientSession, serverSessionProof); return(response2.SessionId); }
protected async Task CallDisconnectAndReconnectCore(JsonServer js, JsonClient jc, ICredentials credentials = null) { js.ProductName = "My awesome server"; js.ProductVersion = "1.2.3.4"; js.Start(); // connect, call, disconnect await Assert_NotTimedOut(jc.ConnectAsync(credentials), "connect"); var result = await Assert_NotTimedOut(jc.Call(new VersionRequest()), "jc.Call(VersionRequest)"); Assert.NotNull(result); Assert.AreEqual(js.ProductName, result.ProductName); Assert.AreEqual(js.ProductVersion, result.ProductVersion); await Assert_NotTimedOut(jc.DisconnectAsync(), "disconnect"); // reconnect, call, disconnect await Assert_NotTimedOut(jc.ConnectAsync(credentials), "reconnect"); result = await Assert_NotTimedOut(jc.Call(new VersionRequest()), "jc.Call(VersionRequest) after reconnect"); Assert.NotNull(result); Assert.AreEqual(js.ProductName, result.ProductName); Assert.AreEqual(js.ProductVersion, result.ProductVersion); await Assert_NotTimedOut(jc.DisconnectAsync(), "disconnect completely"); Assert.AreEqual(0, jc.PendingMessages.Count); }
protected async Task CallGenericMessagesCore(JsonServer js, JsonClient jc, ICredentials credentials = null) { js.Start(); await jc.ConnectAsync(); var intMsg = new GenericRequest <int> { Value = 1 }; var intResult = await jc.Call(intMsg); Assert.AreEqual(2, intResult.Result); var dtMsg = new GenericRequest <DateTime> { Value = new DateTime(2018, 12, 18) }; var dtResult = await jc.Call(dtMsg); Assert.AreEqual(new DateTime(2019, 12, 18), dtResult.Result); var strMsg = new GenericRequest <string> { Value = "World" }; var strResult = await jc.Call(strMsg); Assert.AreEqual("Hello World!", strResult.Result); var boolMsg = new GenericRequest <bool> { Value = true }; Assert.ThrowsAsync <MethodNotFoundException>(async() => await jc.Call(boolMsg)); // make sure all incoming messages are processed Assert.AreEqual(0, jc.PendingMessages.Count); }
public void JsonClientCallAndNotifyThrowOnNullArguments() { var server = new StubServer(); var client = new StubClient(server); var clientProvider = new StubMessageTypeProvider(); var clientSerializer = new Serializer(); var jc = new JsonClient(client, clientProvider, clientSerializer); Assert.Throws <ArgumentNullException>(() => jc.Notify(null)); Assert.ThrowsAsync <ArgumentNullException>(() => jc.Call(null)); Assert.ThrowsAsync <ArgumentNullException>(() => jc.Call <string>(null)); }
protected virtual async Task CallDelayServiceCore(JsonServer js, JsonClient jc, ICredentials credentials = null) { js.Start(); await jc.ConnectAsync(credentials); await Assert_NotTimedOut(jc.Call(new DelayRequest { Milliseconds = 10 }), "jc.Call(Delay 10)"); await Assert_TimedOut(jc.Call(new DelayRequest { Milliseconds = 200 }), "jc.Call(Delay 200)", Task.Delay(10)); // make sure that await completes before the server is disposed (affects NetMQ server) await Task.Delay(300); }
private async Task CallBuiltinVersionServiceCore(JsonServer js, JsonClient jc, ICredentials credentials = null) { // event handlers var connected = 0; var disconnected = 0; js.ClientConnected += (s, e) => connected++; js.ClientDisconnected += (s, e) => disconnected++; js.UnhandledException += (s, e) => Assert.Fail($"Unhandled server exception: {e.Exception}. Connected: {connected}, disconnected: {disconnected}."); jc.UnhandledException += (s, e) => Assert.Fail($"Unhandled client exception: {e.Exception}. Connected: {connected}, disconnected: {disconnected}."); // start json server and connect the client js.Start(); Assert.IsNull(jc.SessionId); var sessionId = await jc.ConnectAsync(credentials); Assert.IsNotNull(jc.SessionId); Assert.AreEqual(sessionId, jc.SessionId); // call Version var msg = new VersionRequest(); var result = await Assert_NotTimedOut(jc.Call(msg), "jc.Call(VersionRequest)"); Assert.NotNull(result); Assert.AreEqual(nameof(JsonServices), result.ProductName); Assert.NotNull(result.ProductVersion); Assert.NotNull(result.EngineVersion); // make sure all incoming messages are processed Assert.AreEqual(0, jc.PendingMessages.Count); }
public virtual async Task <string> Authenticate(JsonClient client) { var response = await client.Call(new AuthRequest { Parameters = Parameters, }); return(response.SessionId); }
public async Task CallServiceBeforeConnectingShouldFail() { // fake transport and serializer var server = new StubServer(); var client = new StubClient(server); var serializer = new Serializer(); var executor = new StubExecutor(); var provider = new StubMessageTypeProvider(); var js = new JsonServer(server, provider, serializer, executor); var jc = new JsonClient(client, provider, serializer); js.Start(); Assert.ThrowsAsync <AuthRequiredException>(async() => await Assert_NotTimedOut(jc.Call(new GetVersion()), "jc.Call(GetVersion) before Connect")); await Assert_NotTimedOut(jc.ConnectAsync(), "jc.ConnectAsync()"); await Assert_NotTimedOut(jc.Call(new GetVersion()), "jc.Call(GetVersion) after connect"); }
private async Task ExecuteGetVersion(JsonClient client, bool isInternal) { var result = await Assert_NotTimedOut(client.Call(new GetVersion { IsInternal = isInternal }), "StressTest.GetVersion"); var expected = isInternal ? "Version 0.01-alpha, build 12345, by yallie" : "0.01-alpha"; Assert.NotNull(result); Assert.AreEqual(expected, result.Version); }
protected async Task CallGetVersionServiceCore(JsonServer js, JsonClient jc, ICredentials credentials = null) { // event handlers var connected = 0; var disconnected = 0; js.ClientConnected += (s, e) => connected++; js.ClientDisconnected += (s, e) => disconnected++; js.UnhandledException += (s, e) => Assert.Fail($"Unhandled server exception: {e.Exception}. Connected: {connected}, disconnected: {disconnected}."); jc.UnhandledException += (s, e) => Assert.Fail($"Unhandled client exception: {e.Exception}. Connected: {connected}, disconnected: {disconnected}."); // start json server and connect the client js.Start(); Assert.IsNull(jc.SessionId); var sessionId = await jc.ConnectAsync(credentials); Assert.IsNotNull(jc.SessionId); Assert.AreEqual(sessionId, jc.SessionId); // call GetVersion var msg = new GetVersion(); var result = await Assert_NotTimedOut(jc.Call(msg), "jc.Call(msg)"); Assert.NotNull(result); Assert.AreEqual("0.01-alpha", result.Version); // call GetVersion msg = new GetVersion { IsInternal = true }; result = await Assert_NotTimedOut(jc.Call(msg), "jc.Call(msg...IsInternal)"); Assert.NotNull(result); Assert.AreEqual("Version 0.01-alpha, build 12345, by yallie", result.Version); // make sure all incoming messages are processed Assert.AreEqual(0, jc.PendingMessages.Count); }
protected async Task CallDelayServiceAndAbortConnectionCore(JsonServer js, JsonClient jc, ICredentials credentials = null) { js.Start(); await jc.ConnectAsync(credentials); var call = jc.Call(new DelayRequest { Milliseconds = 1000 }); await Task.Delay(100); // make sure that the call was actually sent await jc.Client.DisconnectAsync(); // should fire Disconnected event Assert.ThrowsAsync <ClientDisconnectedException>(async() => await Assert_NotTimedOut(call, "jc.Call(Delay 1000)", Task.Delay(2000))); }
protected async Task CallUnregisteredServiceCore(JsonServer js, JsonClient jc, ICredentials credentials = null) { // event handlers var connected = 0; var disconnected = 0; js.ClientConnected += (s, e) => connected++; js.ClientDisconnected += (s, e) => disconnected++; js.UnhandledException += (s, e) => Assert.Fail($"Unhandled server exception: {e.Exception}. Connected: {connected}, disconnected: {disconnected}."); jc.UnhandledException += (s, e) => Assert.Fail($"Unhandled client exception: {e.Exception}. Connected: {connected}, disconnected: {disconnected}."); // start json server and connect the client js.Start(); await jc.ConnectAsync(credentials); // call UnregisteredService var msg = new UnregisteredService(); var ex = Assert.ThrowsAsync <MethodNotFoundException>(async() => await Assert_NotTimedOut(jc.Call(msg), "jc.Call(UnregisteredService)")); Assert.AreEqual(MethodNotFoundException.ErrorCode, ex.Code); // make sure all incoming messages are processed Assert.AreEqual(0, jc.PendingMessages.Count); }
protected async Task CallCalculateServiceCore(JsonServer js, JsonClient jc, ICredentials credentials = null) { // unhandled exception handlers var connected = 0; var disconnected = 0; js.ClientConnected += (s, e) => connected++; js.ClientDisconnected += (s, e) => disconnected++; js.UnhandledException += (s, e) => Assert.Fail($"Unhandled server exception: {e.Exception}. Connected: {connected}, disconnected: {disconnected}."); jc.UnhandledException += (s, e) => Assert.Fail($"Unhandled client exception: {e.Exception}. Connected: {connected}, disconnected: {disconnected}."); // start json server and connect the client js.Start(); await jc.ConnectAsync(credentials); // normal call var msg = new Calculate { FirstOperand = 353, SecondOperand = 181, Operation = "+", }; var result = await Assert_NotTimedOut(jc.Call(msg), "353 + 181"); Assert.NotNull(result); Assert.AreEqual(534, result.Result); msg.SecondOperand = 333; result = await Assert_NotTimedOut(jc.Call(msg), "353 + 333"); Assert.NotNull(result); Assert.AreEqual(686, result.Result); msg.Operation = "-"; result = await Assert_NotTimedOut(jc.Call(msg), "353 - 333"); Assert.NotNull(result); Assert.AreEqual(20, result.Result); // call with error msg.Operation = "#"; var ex = Assert.ThrowsAsync <InternalErrorException>(async() => await Assert_NotTimedOut(jc.Call(msg), "353 # 333")); // internal server error Assert.AreEqual(-32603, ex.Code); Assert.AreEqual("Internal server error: Bad operation: #", ex.Message); // call with another error msg.Operation = "%"; msg.SecondOperand = 0; ex = Assert.ThrowsAsync <InternalErrorException>(async() => await Assert_NotTimedOut(jc.Call(msg), "353 % 0")); // internal server error Assert.AreEqual(-32603, ex.Code); Assert.AreEqual("Internal server error: Attempted to divide by zero.", ex.Message); // normal call again msg.Operation = "*"; result = await Assert_NotTimedOut(jc.Call(msg), "353 * 0"); Assert.NotNull(result); Assert.AreEqual(0, result.Result); msg.Operation = "+"; msg.SecondOperand = 181; result = await Assert_NotTimedOut(jc.Call(msg), "353 + 181 again"); Assert.NotNull(result); Assert.AreEqual(534, result.Result); // make sure all incoming messages are processed Assert.AreEqual(0, jc.PendingMessages.Count); }
protected async Task TestSubscriptionsAndUnsubscriptionsCore(JsonServer js, JsonClient jc, JsonClient sc, ICredentials credentials = null) { // unhandled exception handlers var connected = 0; var disconnected = 0; js.ClientConnected += (s, e) => connected++; js.ClientDisconnected += (s, e) => disconnected++; js.UnhandledException += (s, e) => Assert.Fail($"Unhandled server exception: {e.Exception}. Connected: {connected}, disconnected: {disconnected}."); jc.UnhandledException += (s, e) => Assert.Fail($"Unhandled client exception in jc (first client): {e.Exception}. Connected: {connected}, disconnected: {disconnected}."); sc.UnhandledException += (s, e) => Assert.Fail($"Unhandled client exception in sc (second client): {e.Exception}. Connected: {connected}, disconnected: {disconnected}."); // start json server and connect both clients js.Start(); await Assert_NotTimedOut(jc.ConnectAsync(credentials), "jc.ConnectAsync()"); await Assert_NotTimedOut(sc.ConnectAsync(credentials), "sc.ConnectAsync()"); // subscribe to jc events var jcounter = 0; var jcancel = default(bool?); var jtcs = new TaskCompletionSource <bool>(); var junsubscribe = await Assert_NotTimedOut(jc.Subscribe <CancelEventArgs>( EventBroadcaster.BeforeShutdownEventName, (s, e) => { jcounter++; jcancel = e.Cancel; jtcs.TrySetResult(true); }), "jc.Subscribe<CancelEventArgs>(...)"); // subscribe to sc events var scounter = 0; var spropName = default(string); var stcs = new TaskCompletionSource <bool>(); var sunsubscribe = await Assert_NotTimedOut(sc.Subscribe <MyCoolEventArgs>( EventBroadcaster.AfterStartupEventName, (s, e) => { scounter++; spropName = e.PropertyName; stcs.TrySetResult(true); }), "sc.Subscribe<MyCoolEventArgs>(...)"); // one-way call EventBroadcaster.AfterStartup jc.Notify(new EventBroadcaster { EventName = EventBroadcaster.AfterStartupEventName, }); // sc is subscribed to AfterStartup event, jc is not await Assert_NotTimedOut(stcs.Task, "stcs.Task"); Assert.AreEqual(1, scounter); Assert.AreEqual(0, jcounter); Assert.AreEqual(nameof(EventBroadcaster), spropName); // call EventBroadcaster.BeforeShutdown await Assert_NotTimedOut(jc.Call(new EventBroadcaster { EventName = EventBroadcaster.BeforeShutdownEventName, }), "jc.Call(new EventBroadcaster(...BeforeShutdown))"); // js is subscribed to BeforeShutdown event, sc is not await Assert_NotTimedOut(jtcs.Task, "jtcs.Task"); Assert.AreEqual(1, scounter); Assert.AreEqual(1, jcounter); Assert.IsTrue(jcancel); // restart both task completion sources jtcs = new TaskCompletionSource <bool>(); stcs = new TaskCompletionSource <bool>(); // call EventBroadcaster.BeforeShutdown await Assert_NotTimedOut(jc.Call(new EventBroadcaster { EventName = EventBroadcaster.BeforeShutdownEventName, }), "jc.Call(new EventBroadcaster(...BeforeShutdown)) #2"); // js is subscribed to BeforeShutdown event, sc is not await Assert_NotTimedOut(jtcs.Task, "jtcs.Task #2"); Assert.AreEqual(1, scounter); Assert.AreEqual(2, jcounter); Assert.IsTrue(jcancel); // unsubscribe sc from AfterStartup event await Assert_NotTimedOut(sunsubscribe(), "sunsubscribe()"); // call EventBroadcaster.AfterStartup await Assert_NotTimedOut(jc.Call(new EventBroadcaster { EventName = EventBroadcaster.AfterStartupEventName, }), "jc.Call(new EventBroadcaster(...AfterStartup)) #2"); // make sure that event is not handled anymore await Assert_TimedOut(stcs.Task, "stcs.Task #2", Task.Delay(200)); Assert.AreEqual(1, scounter); // unsubscribe jc from BeforeShutdown event await Assert_NotTimedOut(junsubscribe(), "junsubscribe()"); jtcs = new TaskCompletionSource <bool>(); scounter = 0; jcounter = 0; // call EventBroadcaster.BeforeShutdown await Assert_NotTimedOut(jc.Call(new EventBroadcaster { EventName = EventBroadcaster.BeforeShutdownEventName, }), "jc.Call(new EventBroadcaster(...BeforeShutdown)) #3"); // nobody is subscribed to BeforeShutdown event await Assert_TimedOut(jtcs.Task, "jtcs.Task #3", Task.Delay(200)); Assert.AreEqual(0, scounter); Assert.AreEqual(0, jcounter); // make sure all incoming messages are processed Assert.AreEqual(0, jc.PendingMessages.Count); Assert.AreEqual(0, sc.PendingMessages.Count); }
protected async Task TestFilteredSubscriptionsAndUnsubscriptionsCore(JsonServer js, JsonClient jc, JsonClient sc, ICredentials credentials = null) { // unhandled exception handlers var connected = 0; var disconnected = 0; js.ClientConnected += (s, e) => connected++; js.ClientDisconnected += (s, e) => disconnected++; js.UnhandledException += (s, e) => Assert.Fail($"Unhandled server exception: {e.Exception}. Connected: {connected}, disconnected: {disconnected}."); jc.UnhandledException += (s, e) => Assert.Fail($"Unhandled client exception in jc (first client): {e.Exception}. Connected: {connected}, disconnected: {disconnected}."); sc.UnhandledException += (s, e) => Assert.Fail($"Unhandled client exception in sc (second client): {e.Exception}. Connected: {connected}, disconnected: {disconnected}."); // start json server and connect both clients js.Start(); await Assert_NotTimedOut(jc.ConnectAsync(credentials), "jc.ConnectAsync()"); await Assert_NotTimedOut(sc.ConnectAsync(credentials), "sc.ConnectAsync()"); // subscribe to jc events var jcounter = 0; var jeventArgs = default(FilteredEventArgs); var jtcs = new TaskCompletionSource <bool>(); var junsubscribe = await Assert_NotTimedOut(jc.Subscribe <FilteredEventArgs>( EventBroadcaster.FilteredEventName, (s, e) => { jcounter++; jeventArgs = e; jtcs.TrySetResult(true); }, new Dictionary <string, string> { { nameof(FilteredEventArgs.StringProperty), "Twain" } }), "jc.Subscribe<FilteredEventArgs>(...)"); // subscribe to sc events var scounter = 0; var seventArgs = default(FilteredEventArgs); var stcs = new TaskCompletionSource <bool>(); var sunsubscribe = await Assert_NotTimedOut(sc.Subscribe <FilteredEventArgs>( EventBroadcaster.FilteredEventName, (s, e) => { scounter++; seventArgs = e; stcs.TrySetResult(true); }, new Dictionary <string, string> { { nameof(FilteredEventArgs.StringProperty), "Mark" } }), "sc.Subscribe<FilteredEventArgs>(...)"); // call EventBroadcaster.FilteredEvent await Assert_NotTimedOut(jc.Call(new EventBroadcaster { EventName = EventBroadcaster.FilteredEventName, StringArgument = "Mark Hamill", }), "jc.Call(new EventBroadcaster...FilteredEvent...Mark Hamill))"); // sc is subscribed to Mark filtered event, jc is not await Assert_NotTimedOut(stcs.Task, "stcs.Task"); Assert.AreEqual(1, scounter); Assert.AreEqual(0, jcounter); Assert.AreEqual("Mark Hamill", seventArgs.StringProperty); // restart both task completion sources jtcs = new TaskCompletionSource <bool>(); stcs = new TaskCompletionSource <bool>(); // call EventBroadcaster.FilteredEvent await Assert_NotTimedOut(jc.Call(new EventBroadcaster { EventName = EventBroadcaster.FilteredEventName, StringArgument = "Mark Twain", }), "jc.Call(new EventBroadcaster(...FilteredEvent...Mark Twain))"); // js and sc are both subscribed to this filtered event await Assert_NotTimedOut(jtcs.Task, "jtcs.Task"); await Assert_NotTimedOut(stcs.Task, "stcs.Task"); Assert.AreEqual(2, scounter); Assert.AreEqual(1, jcounter); Assert.AreEqual("Mark Twain", jeventArgs.StringProperty); Assert.AreEqual("Mark Twain", seventArgs.StringProperty); // restart both task completion sources jtcs = new TaskCompletionSource <bool>(); stcs = new TaskCompletionSource <bool>(); // call EventBroadcaster.FilteredEvent await Assert_NotTimedOut(sc.Call(new EventBroadcaster { EventName = EventBroadcaster.FilteredEventName, StringArgument = "TWAIN driver" }), "sc.Call(new EventBroadcaster(...FilteredEvent...TWAIN driver))"); // jc is subscribed to TWAIN filtered event, sc is not await Assert_NotTimedOut(jtcs.Task, "jtcs.Task #2"); Assert.AreEqual(2, scounter); Assert.AreEqual(2, jcounter); Assert.AreEqual("TWAIN driver", jeventArgs.StringProperty); // unsubscribe sc from the filtered event await Assert_NotTimedOut(sunsubscribe(), "sunsubscribe()"); // one-way call EventBroadcaster.FilteredEvent jc.Notify(new EventBroadcaster { EventName = EventBroadcaster.FilteredEventName, StringArgument = "Mark Knopfler" }); // make sure that event is not handled anymore await Assert_TimedOut(stcs.Task, "stcs.Task #2", Task.Delay(200)); Assert.AreEqual(2, scounter); Assert.AreEqual(2, jcounter); // unsubscribe jc from the filtered event await Assert_NotTimedOut(junsubscribe(), "junsubscribe()"); jtcs = new TaskCompletionSource <bool>(); scounter = 0; jcounter = 0; // call EventBroadcaster.FilteredEvent await Assert_NotTimedOut(sc.Call(new EventBroadcaster { EventName = EventBroadcaster.FilteredEventName, StringArgument = "Twain, Mark", }), "sc.Call(new EventBroadcaster(...FilteredEvent...Twain, Mark))"); // nobody is subscribed to BeforeShutdown event await Assert_TimedOut(jtcs.Task, "jtcs.Task #3", Task.Delay(200)); Assert.AreEqual(0, scounter); Assert.AreEqual(0, jcounter); // make sure all incoming messages are processed Assert.AreEqual(0, jc.PendingMessages.Count); Assert.AreEqual(0, sc.PendingMessages.Count); }