예제 #1
0
        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));
        }
예제 #2
0
        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));
        }
예제 #3
0
        /// <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));
        }
예제 #4
0
        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));
        }
예제 #6
0
        /// <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);
        }
예제 #7
0
        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());
        }
예제 #8
0
        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());
        }
예제 #9
0
        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));
        }
예제 #10
0
        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,
            }
                                                   )
                       ));
        }
예제 #11
0
        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);
        }