public static void TestWebPubSubTrigger( [WebPubSubTrigger("chat", WebPubSubEventType.System, "connect")] ConnectEventRequest request, WebPubSubConnectionContext connectionContext) { // Valid case use default url for verification. Assert.AreEqual(TestContext, connectionContext); }
public void TestWebPubSubContext_UserEventStates_CollectionsInSync() { var states = new Dictionary <string, object> { { "aKey", "aValue" }, { "bKey", 123 }, { "cKey", new StateTestClass() } } .EncodeConnectionStates() .DecodeConnectionStates() .ToDictionary(p => p.Key, p => (BinaryData)p.Value); var ctx = new WebPubSubConnectionContext( eventType: WebPubSubEventType.System, eventName: "connected", hub: null, connectionId: "connectionId", userId: "userA", connectionStates: states); CollectionAssert.AreEquivalent(ctx.ConnectionStates.Keys, ctx.States.Keys); Assert.AreEqual(ctx.ConnectionStates["aKey"].ToString(), ctx.States["aKey"]); Assert.AreEqual(ctx.ConnectionStates["bKey"].ToString(), ctx.States["bKey"]); Assert.AreEqual(ctx.ConnectionStates["cKey"].ToString(), ctx.States["cKey"]); }
internal static bool IsValidSignature(this WebPubSubConnectionContext connectionContext, WebPubSubValidationOptions options) { // no options skip validation. if (options == null || !options.ContainsHost()) { return(true); } if (options.TryGetKey(connectionContext.Origin, out var accessKey)) { // server side disable signature checks. if (string.IsNullOrEmpty(accessKey)) { return(true); } var signatures = connectionContext.Signature.ToHeaderList(); if (signatures == null) { return(false); } using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(accessKey)); var hashBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(connectionContext.ConnectionId)); var hash = "sha256=" + BitConverter.ToString(hashBytes).Replace("-", ""); if (signatures.Contains(hash, StringComparer.OrdinalIgnoreCase)) { return(true); } } return(false); }
private static bool TryParseCloudEvents(this HttpRequest request, out WebPubSubConnectionContext connectionContext) { try { var connectionId = request.Headers.GetFirstHeaderValueOrDefault(Constants.Headers.CloudEvents.ConnectionId); var hub = request.Headers.GetFirstHeaderValueOrDefault(Constants.Headers.CloudEvents.Hub); var eventType = GetEventType(request.Headers.GetFirstHeaderValueOrDefault(Constants.Headers.CloudEvents.Type)); var eventName = request.Headers.GetFirstHeaderValueOrDefault(Constants.Headers.CloudEvents.EventName); var signature = request.Headers.GetFirstHeaderValueOrDefault(Constants.Headers.CloudEvents.Signature); var origin = request.Headers.GetFirstHeaderValueOrDefault(Constants.Headers.WebHookRequestOrigin); var headers = request.Headers.ToDictionary(x => x.Key, v => v.Value.ToArray(), StringComparer.OrdinalIgnoreCase); string userId = null; // UserId is optional, e.g. connect if (request.Headers.ContainsKey(Constants.Headers.CloudEvents.UserId)) { userId = request.Headers.GetFirstHeaderValueOrDefault(Constants.Headers.CloudEvents.UserId); } Dictionary <string, BinaryData> states = null; // connection states. if (request.Headers.ContainsKey(Constants.Headers.CloudEvents.State)) { states = request.Headers.GetFirstHeaderValueOrDefault(Constants.Headers.CloudEvents.State).DecodeConnectionStates(); } connectionContext = new WebPubSubConnectionContext(eventType, eventName, hub, connectionId, userId, signature, origin, states, headers); return(true); } catch { connectionContext = null; return(false); } }
internal static Dictionary <string, object> UpdateStates(this WebPubSubConnectionContext connectionContext, IReadOnlyDictionary <string, BinaryData> newStates) { // states cleared. if (newStates == null) { return(null); } if (connectionContext.ConnectionStates?.Count > 0 || newStates.Count > 0) { var states = new Dictionary <string, object>(); if (connectionContext.ConnectionStates?.Count > 0) { foreach (var state in connectionContext.ConnectionStates) { states.Add(state.Key, state.Value); } } // response states keep empty is no change. if (newStates.Count == 0) { return(states); } foreach (var item in newStates) { states[item.Key] = item.Value; } return(states); } return(null); }
public void TestUpdateConnectionState() { var exist = new Dictionary <string, BinaryData> { { "aaa", BinaryData.FromObjectAsJson("aaa") }, { "bbb", BinaryData.FromObjectAsJson("bbb") } }; var connectionContext = new WebPubSubConnectionContext(eventType: WebPubSubEventType.System, null, null, null, connectionStates: exist); var response = new ConnectEventResponse { UserId = "aaa" }; response.SetState("test", BinaryData.FromObjectAsJson("ddd")); response.SetState("bbb", BinaryData.FromObjectAsJson("bbb1")); var updated = connectionContext.UpdateStates(response.ConnectionStates); // new Assert.AreEqual("ddd", updated["test"].ToObjectFromJson <string>()); // no change Assert.AreEqual("aaa", updated["aaa"].ToObjectFromJson <string>()); // update Assert.AreEqual("bbb1", updated["bbb"].ToObjectFromJson <string>()); response.ClearStates(); updated = connectionContext.UpdateStates(response.ConnectionStates); // After clear is null. Assert.IsNull(updated); }
public void TestWebPubSubContext_UserEventStates_AllBinaryData() { var ctx = new WebPubSubConnectionContext( eventType: WebPubSubEventType.System, eventName: "connected", hub: null, connectionId: "connectionId", userId: "userA", signature: null, origin: null, states: new Dictionary <string, object> { { "aKey", "aValue" }, { "bKey", 123 }, { "cKey", new StateTestClass(DateTime.Now, "Test", 42) } }, headers: null); Assert.IsInstanceOf <BinaryData>(ctx.ConnectionStates["aKey"]); Assert.IsInstanceOf <string>(ctx.States["aKey"]); Assert.AreEqual("aValue", ctx.ConnectionStates["aKey"].ToObjectFromJson <string>()); Assert.AreEqual("\"aValue\"", ctx.States["aKey"]); Assert.IsInstanceOf <BinaryData>(ctx.ConnectionStates["bKey"]); Assert.IsInstanceOf <string>(ctx.States["bKey"]); Assert.AreEqual(123, ctx.ConnectionStates["bKey"].ToObjectFromJson <int>()); Assert.AreEqual("123", ctx.States["bKey"]); Assert.IsInstanceOf <BinaryData>(ctx.ConnectionStates["cKey"]); Assert.IsInstanceOf <string>(ctx.States["cKey"]); Assert.AreEqual(42, ctx.ConnectionStates["cKey"].ToObjectFromJson <StateTestClass>().Version); StringAssert.StartsWith("{", (string)ctx.States["cKey"]); }
public void TestSignatureCheck_SignatureNullFail() { var connectionContext = new WebPubSubConnectionContext( WebPubSubEventType.System, null, null, "0f9c97a2f0bf4706afe87a14e0797b11", origin: TestUri.Host); var options = new WebPubSubValidationOptions($"Endpoint={TestUri};AccessKey=7aab239577fd4f24bc919802fb629f5f;Version=1.0;"); var result = connectionContext.IsValidSignature(options); Assert.False(result); }
public void TestSignatureCheck_OptionsEmptySuccess() { var connectionContext = new WebPubSubConnectionContext( WebPubSubEventType.System, null, null, "0f9c97a2f0bf4706afe87a14e0797b11", signature: "sha256=7767effcb3946f3e1de039df4b986ef02c110b1469d02c0a06f41b3b727ab561", origin: TestUri.Host); var result = connectionContext.IsValidSignature(null); Assert.True(result); }
public void TestSignatureCheck(string accessKey, bool valid) { var connectionContext = new WebPubSubConnectionContext( WebPubSubEventType.System, null, null, "0f9c97a2f0bf4706afe87a14e0797b11", signature: "sha256=7767effcb3946f3e1de039df4b986ef02c110b1469d02c0a06f41b3b727ab561", origin: TestUri.Host); var options = new WebPubSubValidationOptions($"Endpoint={TestUri};AccessKey={accessKey};Version=1.0;"); var result = connectionContext.IsValidSignature(options); Assert.AreEqual(valid, result); }
public void TestUserEventRequestSerialize() { var connectionContext = new WebPubSubConnectionContext( WebPubSubEventType.System, null, null, "0f9c97a2f0bf4706afe87a14e0797b11", signature: "sha256=7767effcb3946f3e1de039df4b986ef02c110b1469d02c0a06f41b3b727ab561", origin: TestUri.Host); var request = new UserEventRequest(connectionContext, BinaryData.FromString("Hello World"), WebPubSubDataType.Text); var serialized = JsonSerializer.Serialize(request); }
public void TestWebPubSubContext_ConnectedEvent() { var context = new WebPubSubConnectionContext(connectionId: "connectionId", userId: "userA", eventName: "connected", eventType: WebPubSubEventType.System, hub: null); var test = new WebPubSubContext(new ConnectedEventRequest(context)); var serialize = JObject.FromObject(test); Assert.NotNull(serialize["request"]); Assert.NotNull(serialize["response"]); Assert.AreEqual("", serialize["errorMessage"].ToString()); Assert.AreEqual("False", serialize["hasError"].ToString()); Assert.AreEqual("False", serialize["isPreflight"].ToString()); }
private static HttpResponseMessage BuildResponse(string input, RequestType requestType, bool hasTestStates = false) { Dictionary <string, object> states = null; if (hasTestStates) { states = new Dictionary <string, object> { { "testKey", BinaryData.FromString("value") } }; } var context = new WebPubSubConnectionContext(WebPubSubEventType.System, "connect", "testhub", "Connection-Id1", null, null, null, states, null); return(Utilities.BuildValidResponse(JToken.Parse(input), requestType, context)); }
public void TestWebPubSubContext_UserEventStates_Legacy() { var states = new Dictionary <string, object> { { "aKey", "aValue" }, { "bKey", 123 }, { "cKey", new StateTestClass() } }; // Use the Dictionary<string, object> states .ctor overload var context = new WebPubSubConnectionContext( WebPubSubEventType.System, "connected", "hub", "connectionId", "userA", null, null, states, null); var test = new WebPubSubContext(new UserEventRequest(context, BinaryData.FromString("test"), WebPubSubDataType.Text)); var jObj = JObject.FromObject(test); var request = jObj["request"]; Assert.NotNull(request); Assert.AreEqual("test", request["data"].ToString()); Assert.NotNull(jObj["response"]); Assert.AreEqual("", jObj["errorMessage"].ToString()); Assert.AreEqual("False", jObj["hasError"].ToString()); Assert.AreEqual("False", jObj["isPreflight"].ToString()); var context1 = request["connectionContext"]; Assert.NotNull(context1); var states1 = context1["states"]; Assert.NotNull(states1); Assert.AreEqual("\"aValue\"", states1["aKey"].Value <string>()); Assert.NotNull(states1); Assert.AreEqual(123, states1["bKey"].Value <int>()); }
public void TestWebPubSubContext_UserEventStates() { var states = new Dictionary <string, object> { { "aKey", "aValue" }, { "bKey", 123 }, { "cKey", new StateTestClass() } }.EncodeConnectionStates().DecodeConnectionStates().ToDictionary(p => p.Key, p => (BinaryData)p.Value); // Use the Dictionary<string, BinaryData> connectionStates .ctor overload var context = new WebPubSubConnectionContext( eventType: WebPubSubEventType.System, eventName: "connected", hub: null, connectionId: "connectionId", userId: "userA", connectionStates: states); var test = new WebPubSubContext(new UserEventRequest(context, BinaryData.FromString("test"), WebPubSubDataType.Text)); var jObj = JObject.Parse(JsonConvert.SerializeObject(test)); var request = jObj["request"]; Assert.NotNull(request); Assert.AreEqual("test", request["data"].Value <string>()); Assert.NotNull(jObj["response"]); Assert.AreEqual(null, jObj["errorMessage"].Value <string>()); Assert.AreEqual("False", jObj["hasError"].Value <string>()); Assert.AreEqual("False", jObj["isPreflight"].Value <string>()); var context1 = request["connectionContext"]; Assert.NotNull(context1); var states1 = context1["states"]; Assert.NotNull(states1); Assert.AreEqual("aValue", states1["aKey"].Value <string>()); Assert.AreEqual(123, states1["bKey"].Value <int>()); var classStates = states1["cKey"]; Assert.NotNull(classStates); Assert.AreEqual("GA", classStates["Title"].Value <string>()); }
private static RequestType GetRequestType(this WebPubSubConnectionContext context) { if (context.EventType == WebPubSubEventType.User) { return(RequestType.User); } if (context.EventName.Equals(Constants.Events.ConnectEvent, StringComparison.OrdinalIgnoreCase)) { return(RequestType.Connect); } if (context.EventName.Equals(Constants.Events.DisconnectedEvent, StringComparison.OrdinalIgnoreCase)) { return(RequestType.Disconnected); } if (context.EventName.Equals(Constants.Events.ConnectedEvent, StringComparison.OrdinalIgnoreCase)) { return(RequestType.Connected); } return(RequestType.Ignored); }
public void TestWebPubSubContext_ConnectEvent() { var context = new WebPubSubConnectionContext(connectionId: "connectionId", userId: "userA", eventName: "connected", eventType: WebPubSubEventType.System, hub: null); var claims = new Dictionary <string, string[]> { { "aa", new string[] { "aa1, aa2" } }, { "bb", new string[] { "bb, bb2" } }, }; var subprotocol = new string[] { "sub1", "sub2" }; var test = new WebPubSubContext(new ConnectEventRequest(context, claims, null, subprotocol, null)); var serialize = JObject.FromObject(test); var request = serialize["request"]; Assert.NotNull(request); Assert.AreEqual(subprotocol, request["subprotocols"].ToObject <string[]>()); Assert.NotNull(serialize["response"]); Assert.AreEqual("", serialize["errorMessage"].ToString()); Assert.AreEqual("False", serialize["hasError"].ToString()); Assert.AreEqual("False", serialize["isPreflight"].ToString()); }
public void TestConnectEventRequestSerialize() { var connectionContext = new WebPubSubConnectionContext( WebPubSubEventType.System, null, null, "0f9c97a2f0bf4706afe87a14e0797b11", signature: "sha256=7767effcb3946f3e1de039df4b986ef02c110b1469d02c0a06f41b3b727ab561", origin: TestUri.Host); var claims = new Dictionary <string, string[]> { { "aaa", new string[] { "a1", "a2" } }, { "bbb", new string[] { "b1", "b2" } }, { "ccc", new string[] { "c1", "c2" } }, }; var query = new Dictionary <string, string[]> { { "query1", new string[] { "a1", "a2" } }, { "query2", new string[] { "b1" } }, }; var certs = new List <WebPubSubClientCertificate> { new WebPubSubClientCertificate("111"), new WebPubSubClientCertificate("222") }; var request = new ConnectEventRequest(connectionContext, claims, query, new string[] { "protocol1", "protocol2" }, certs); var serilized = JsonSerializer.Serialize(request); var converted = JsonSerializer.Deserialize <ConnectEventRequest>(serilized); Assert.AreEqual(3, converted.Claims.Count); Assert.AreEqual(2, converted.Query.Count); Assert.AreEqual(2, converted.Subprotocols.Count); Assert.AreEqual(new string[] { "protocol1", "protocol2" }, converted.Subprotocols); Assert.NotNull(converted.ClientCertificates); Assert.AreEqual(2, converted.ClientCertificates.Count); }
/// <summary> /// The connected event request /// </summary> /// <param name="context"></param> public ConnectedEventRequest(WebPubSubConnectionContext context) : base(context) { }
public static void Func2([WebPubSubTrigger("testchat", WebPubSubEventType.User, "message")] WebPubSubConnectionContext connectionContext, BinaryData data, WebPubSubDataType dataType) { }
public static void TestFunc( [WebPubSubTrigger("%testhub%", WebPubSubEventType.System, "testevent")] WebPubSubConnectionContext context) { }
public static void Func1([WebPubSubTrigger("testchat", WebPubSubEventType.System, "connect")] WebPubSubConnectionContext connectionContext) { }