From a9e7935190d8fc112e674add05e86b8d0152e8df Mon Sep 17 00:00:00 2001
From: Benjamin Auder <benjamin.auder@somewhere>
Date: Mon, 30 Mar 2020 15:28:55 +0200
Subject: [PATCH] Fix pronlems edit by admins

---
 client/src/parameters.js.dist    |  5 ++++-
 client/src/views/News.vue        |  7 ++++---
 client/src/views/Problems.vue    |  4 ++--
 server/config/parameters.js.dist |  3 +++
 server/models/Problem.js         | 12 ++++++++----
 server/routes/news.js            | 14 ++++++++++----
 server/routes/problems.js        |  5 +++--
 7 files changed, 34 insertions(+), 16 deletions(-)

diff --git a/client/src/parameters.js.dist b/client/src/parameters.js.dist
index 2e47407e..b7f0899b 100644
--- a/client/src/parameters.js.dist
+++ b/client/src/parameters.js.dist
@@ -7,7 +7,10 @@ const Parameters =
   serverUrl: "http://localhost:3000",
 
   // "include" if the server is at a different address
-  credentials: "same-origin"
+  credentials: "same-origin",
+
+  // IDs of users allowed to post news and edit any problem
+  devs: []
 };
 
 export default Parameters;
diff --git a/client/src/views/News.vue b/client/src/views/News.vue
index 97f0eb84..37bd3cae 100644
--- a/client/src/views/News.vue
+++ b/client/src/views/News.vue
@@ -17,7 +17,7 @@ main
   .row
     .col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2
       button#writeNewsBtn(
-        v-if="devs.includes(st.user.id)"
+        v-if="devTeam"
         @click="showModalNews"
       )
         | {{ st.tr["Write news"] }}
@@ -27,7 +27,7 @@ main
         :class="{margintop:idx>0}"
       )
         span.ndt {{ formatDatetime(n.added) }}
-        .dev-buttons(v-if="devs.includes(st.user.id)")
+        .dev-buttons(v-if="devTeam")
           button(@click="editNews(n)") {{ st.tr["Edit"] }}
           button(@click="deleteNews(n)") {{ st.tr["Delete"] }}
         button(@click="gotoPrevNext(n, 1)") {{ st.tr["Previous_n"] }}
@@ -43,14 +43,15 @@ main
 <script>
 import { store } from "@/store";
 import { ajax } from "@/utils/ajax";
+import params from "@/parameters";
 import { getDate, getTime } from "@/utils/datetime";
 import { processModalClick } from "@/utils/modalClick";
 export default {
   name: "my-news",
   data: function() {
     return {
-      devs: [1], //for now the only dev is me
       st: store.state,
+      devTeam: params.devs.include(store.state.user.id),
       // timestamp of oldest showed news:
       cursor: Number.MAX_SAFE_INTEGER,
       // hasMore == TRUE: a priori there could be more news to load
diff --git a/client/src/views/Problems.vue b/client/src/views/Problems.vue
index a62949c8..bcfb3a39 100644
--- a/client/src/views/Problems.vue
+++ b/client/src/views/Problems.vue
@@ -115,6 +115,7 @@ main
 import { store } from "@/store";
 import { ajax } from "@/utils/ajax";
 import { checkProblem } from "@/data/problemCheck";
+import params from "@/parameters";
 import { getDiagram } from "@/utils/printDiagram";
 import { processModalClick } from "@/utils/modalClick";
 import { ArrayFun } from "@/utils/array";
@@ -154,7 +155,6 @@ export default {
       onlyMine: false,
       showOne: false,
       infoMsg: "",
-      admins: [1], //hard-coded for now. TODO
       game: {
         players: [{ name: "Problem" }, { name: "Problem" }],
         mode: "analyze"
@@ -409,7 +409,7 @@ export default {
       );
     },
     canIedit: function(puid) {
-      return this.admins.concat([puid]).includes(this.st.user.id);
+      return params.devs.concat([puid]).includes(this.st.user.id);
     },
     editProblem: function(prob) {
       // prob.diag might correspond to some other problem or be empty:
diff --git a/server/config/parameters.js.dist b/server/config/parameters.js.dist
index c1908411..c0640cd6 100644
--- a/server/config/parameters.js.dist
+++ b/server/config/parameters.js.dist
@@ -30,4 +30,7 @@ module.exports = {
     noreply: "some_noreply_email",
     contact: "some_contact_email",
   },
+
+  // IDs of users allowed to post news and edit any problem
+  devs: []
 };
diff --git a/server/models/Problem.js b/server/models/Problem.js
index 2d29520f..9978d76f 100644
--- a/server/models/Problem.js
+++ b/server/models/Problem.js
@@ -63,8 +63,10 @@ const ProblemModel = {
     });
   },
 
-  safeUpdate: function(prob, uid) {
+  safeUpdate: function(prob, uid, devs) {
     db.serialize(function() {
+      let whereClause = "WHERE id = " + prob.id;
+      if (!devs.includes(uid)) whereClause += " AND uid = " + uid;
       const query =
         "UPDATE Problems " +
         "SET " +
@@ -72,16 +74,18 @@ const ProblemModel = {
           "fen = '" + prob.fen + "'," +
           "instruction = ?," +
           "solution = ? " +
-        "WHERE id = " + prob.id + " AND uid = " + uid;
+        whereClause;
       db.run(query, [prob.instruction, prob.solution]);
     });
   },
 
-  safeRemove: function(id, uid) {
+  safeRemove: function(id, uid, devs) {
     db.serialize(function() {
+      let whereClause = "WHERE id = " + prob.id;
+      if (!devs.includes(uid)) whereClause += " AND uid = " + uid;
       const query =
         "DELETE FROM Problems " +
-        "WHERE id = " + id + " AND uid = " + uid;
+        whereClause;
       db.run(query);
     });
   },
diff --git a/server/routes/news.js b/server/routes/news.js
index af7f6ac0..e78020ef 100644
--- a/server/routes/news.js
+++ b/server/routes/news.js
@@ -1,11 +1,11 @@
 let router = require("express").Router();
 const access = require("../utils/access");
+const params = require("../config/parameters");
 const NewsModel = require("../models/News");
 const sanitizeHtml = require('sanitize-html');
-const devs = [1]; //hard-coded list of developers IDs, allowed to post news
 
 router.post("/news", access.logged, access.ajax, (req,res) => {
-  if (devs.includes(req.userId)) {
+  if (params.devs.includes(req.userId)) {
     const content = sanitizeHtml(req.body.news.content);
     NewsModel.create(content, req.userId, (err, ret) => {
       res.json(err || ret);
@@ -31,7 +31,10 @@ router.get("/newsts", access.ajax, (req,res) => {
 
 router.put("/news", access.logged, access.ajax, (req,res) => {
   let news = req.body.news;
-  if (devs.includes(req.userId) && news.id.toString().match(/^[0-9]+$/)) {
+  if (
+    params.devs.includes(req.userId) &&
+    news.id.toString().match(/^[0-9]+$/)
+  ) {
     news.content = sanitizeHtml(news.content);
     NewsModel.update(news);
     res.json({});
@@ -40,7 +43,10 @@ router.put("/news", access.logged, access.ajax, (req,res) => {
 
 router.delete("/news", access.logged, access.ajax, (req,res) => {
   const nid = req.query.id;
-  if (devs.includes(req.userId) && nid.toString().match(/^[0-9]+$/)) {
+  if (
+    params.devs.includes(req.userId) &&
+    nid.toString().match(/^[0-9]+$/)
+  ) {
     NewsModel.remove(nid);
     res.json({});
   }
diff --git a/server/routes/problems.js b/server/routes/problems.js
index 2db81bbc..746be9aa 100644
--- a/server/routes/problems.js
+++ b/server/routes/problems.js
@@ -1,5 +1,6 @@
 let router = require("express").Router();
 const access = require("../utils/access");
+const params = require("../config/parameters");
 const ProblemModel = require("../models/Problem");
 const sanitizeHtml = require('sanitize-html');
 
@@ -41,7 +42,7 @@ router.put("/problems", access.logged, access.ajax, (req,res) => {
   if (ProblemModel.checkProblem(obj)) {
     obj.instruction = sanitizeHtml(obj.instruction);
     obj.solution = sanitizeHtml(obj.solution);
-    ProblemModel.safeUpdate(obj, req.userId);
+    ProblemModel.safeUpdate(obj, req.userId, params.devs);
   }
   res.json({});
 });
@@ -49,7 +50,7 @@ router.put("/problems", access.logged, access.ajax, (req,res) => {
 router.delete("/problems", access.logged, access.ajax, (req,res) => {
   const pid = req.query.id;
   if (pid.toString().match(/^[0-9]+$/))
-    ProblemModel.safeRemove(pid, req.userId);
+    ProblemModel.safeRemove(pid, req.userId, params.devs);
   res.json({});
 });
 
-- 
2.44.0