public void WebsocketBroadcast() { Task.Run(async() => { string data = client.UploadString($"{Address}/security/GetToken", JsonConvert.SerializeObject(new SecurityUser() { Username = AdminUsername, Password = AdminPassword })); APIWrap <Token> tokenResult = JsonConvert.DeserializeObject <APIWrap <Token> >(data); ClientWebSocket socket = new ClientWebSocket(); await socket.ConnectAsync(new Uri("ws://localhost:9990/websocket"), CancellationToken.None); ClientWebSocket socket2 = new ClientWebSocket(); await socket2.ConnectAsync(new Uri("ws://localhost:9990/adminsocket?t=" + tokenResult.Result.AccessToken), CancellationToken.None); await socket2.SendAsync(new ArraySegment <byte>(Encoding.UTF8.GetBytes("Broadcast:AdminPing")), WebSocketMessageType.Text, true, CancellationToken.None); byte[] buffer = new byte[1024]; WebSocketReceiveResult result = await socket.ReceiveAsync(new ArraySegment <byte>(buffer), CancellationToken.None); string resp = Encoding.UTF8.GetString(buffer, 0, result.Count); Assert.AreEqual(resp, "AdminPing"); }).Wait(); }
public void WebSocketAuthenticated() { Task.Run(async() => { string data = client.UploadString($"{Address}/security/GetToken", JsonConvert.SerializeObject(new SecurityUser() { Username = AdminUsername, Password = AdminPassword })); APIWrap <Token> tokenResult = JsonConvert.DeserializeObject <APIWrap <Token> >(data); bool didSuccess = false; bool didCrash = false; try { ClientWebSocket socket = new ClientWebSocket(); await socket.ConnectAsync(new Uri("ws://localhost:9990/adminsocket"), CancellationToken.None); await socket.SendAsync(new ArraySegment <byte>(Encoding.UTF8.GetBytes("Ping")), WebSocketMessageType.Text, true, CancellationToken.None); byte[] buffer = new byte[1024]; WebSocketReceiveResult result = await socket.ReceiveAsync(new ArraySegment <byte>(buffer), CancellationToken.None); string resp = Encoding.UTF8.GetString(buffer, 0, result.Count); didSuccess = true; } catch (Exception ex) { didCrash = true; } Assert.IsTrue(!didSuccess && didCrash); ClientWebSocket socket2 = new ClientWebSocket(); await socket2.ConnectAsync(new Uri("ws://localhost:9990/adminsocket?t=" + tokenResult.Result.AccessToken), CancellationToken.None); await socket2.SendAsync(new ArraySegment <byte>(Encoding.UTF8.GetBytes("Ping")), WebSocketMessageType.Text, true, CancellationToken.None); byte[] buffer2 = new byte[1024]; WebSocketReceiveResult result2 = await socket2.ReceiveAsync(new ArraySegment <byte>(buffer2), CancellationToken.None); string resultString = Encoding.UTF8.GetString(buffer2, 0, result2.Count); Assert.AreEqual(resultString, "Pong"); }).Wait(); }
public void Authentication() { string data = client.DownloadString($"{Address}/controller/AuthTest"); Assert.AreNotEqual("true", data, $"Server should not allow access to this controller"); APIWrap result = JsonConvert.DeserializeObject <APIWrap>(data); Assert.IsFalse(result.Success, $"Call should not be succesfull"); Assert.AreEqual(typeof(ForbiddenException).Name, result.Exception.Type, $"Server giving wrong exception"); data = client.UploadString($"{Address}/security/GetToken", JsonConvert.SerializeObject(new SecurityUser() { Username = "******", Password = "******" })); APIWrap <Token> tokenResult = JsonConvert.DeserializeObject <APIWrap <Token> >(data); Assert.IsTrue(tokenResult.Success, $"Failed GetToken due to [{tokenResult.Exception?.Type}]:{tokenResult.Exception?.Message}"); data = client.DownloadString($"{Address}/controller/AuthTest?t={tokenResult.Result.AccessToken}"); Assert.AreEqual("true", data, $"No access given to controller despite authentication"); data = client.DownloadString($"{Address}/controller/AuthLvl5Test?t={tokenResult.Result.AccessToken}"); Assert.AreNotEqual("true", data, $"Server should not allow access to this controller"); result = JsonConvert.DeserializeObject <APIWrap>(data); Assert.IsFalse(result.Success, $"Call should not be succesfull"); Assert.AreEqual(typeof(ForbiddenException).Name, result.Exception.Type, $"Server giving wrong exception"); data = client.UploadString($"{Address}/security/GetToken", JsonConvert.SerializeObject(new SecurityUser() { Username = AdminUsername, Password = AdminPassword })); tokenResult = JsonConvert.DeserializeObject <APIWrap <Token> >(data); Assert.IsTrue(tokenResult.Success, $"Failed GetToken for admin due to [{tokenResult.Exception?.Type}]:{tokenResult.Exception?.Message}"); data = client.DownloadString($"{Address}/controller/AuthLvl5Test?t={tokenResult.Result.AccessToken}"); Assert.AreEqual("true", data, $"No access given to admin controller despite authentication"); }
public bool ExecuteController(string methodName, HttpRequest request) { string mn = methodName.ToLower(); if (Calls.ContainsKey(methodName)) { if (request.IsClosed) { return(true); } BodyType responseType = Server.DefaultResponseType; //Header override string accept = request.GetHeader("Accept"); if (!string.IsNullOrEmpty(accept)) { switch (accept.ToLower()) { case "text/json": case "application/json": responseType = BodyType.JSON; break; case "text/xml": case "application/xml": responseType = BodyType.XML; break; default: //Not supported ResponseType break; } } try { CallDescriptor call = Calls[methodName]; //Pre-Controller logic request.Server.PreControllerCheck(request, call); if (request.IsClosed) { return(true); } //With descriptor if (call.Descriptor != null) { responseType = call.Descriptor.ResponseType; if (responseType == BodyType.Undefined) { responseType = Server.DefaultResponseType; } if (call.Descriptor.HasParameters) { foreach (string enforced in call.Descriptor.Parameters) { if (!request.Parameters.ContainsKey(enforced)) { throw new ArgumentException($"Missing parameter {enforced}"); } } } } object result = null; Exception ex = null; try { if (call.TokenRequirements != null) { if (!request.Authenticated || call.TokenRequirements.LevelRequired > request.AuthenticationLevel) { throw new ForbiddenException("You don't have permission to access this API method"); } if (call.TokenRequirements.RequestAttributes != null && call.TokenRequirements.RequestAttributes.Length > 0) { foreach (string attr in call.TokenRequirements.RequestAttributes) { if (!request.Attributes.Contains(attr)) { throw new ForbiddenException("You don't have permission to access this API method at this moment"); } } } } //Caching if (call.CacheHeader != null) { switch (call.CacheHeader.Cache) { case CachingType.Cache: request.Response.Headers.Add("cache-control", "max-age=" + call.CacheHeader.Validity.ToString()); break; case CachingType.Prevent: request.Response.Headers.Add("cache-control", "no-cache, no-store, must-revalidate"); request.Response.Headers.Add("Pragma", "no-cache"); request.Response.Headers.Add("Expires", "0"); break; } } //Parse Parameters object[] paras = GetParameters(call, request); //Handling result = call.Info.Invoke(GetInstance(request), paras.ToArray()); if (request.DisableAutoHandling) { return(true); } } catch (TargetInvocationException tx) { ex = tx.InnerException; } catch (Exception x) { ex = x; } if (!request.IsClosed && (result != null || ex != null)) { Type resultType; if (ex != null) { resultType = typeof(Exception); result = new APIWrap(ex); if (!Server.Debug) { ((APIWrap)result).Exception.StackTrace = ""; } if (responseType == BodyType.Raw || responseType == BodyType.Razor) { responseType = Server.DefaultResponseType; } HandleResult(Server, request, call, responseType, result, false); } else { HandleResult(Server, request, call, responseType, result, UseWrap); } } } catch (Exception ex) { if (responseType == BodyType.Razor) { responseType = Server.DefaultResponseType; } request.Write(new APIWrap(ex), responseType); } if (!request.IsClosed) { request.Close(); } return(true); } else { return(false); } }
private static void HandleResult(HttpServer server, HttpRequest request, CallDescriptor call, BodyType responseType, object result, bool useWrap) { Type resultType = result.GetType(); if (useWrap && responseType != BodyType.Raw && responseType != BodyType.Razor) { result = new APIWrap(result); } if (!server?.IsAllowedResponse(responseType) ?? false) { throw new Exceptions.ConfigurationException("Requested response type is not allowed"); } switch (responseType) { case BodyType.Razor: HandleRazor(request, call, result); break; case BodyType.Raw: if (resultType == typeof(byte[])) { request.Response.ContentType = "application/octet-stream"; request.Write((byte[])result); } else { request.Response.ContentType = "text/plain"; request.Write(result.ToString()); } break; case BodyType.JSON: request.Response.ContentType = "application/json"; JsonSerializerSettings settings = call.JsonSerialization?.Response; if (settings != null) { request.Write(JsonConvert.SerializeObject(result, settings)); } else { request.Write(JsonConvert.SerializeObject(result)); } break; case BodyType.XML: if (useWrap) { XmlParser.AddSubType(typeof(APIWrap), resultType); } request.Response.ContentType = "application/xml"; request.Write(XmlParser.Serialize(result)); break; case BodyType.UrlEncoded: throw new NotSupportedException(); case BodyType.MultipartStream: throw new NotSupportedException(); } }