Пример #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="request"></param>
        /// <param name="body"></param>
        /// <param name="encoder"></param>
        /// <exception cref="UnauthorizedException">User has insufficient priviledges to modify the item.</exception>
        /// <exception cref="AuthenticationException">User is not valid for access of any type.</exception>
        /// <exception cref="InvalidArgumentException">One of the arguments was not correct or the reason for failure.</exception>
        /// <exception cref="ProgramException">Anything properly handled but needs handling for acknowlegement purposes.</exception>
        /// <exception cref="Exception">Anything else could result in instability.</exception>
        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)
            {
                throw new UnauthorizedException();
            }

            var sreq = JsonConvert.DeserializeObject <API.Requests.CommitSetRequest>(auth_resp.payload);

            Monitor.Enter(shandler.items);

            Item item;

#if DEBUG
            //Logger.WriteDebugString($"sreq.security_id={sreq.security_id}");
#endif

            try
            {
                if (!shandler.items.ContainsKey(sreq.security_id))
                {
                    await encoder.WriteQuickHeader(404, "Not Found");

                    await encoder.BodyWriteSingleChunk("");

                    return(Task.CompletedTask);
                }

                item = shandler.items[sreq.security_id];
            }
            catch (Exception ex)
            {
#if DEBUG
                //Logger.WriteDebugString($"Exception on getting item was:\n{ex}");
#endif
                await encoder.WriteQuickHeader(500, "Error");

                await encoder.BodyWriteSingleChunk("");

                return(Task.CompletedTask);
            }
            finally
            {
                Monitor.Exit(shandler.items);
            }

            if (!Helpers.CanUserModifyItem(auth_resp.user, item))
            {
#if DEBUG
                //Logger.WriteDebugString($"User was not authorized to write to item.");
#endif
                await encoder.WriteQuickHeader(403, "Not Authorized");

                await encoder.BodyWriteSingleChunk("");

                return(Task.CompletedTask);
            }

            // Check fields to see if the user is authorized to modify them.
            foreach (var pair in sreq.meta)
            {
                if (!await shandler.FieldModificationValidForUser(auth_resp.user, pair.Key))
                {
                    await encoder.WriteQuickHeader(403, "Not Authorized");

                    await encoder.BodyWriteSingleChunk("");

                    return(Task.CompletedTask);
                }
            }

            try
            {
                foreach (var pair in sreq.meta)
                {
                    // Reflection simplified coding time at the expense of performance.
                    var field = item.GetType().GetField(pair.Key);
                    field.SetValue(item, pair.Value.ToObject(field.FieldType));

#if DEBUG
                    //Logger.WriteDebugString($"Set field {field} of {sreq.meta} to {pair.Value.ToString()}.");
#endif
                }

                shandler.items[sreq.security_id] = item;

                if (!await shandler.WriteItemToJournal(item))
                {
#if DEBUG
                    //Logger.WriteDebugString($"Error happened when writing to the journal for a commit set operation.");
#endif
                    await encoder.WriteQuickHeader(500, "Error");

                    await encoder.BodyWriteSingleChunk("");

                    return(Task.CompletedTask);
                }
            }
            catch (Exception)
            {
#if DEBUG
                //Logger.WriteDebugString($"Error happened when writing to journal or setting item fields during commit set operation.");
#endif
                await encoder.WriteQuickHeader(500, "Error");

                await encoder.BodyWriteSingleChunk("");

                return(Task.CompletedTask);
            }

            var resp = new MDACS.API.Responses.CommitSetResponse();

            resp.success = true;

            await encoder.WriteQuickHeader(200, "OK");

            await encoder.BodyWriteSingleChunk(JsonConvert.SerializeObject(resp));

            return(Task.CompletedTask);
        }
        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);
        }