diff --git a/.env b/.env index d0d83b2..46acd94 100644 --- a/.env +++ b/.env @@ -1,2 +1,8 @@ # change this to a directory on your local machine to store pubmed articles -PUBMED_DIR=./pubmed \ No newline at end of file +PUBMED_DIR=/Users/rmillikin/PubmedAbstracts + +# password hash (password is 'password' by default; to change it, you need +# to generate a hash yourself using bcrypt and put it here) +# NOTE: I can't figure out how to use dollar signs in the hash. This is hacky, +# but replace $ with ____ (four underscores). +PASSWORD_HASH="____2b____12____YfgpDEOwxLy..UkZEe0H8.0aO/AQXpbsA4sAgZ9RWQShkG4iZYl16" \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 986ac22..a8a2d68 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,6 +5,7 @@ services: context: . dockerfile: ./src/server/Dockerfile image: fast_km-server:build + command: --pw ${PASSWORD_HASH} # edit .env file to change password ports: - "5001:5000" depends_on: diff --git a/requirements.txt b/requirements.txt index e14ab95..2956b84 100755 --- a/requirements.txt +++ b/requirements.txt @@ -39,3 +39,4 @@ typing-extensions==3.10.0.2 urllib3==1.26.7 Werkzeug==2.0.2 zipp==3.6.0 +flask-bcrypt==0.7.1 \ No newline at end of file diff --git a/src/run_server.py b/src/run_server.py index 9393c4b..1b676df 100644 --- a/src/run_server.py +++ b/src/run_server.py @@ -1,7 +1,12 @@ +import argparse import server.app as app +parser = argparse.ArgumentParser() +parser.add_argument('-p', '--pw_hash', default='none') +args = parser.parse_args() + def main(): - app.start_server() + app.start_server(args.pw_hash) if __name__ == '__main__': main() \ No newline at end of file diff --git a/src/server/app.py b/src/server/app.py index 6a9cf3f..1a7115e 100644 --- a/src/server/app.py +++ b/src/server/app.py @@ -6,13 +6,19 @@ from flask_restful import Api from workers.work import km_work, skim_work, triple_miner_work, update_index_work import logging +from flask_bcrypt import Bcrypt _r = Redis(host='redis', port=6379) _q = Queue(connection=_r) _app = Flask(__name__) _api = Api(_app) +_bcrypt = Bcrypt(_app) +_pw_hash = '' + +def start_server(pw_hash: str): + global _pw_hash + _pw_hash = pw_hash.replace('____', '$') -def start_server(): # set up redis-queue dashboard _set_up_rq_dashboard() @@ -28,6 +34,17 @@ def _set_up_rq_dashboard(): _app.register_blueprint(rq_dashboard.blueprint, url_prefix="/rq") _app.config['RQ_DASHBOARD_REDIS_URL'] = 'redis://redis:6379' +def _authenticate(request): + if _pw_hash == 'none': + return True + + if request.authorization and 'password' in request.authorization: + candidate = request.authorization['password'] + else: + return False + + return _bcrypt.check_password_hash(_pw_hash, candidate) + ## ******** Generic Post/Get ******** def _post_generic(work, request, job_timeout = 43200): if request.content_type != 'application/json': @@ -36,6 +53,10 @@ def _post_generic(work, request, job_timeout = 43200): # NOTE: the max amount of time a job is allowed to take is 12 hrs by default json_data = request.get_json(request.data) + + if not _authenticate(request): + return 'Invalid password. do request.post(..., auth=(\'username\', \'password\'))', 401 + job = _q.enqueue(work, json_data, job_timeout = job_timeout) job_data = dict() @@ -47,6 +68,9 @@ def _post_generic(work, request, job_timeout = 43200): return response def _get_generic(request): + if not _authenticate(request): + return 'Invalid password. do request.post(..., auth=(\'username\', \'password\'))', 401 + id = request.args['id'] job = _q.fetch_job(id)