Skip to content

Commit b9d74f5

Browse files
authored
Merge pull request #5 from pietroborrello/master
Add `force` permission to bypass server policy
2 parents 7198a4a + dcdec6d commit b9d74f5

File tree

3 files changed

+46
-6
lines changed

3 files changed

+46
-6
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ Authentication is handled via tokens defined in `tokens.json`. The file has the
3030
"search": true,
3131
"read": true,
3232
"write": true,
33-
"delete": true
33+
"delete": true,
34+
"force": true
3435
},
3536
"token2": {
3637
"search": true,
@@ -47,6 +48,7 @@ The permissions are:
4748
* `read`: Get a bibliography entry based on an identifier
4849
* `write`: Add or modify bibliography entries
4950
* `delete`: Delete bibliography entries
51+
* `force`: Allow bibliography entries writes to bypass server policy
5052

5153
## Server
5254
The server runs inside a Docker container and works on a Git-versioned bibliography file outside the container.

client.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,19 @@ def resolve_duplicate():
150150
return "i"
151151
return None
152152

153+
def resolve_policy_reject():
154+
print("Your options are")
155+
print(" force entry write to the server (F)")
156+
print(" ignore, do not apply any changes (I)")
157+
print(" abort without changes (A)")
158+
while True:
159+
action = input("Your choice [f/I/a]: ").lower()
160+
if action == "f" or action == "i" or action == "a":
161+
return action
162+
if not action or action == "":
163+
return "i"
164+
return None
165+
153166

154167
def update_local_bib(key, new_entry):
155168
for (idx, entry) in enumerate(bib_database.entries):
@@ -163,8 +176,12 @@ def update_remote_bib(key, new_entry):
163176
if "success" in response.json() and not response.json()["success"]:
164177
show_error(response.json())
165178

166-
def add_remote_bib(key, entry):
167-
response = requests.post(server + "entry/%s" % key, json = {"entry": entry, "token": token})
179+
def add_remote_bib(key, entry, force=False):
180+
if force:
181+
# do not rely on boolean encoding of `force`
182+
response = requests.post(server + "entry/%s" % key, json = {"entry": entry, "token": token, "force": "true"})
183+
else:
184+
response = requests.post(server + "entry/%s" % key, json = {"entry": entry, "token": token})
168185
if "success" in response.json() and not response.json()["success"]:
169186
show_error(response.json())
170187

@@ -275,7 +292,18 @@ def show_error(obj):
275292
response = requests.post(server + "update", json = {"entries": bib_database.entries, "token": token})
276293
result = response.json()
277294
if not result["success"]:
278-
if result["reason"] == "duplicate":
295+
if result["reason"] == "policy":
296+
#print(result["entries"])
297+
for entry in result["entries"]:
298+
print("\n[!] Server policy rejected entry %s. Reason: %s" % (entry["ID"], entry["reason"]))
299+
action = resolve_policy_reject()
300+
if action == "i":
301+
pass
302+
elif action == "a":
303+
sys.exit(1)
304+
elif action == "f":
305+
add_remote_bib(entry["ID"], entry_by_key(entry["ID"]), force=True)
306+
elif result["reason"] == "duplicate":
279307
#print(result["entries"])
280308
for dup in result["entries"]:
281309
print("\n[!] There is already a similar entry for %s on the server (%s) [Levenshtein %d]" % (dup[1], dup[2]["ID"], dup[0]))

server.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,11 @@ def add_entry(key):
216216
ok, reason = check_token(request.json["token"], "write")
217217
if not ok:
218218
return jsonify(reason)
219+
# check if the client is forcing the server policy
220+
if "force" in request.json:
221+
ok, reason = check_token(request.json["token"], "force")
222+
if not ok:
223+
return jsonify(reason)
219224

220225
if "ID" not in request.json["entry"]:
221226
request.json["entry"]["ID"] = key
@@ -224,7 +229,7 @@ def add_entry(key):
224229
if existing:
225230
return jsonify({"success": False, "reason": "exists", "entry": existing})
226231

227-
if policy:
232+
if policy and "force" not in request.json:
228233
accept, reason = policy.check(request.json["entry"], bib_database.entries)
229234
if not accept:
230235
entry = request.json["entry"]
@@ -276,6 +281,11 @@ def add_entries():
276281
ok, reason = check_token(request.json["token"], "write")
277282
if not ok:
278283
return jsonify(reason)
284+
# check if the client is forcing the server policy
285+
if "force" in request.json:
286+
ok, reason = check_token(request.json["token"], "force")
287+
if not ok:
288+
return jsonify(reason)
279289

280290
dups = []
281291
changes = False
@@ -290,7 +300,7 @@ def add_entries():
290300
if len(dup) == 0:
291301
# new entry, add
292302
if not entry_by_key(entry["ID"]):
293-
if policy:
303+
if policy and "force" not in request.json:
294304
accept, reason = policy.check(entry, bib_database.entries)
295305
if not accept:
296306
entry["reason"] = reason

0 commit comments

Comments
 (0)