public IActionResult CreateEntry([FromForm] string simp, [FromForm] string trad,
                                         [FromForm] string pinyin, [FromForm] string trg, [FromForm] string note)
        {
            if (simp == null)
            {
                return(StatusCode(400, "Missing 'simp' parameter."));
            }
            if (trad == null)
            {
                return(StatusCode(400, "Missing 'trad' parameter."));
            }
            if (pinyin == null)
            {
                return(StatusCode(400, "Missing 'pinyin' parameter."));
            }
            if (trg == null)
            {
                return(StatusCode(400, "Missing 'trg' parameter."));
            }
            if (note == null)
            {
                return(StatusCode(400, "Missing 'note' parameter."));
            }

            // Must be authenticated user
            int    userId;
            string userName;

            auth.CheckSession(HttpContext.Request.Headers, out userId, out userName);
            if (userId < 0)
            {
                return(StatusCode(401, "Request must not contain authentication token."));
            }

            NewEntrySubmitResult res = new NewEntrySubmitResult {
                Success = true
            };

            SqlDict.SimpleBuilder builder = null;
            try
            {
                builder = dict.GetSimpleBuilder(userId);
                CedictEntry entry = Utils.BuildEntry(simp, trad, pinyin, trg);
                builder.NewEntry(entry, note);
                // Refresh cached contrib score
                auth.RefreshUserInfo(userId);
            }
            catch (Exception ex)
            {
                // TO-DO: Log
                //DiagLogger.LogError(ex);
                res.Success = false;
            }
            finally { if (builder != null)
                      {
                          builder.Dispose();
                      }
            }

            // Tell our caller
            return(new ObjectResult(res));
        }
        public IActionResult CommentEntry([FromForm] string entryId, [FromForm] string note, [FromForm] string statusChange)
        {
            if (entryId == null || note == null || statusChange == null)
            {
                return(StatusCode(400, "Missing parameter(s)."));
            }
            // Supported/expected status changes
            SqlDict.Builder.StatusChange change;
            if (statusChange == "none")
            {
                change = SqlDict.Builder.StatusChange.None;
            }
            else if (statusChange == "approve")
            {
                change = SqlDict.Builder.StatusChange.Approve;
            }
            else if (statusChange == "flag")
            {
                change = SqlDict.Builder.StatusChange.Flag;
            }
            else if (statusChange == "unflag")
            {
                change = SqlDict.Builder.StatusChange.Unflag;
            }
            else
            {
                return(StatusCode(400, "Invalid statusChange parameter."));
            }

            // Must be authenticated user
            int    userId;
            string userName;

            auth.CheckSession(HttpContext.Request.Headers, out userId, out userName);
            if (userId < 0)
            {
                return(StatusCode(401, "Request must contain authentication token."));
            }

            // If status change is approve: is user entitled to do it?
            bool canApprove = false;

            if (change == SqlDict.Builder.StatusChange.Approve)
            {
                canApprove = auth.CanApprove(userId);
                if (!canApprove)
                {
                    return(StatusCode(401, "User is not authorized to approve entries."));
                }
            }

            bool success = false;

            SqlDict.SimpleBuilder builder = null;
            try
            {
                int idVal = EntryId.StringToId(entryId);
                builder = dict.GetSimpleBuilder(userId);
                builder.CommentEntry(idVal, note, change);
                // Refresh cached contrib score
                auth.RefreshUserInfo(userId);
                success = true;
            }
            catch (Exception ex)
            {
                // TO-DO: Log
                //DiagLogger.LogError(ex);
            }
            finally { if (builder != null)
                      {
                          builder.Dispose();
                      }
            }

            // Tell our caller
            return(new ObjectResult(success));
        }