Skip to content
This repository has been archived by the owner on Jan 5, 2024. It is now read-only.

Commit

Permalink
Restructures the code base with more object methods
Browse files Browse the repository at this point in the history
proxy.py

    Now, Proxy class gets a must conf_path argument, and it creates the inital
    `conf` attribute from that.  Proxy also has default on_save and on_done and
    err_on_done methods.  def handle_response(self) method has a `assert
    self.res` to mark that res is populated before this call. This is for mypy

main.py
    Mostly has changes from black

entrypoint.py
    No need for fancy dynamic err_call_back, the proxy object will call
    self.err_call_back if any issue in reading configuration.

The test cases now have thier own configuration files to create the proxy
object. Also, to do proper dynamic attachment of any method of Proxy class
we are using https://docs.python.org/3/library/types.html#types.MethodType
so that our own on_save or on_done or err_on_done will be called during
tests.
  • Loading branch information
kushaldas committed Jan 7, 2020
1 parent e12b896 commit df2dc21
Show file tree
Hide file tree
Showing 12 changed files with 548 additions and 554 deletions.
44 changes: 0 additions & 44 deletions securedrop_proxy/callbacks.py

This file was deleted.

58 changes: 0 additions & 58 deletions securedrop_proxy/config.py

This file was deleted.

52 changes: 22 additions & 30 deletions securedrop_proxy/entrypoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,76 +14,68 @@

from logging.handlers import TimedRotatingFileHandler

from securedrop_proxy import callbacks
from securedrop_proxy import config
from securedrop_proxy import main
from securedrop_proxy import proxy
from securedrop_proxy.version import version


DEFAULT_HOME = os.path.join(os.path.expanduser("~"), ".securedrop_proxy")
LOGLEVEL = os.environ.get('LOGLEVEL', 'info').upper()
LOGLEVEL = os.environ.get("LOGLEVEL", "info").upper()


def start():
'''
def start() -> None:
"""
Set up a new proxy object with an error handler, configuration that we read from argv[1], and
the original user request from STDIN.
'''
"""
try:
configure_logging()

logging.debug('Starting SecureDrop Proxy {}'.format(version))

# a fresh, new proxy object
p = proxy.Proxy()

# set up an error handler early, so we can use it during
# configuration, etc
original_on_done = p.on_done
p.on_done = callbacks.err_on_done
logging.debug("Starting SecureDrop Proxy {}".format(version))

# path to config file must be at argv[1]
if len(sys.argv) != 2:
raise ValueError("sd-proxy script not called with path to configuration file")
raise ValueError(
"sd-proxy script not called with path to configuration file"
)

# read config. `read_conf` will call `p.on_done` if there is a config
# read config. `read_conf` will call `p.err_on_done` if there is a config
# problem, and will return a Conf object on success.
conf_path = sys.argv[1]
p.conf = config.read_conf(conf_path, p)
# a fresh, new proxy object
p = proxy.Proxy(conf_path=conf_path)

# read user request from STDIN
incoming = []
incoming_lines = []
for line in sys.stdin:
incoming.append(line)
incoming = "\n".join(incoming)
incoming_lines.append(line)
incoming = "\n".join(incoming_lines)

p.on_done = original_on_done
main.__main__(incoming, p)
except Exception as e:
response = {
"status": http.HTTPStatus.INTERNAL_SERVER_ERROR,
"body": json.dumps({
"error": str(e),
})
"body": json.dumps({"error": str(e),}),
}
print(json.dumps(response))
sys.exit(1)


def configure_logging() -> None:
'''
"""
All logging related settings are set up by this function.
'''
"""
home = os.getenv("SECUREDROP_HOME", DEFAULT_HOME)
log_folder = os.path.join(home, 'logs')
log_folder = os.path.join(home, "logs")
if not os.path.exists(log_folder):
os.makedirs(log_folder)

log_file = os.path.join(home, 'logs', 'proxy.log')
log_file = os.path.join(home, "logs", "proxy.log")

# set logging format
log_fmt = ('%(asctime)s - %(name)s:%(lineno)d(%(funcName)s) %(levelname)s: %(message)s')
log_fmt = (
"%(asctime)s - %(name)s:%(lineno)d(%(funcName)s) %(levelname)s: %(message)s"
)
formatter = logging.Formatter(log_fmt)

# define log handlers such as for rotating log files
Expand Down
33 changes: 17 additions & 16 deletions securedrop_proxy/main.py
Original file line number Diff line number Diff line change
@@ -1,44 +1,45 @@
import json
import logging
from typing import Dict, Any

from securedrop_proxy import callbacks
from securedrop_proxy import proxy


from securedrop_proxy.proxy import Proxy

logger = logging.getLogger(__name__)


def __main__(incoming, p):
'''
def __main__(incoming: str, p: Proxy) -> None:
"""
Deserialize incoming request in order to build and send a proxy request.
'''
logging.debug('Creating request to be sent by proxy')
"""
logging.debug("Creating request to be sent by proxy")

client_req = None
client_req: Dict[str, Any] = {}
try:
client_req = json.loads(incoming)
except json.decoder.JSONDecodeError as e:
logging.error(e)
p.simple_error(400, 'Invalid JSON in request')
p.on_done(p.res)
p.simple_error(400, "Invalid JSON in request")
p.on_done()
return

req = proxy.Req()
try:
req.method = client_req['method']
req.path_query = client_req['path_query']
req.method = client_req["method"]
req.path_query = client_req["path_query"]
except KeyError as e:
logging.error(e)
p.simple_error(400, 'Missing keys in request')
p.on_done(p.res)
p.simple_error(400, "Missing keys in request")
p.on_done()

if "headers" in client_req:
req.headers = client_req['headers']
req.headers = client_req["headers"]

if "body" in client_req:
req.body = client_req['body']
req.body = client_req["body"]

p.req = req
if not p.on_save:
p.on_save = callbacks.on_save

p.proxy()
Loading

0 comments on commit df2dc21

Please sign in to comment.