From 16eaa7814a183a00a4f76c8199193de88de7f7f0 Mon Sep 17 00:00:00 2001 From: Igor Chubin Date: Sun, 31 Jan 2021 18:34:35 +0100 Subject: [PATCH] Add devkeys support --- bin/app.py | 7 +++++++ lib/adapter/internal.py | 8 +++++++- lib/config.py | 1 + lib/devkeys.py | 43 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 lib/devkeys.py diff --git a/bin/app.py b/bin/app.py index 17acc03..6565b8a 100644 --- a/bin/app.py +++ b/bin/app.py @@ -24,12 +24,14 @@ if sys.version_info[0] < 3: import sys import logging import os + import requests import jinja2 from flask import Flask, request, send_from_directory, redirect, Response sys.path.append(os.path.abspath(os.path.join(__file__, "..", "..", "lib"))) from config import CONFIG +from devkeys import Devkeys from limits import Limits from cheat_wrapper import cheat_wrapper from post import process_post_request @@ -279,6 +281,11 @@ def answer(topic=None): if lang: options['lang'] = lang + options["authorized"] = "" + if ("X-Cheatsh-Key" in request.headers and + Devkeys.check(request.headers.get("X-Cheatsh-Key"))): + options["authorized"] = Devkeys.check(request.headers.get("X-Cheatsh-Key")) + ip_address = get_request_ip(request) if '+' in topic: not_allowed = LIMITS.check_ip(ip_address) diff --git a/lib/adapter/internal.py b/lib/adapter/internal.py index da1e416..6e0a094 100644 --- a/lib/adapter/internal.py +++ b/lib/adapter/internal.py @@ -21,6 +21,7 @@ from .adapter import Adapter from fmt.internal import colorize_internal _INTERNAL_TOPICS = [ + ":authorized", ":cht.sh", ":bash_completion", ":emacs", @@ -88,7 +89,12 @@ class InternalPages(Adapter): return self._get_list_answer(topic) answer = "" - if topic == ':styles': + if topic == ":authorized": + if request_options.get("authorized"): + answer = "AUTHORIZED (%s)\n" % (request_options.get("authorized")) + else: + answer = "NOT AUTHORIZED\n" + elif topic == ':styles': answer = "\n".join(CONFIG["frontend.styles"]) + "\n" elif topic == ":stat": answer = self._get_stat()+"\n" diff --git a/lib/config.py b/lib/config.py index 25c9785..9714928 100644 --- a/lib/config.py +++ b/lib/config.py @@ -101,6 +101,7 @@ _CONFIG = { "path.internal.ansi2html": os.path.join(_MYDIR, "share/ansi2html.sh"), "path.internal.bin": os.path.join(_MYDIR, "bin"), "path.internal.bin.upstream": os.path.join(_MYDIR, "bin", "upstream"), + "path.internal.keysfile": os.path.join(_MYDIR, "etc/devkeys.txt"), "path.internal.malformed": os.path.join(_MYDIR, "share/static/malformed-response.html"), "path.internal.pages": os.path.join(_MYDIR, "share"), "path.internal.static": os.path.join(_MYDIR, "share/static"), diff --git a/lib/devkeys.py b/lib/devkeys.py new file mode 100644 index 0000000..796774a --- /dev/null +++ b/lib/devkeys.py @@ -0,0 +1,43 @@ +#pylint: disable=too-few-public-methods + +""" +Developer keys validator +""" + +import os + +from config import CONFIG + +class DevkeysChecker: + + """ + Developer keys validator class + """ + + def __init__(self): + + self._keys = {} + self._load_keys() + + def check(self, key: str) -> str: + """ + Check `key` and return True if it is valid. + """ + return self._keys.get(key) + + def _load_keys(self) -> None: + filename = self._get_keys_file() + if not os.path.exists(filename): + return + with open(filename, "r") as f_keys: + for line in f_keys.readlines(): + parts = line.strip().split() + if len(parts) < 2: + continue + self._keys[parts[0]] = parts[1] + + @staticmethod + def _get_keys_file() -> str: + return CONFIG["path.internal.keysfile"] + +Devkeys = DevkeysChecker()