public static async Task <Task> Action(ServerHandler shandler, HTTPRequest request, Stream body, IProxyHTTPEncoder encoder) { var auth_resp = await Helpers.ReadMessageFromStreamAndAuthenticate(shandler, 1024 * 16, body); if (!auth_resp.success) { return(encoder.Response(403, "Denied").SendNothing()); } var reply = new HandleDataReply(); reply.data = new Item[shandler.items.Count]; lock (shandler.items) { int x = 0; foreach (var pair in shandler.items) { if ( Helpers.CanUserSeeItem(auth_resp.user, pair.Value) ) { reply.data[x++] = pair.Value; } } } return(encoder.Response(200, "OK").SendJsonFromObject(reply)); }
public async Task <Task> ServeData(string dataName, IProxyHTTPEncoder encoder) { var dataNameSanitized = SanitizeDataName(dataName); var fullPath = Path.Combine(cfg.web_resources_path, dataNameSanitized); FileStream fp; try { fp = File.OpenRead(fullPath); } catch (FileNotFoundException) { return(encoder.Response(404, "Not Found") .ContentType("text/plain") .CacheControlDoNotCache() .SendString("Not Found")); } catch (Exception ex) { return(encoder.Response(500, "Internal Error") .ContentType("text/plain") .CacheControlDoNotCache() .SendString(ex.ToString())); } return(await encoder.Response(200, "OK") .ContentType_GuessFromFileName(dataName) .CacheControlDoNotCache() .SendStream(fp)); }
/// <summary> /// Helper method used to send data stored as a resource under the webres folder (namespace). /// </summary> /// <param name="target">The name of the resource in the webres folder/namespace.</param> /// <param name="state">Pass-through parameter.</param> /// <param name="request">Pass-through parameter.</param> /// <param name="body">Pass-through parameter.</param> /// <param name="encoder">Pass-through parameter.</param> /// <returns>A task object which may or may not be completed already. This also may need to be returned as a dependency of the handler completion.</returns> private static async Task <Task> StaticRoute( string target, ServerHandler state, HTTPRequest request, Stream body, IProxyHTTPEncoder encoder) { await Util.ReadStreamUntilEndAndDiscardDataAsync(body); #if USE_SOURCE_DIRECTORY_WEBRES var strm = File.OpenRead( Path.Combine( @"/home/kmcguire/extra/old/source/repos/MDACSDatabase/MDACSDatabase/webres", target ) ); #else var strm = Assembly.GetExecutingAssembly().GetManifestResourceStream($"MDACSDatabase.webres.{target}"); if (strm == null) { return(await encoder.Response(404, "Not Found") .CacheControl("no-cache, no-store, must-revalidate") .SendNothing()); } #endif return(await encoder.Response(200, "OK") .ContentType_GuessFromFileName(target) .CacheControl("public, max-age=0") .SendStream(strm)); }
public static async Task <Task> UserList( ServerState state, HTTPRequest request, Stream body, IProxyHTTPEncoder encoder) { var msg = await Util.ReadJsonObjectFromStreamAsync <Msg>(body, 1024); var(user, req) = state.AuthenticateMessage <JObject>(msg); if (user == null) { return(await encoder.Response(403, "The user list request was denied due to an authentication failure.") .ContentType("text/plain") .CacheControlDoNotCache() .SendNothing()); } var users = state.GetUserList(); return(await encoder.Response(200, "OK") .ContentType_JSON() .SendJsonFromObject(state.GetUserList())); }
public static async Task <Task> Action(ServerHandler shandler, HTTPRequest request, Stream body, IProxyHTTPEncoder encoder) { var auth = await Helpers.ReadMessageFromStreamAndAuthenticate(shandler, 1024 * 16, body); if (!auth.success) { return(encoder.Response(403, "Denied").SendNothing()); } var resp = new EnumerateConfigurationsResponse(); resp.success = true; resp.configs = new Dictionary <string, string>(); try { foreach (var node in Directory.EnumerateFiles(shandler.config_path)) { var fnode = Path.Combine(shandler.data_path, node); var fnode_filename = Path.GetFileName(fnode); if (fnode_filename.StartsWith("config_") && fnode_filename.EndsWith(".data")) { var fd = File.OpenRead(fnode); var buf = new byte[fd.Length]; int cnt = 0; while (cnt < buf.Length) { cnt += await fd.ReadAsync(buf, cnt, buf.Length - cnt); } var buf_text = Encoding.UTF8.GetString(buf); var id = fnode_filename.Substring(fnode_filename.IndexOf("_") + 1); id = id.Substring(0, id.LastIndexOf(".")); resp.configs[id] = buf_text; fd.Dispose(); } } } catch (Exception ex) { //Logger.WriteCriticalString($"Error during configuration enumeration as follows:\n{ex}"); return(encoder.Response(500, "Error").SendNothing()); } return(encoder.Response(200, "OK").SendJsonFromObject(resp)); }
/// <summary> /// Handles deleting existing data files. Requires authentication and a special privilege. /// </summary> /// <param name="shandler"></param> /// <param name="request"></param> /// <param name="body"></param> /// <param name="encoder"></param> /// <returns></returns> public static async Task <Task> Action(ServerHandler shandler, HTTPRequest request, Stream body, IProxyHTTPEncoder encoder) { var auth_resp = await Helpers.ReadMessageFromStreamAndAuthenticate(shandler, 1024 * 16, body); if (!auth_resp.success) { return(encoder.Response(403, "Denied").SendNothing()); } if (!auth_resp.user.can_delete) { return(encoder.Response(403, "Denied").SendNothing()); } var sreq = JsonConvert.DeserializeObject <DeleteRequest>(auth_resp.payload); var sid = sreq.sid; if (shandler.items.ContainsKey(sid)) { var item = shandler.items[sid]; try { File.Delete(item.fqpath); } catch (Exception) { await encoder.WriteQuickHeaderAndStringBody( 500, "Error", JsonConvert.SerializeObject(new DeleteResponse() { success = false, }) ); return(Task.CompletedTask); } if (item.fqpath != null && item.fqpath.Length > 0) { shandler.UsedSpaceSubtract((long)item.datasize); } item.fqpath = null; await shandler.WriteItemToJournal(item); } await encoder.WriteQuickHeaderAndStringBody( 200, "Deleted", JsonConvert.SerializeObject(new DeleteResponse() { success = true, }) ); return(Task.CompletedTask); }
public static async Task <Task> UserSet( ServerState state, HTTPRequest request, Stream body, IProxyHTTPEncoder encoder) { var msg = await Util.ReadJsonObjectFromStreamAsync <Msg>(body, 1024); var(user, req) = state.AuthenticateMessage <AuthUserSetRequest>(msg); if (user == null) { return(await encoder.Response(403, "Authentication based on user failed.") .ContentType("text/plain") .CacheControlDoNotCache() .SendNothing()); } if (!user.admin && user.user != req.user.user) { return(await encoder.Response(403, "Disallowed modification of another user.") .ContentType("text/plain") .CacheControlDoNotCache() .SendNothing()); } if (!await state.SetUser(req.user)) { return(await encoder.Response(500, "The set user command failed to execute.") .ContentType("text/plain") .CacheControlDoNotCache() .SendNothing()); } return(await encoder.Response(200, "OK") .ContentType("text/plain") .CacheControlDoNotCache() .SendNothing()); }
public static async Task <Task> UserDelete( ServerState state, HTTPRequest request, Stream body, IProxyHTTPEncoder encoder) { var msg = await Util.ReadJsonObjectFromStreamAsync <Msg>(body, 1024); var(user, req) = state.AuthenticateMessage <AuthUserDeleteRequest>(msg); if (user == null) { return(await encoder.Response(403, "Authentication failed for the user used.") .ContentType("text/plain") .CacheControlDoNotCache() .SendNothing()); } if (!user.admin) { return(await encoder.Response(403, "Disallowed delete of user by non-administrator.") .ContentType("text/plain") .CacheControlDoNotCache() .SendNothing()); } if (!await state.DeleteUser(req.username)) { return(await encoder.Response(500, "The delete user command failed on the server.") .ContentType("text/plain") .CacheControlDoNotCache() .SendNothing()); } return(await encoder.Response(200, "OK") .ContentType("text/plain") .CacheControlDoNotCache() .SendNothing()); }
public static async Task <Task> VerifyPayload( ServerState state, HTTPRequest request, Stream body, IProxyHTTPEncoder encoder) { var req = await Util.ReadJsonObjectFromStreamAsync <AuthVerifyPayloadRequest>(body, 1024 * 1024); var user = state.VerifyPayload(req.challenge, req.chash, req.phash); if (user == null) { return(await encoder.Response(403, "Authentication based on user failed.").SendNothing()); } var resp = new AuthCheckResponse() { payload = "", success = true, user = user, }; return(await encoder.Response(200, "OK").ContentType_JSON().SendJsonFromObject(resp)); }
public static async Task <Task> Challenge( ServerState state, HTTPRequest request, Stream body, IProxyHTTPEncoder encoder) { await Util.ReadStreamUntilEndAndDiscardDataAsync(body); var challenge = state.GetChallenge(); return(await encoder.Response(200, "OK") .ContentType_JSON() .SendString( JsonConvert.SerializeObject(new AuthChallengeResponse() { challenge = challenge, } ) )); }
public static async Task <Task> IsLoginValid( ServerState state, HTTPRequest request, Stream body, IProxyHTTPEncoder encoder) { var msg = await Util.ReadJsonObjectFromStreamAsync <Msg>(body, 1024); bool valid = false; User user; if (msg.payload == null || msg.auth.hash == null) { // Ensure the payload can never be accidentally used since this // authentication is without a payload hash. msg.payload = null; user = state.Verify(msg.auth.challenge, msg.auth.chash); if (user != null) { valid = true; } } else { var payload_hash = BitConverter.ToString( new SHA512Managed().ComputeHash( Encoding.UTF8.GetBytes(msg.payload) ) ).Replace("-", "").ToLower(); user = state.VerifyPayload( msg.auth.challenge, msg.auth.chash, payload_hash /* recompute it */ ); if (user != null) { valid = true; } } if (valid) { return(await encoder.Response(200, "Login Valid") .CacheControlDoNotCache() .ContentType_JSON() .SendJsonFromObject(new AuthLoginValidResponse() { success = true, user = user, })); } else { return(await encoder.Response(403, "The login was not valid.") .CacheControlDoNotCache() .ContentType_JSON() .SendJsonFromObject(new AuthLoginValidResponse() { success = false, user = null, })); } }
public static async Task <Task> Action(ServerHandler shandler, HTTPRequest request, Stream body, IProxyHTTPEncoder encoder) { var auth = await Helpers.ReadMessageFromStreamAndAuthenticate(shandler, 1024 * 16, body); if (!auth.success) { return(encoder.Response(403, "Denied").SendNothing()); } var req = JsonConvert.DeserializeObject <HandleBatchSingleOpsRequest>(auth.payload); var failed = new List <BatchSingleOp>(); var tasks = new List <Task <bool> >(); foreach (var op in req.ops) { var sid = op.sid; var field_name = op.field_name; if (!await shandler.FieldModificationValidForUser(auth.user, field_name)) { return(encoder.Response(403, $"Denied Change On Field {field_name}").SendNothing()); } } foreach (var op in req.ops) { var sid = op.sid; var field_name = op.field_name; var value = op.value; lock (shandler.items) { if (shandler.items.ContainsKey(sid)) { try { var tmp = shandler.items[sid]; var field = tmp.GetType().GetField(field_name); field.SetValue(tmp, value.ToObject(field.FieldType)); tasks.Add(shandler.WriteItemToJournal(tmp)); } catch (Exception ex) { //Logger.WriteDebugString( // $"Failed during batch single operation. The SID was {sid}. The field name was {field_name}. The value was {value}. The error was:\n{ex}" //); failed.Add(new BatchSingleOp() { field_name = field_name, sid = sid, value = value, }); } } else { failed.Add(new BatchSingleOp() { field_name = field_name, sid = sid, value = value, }); } } } Task.WaitAll(tasks.ToArray()); var resp = new HandleBatchSingleOpsResponse(); resp.success = true; resp.failed = failed.ToArray(); await encoder.Response(200, "OK") .CacheControlDoNotCache() .SendJsonFromObject(resp); return(Task.CompletedTask); }