From 1e979ad5197f19ad35a026e2674850ad7a4e7804 Mon Sep 17 00:00:00 2001 From: Jim Moffet Date: Fri, 1 Jul 2022 07:58:58 -0700 Subject: [PATCH] fix basic auth for live environment --- .flake8 | 15 --------------- app/__init__.py | 19 ++++++++++++++++++- app/config.py | 4 ++-- app/custom_auth.py | 17 +++++++++++++++++ app/main/views/index.py | 3 ++- app/status/views/healthcheck.py | 16 +++++++++++++++- application.log.json | 18 ++++++++++++++++++ manifest.yml | 7 +++++-- varsfile.sample | 1 + 9 files changed, 78 insertions(+), 22 deletions(-) delete mode 100644 .flake8 create mode 100644 app/custom_auth.py create mode 100644 application.log.json diff --git a/.flake8 b/.flake8 deleted file mode 100644 index dc53bee7e..000000000 --- a/.flake8 +++ /dev/null @@ -1,15 +0,0 @@ -[flake8] -# Rule definitions: http://flake8.pycqa.org/en/latest/user/error-codes.html -exclude = venv*,__pycache__,node_modules,cache -max-complexity = 14 -max-line-length = 120 - -# B003 assigning to os.environ -# B306 BaseException.message has been deprecated -# W503: line break before binary operator -# W504 line break after binary operator -extend_ignore= - B003, - B306, - W503, - W504 diff --git a/app/__init__.py b/app/__init__.py index 0c4dd51d2..76bf55333 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -14,6 +14,7 @@ from flask import ( request, session, url_for, + jsonify ) from flask.globals import _lookup_req_object, _request_ctx_stack from flask_login import LoginManager, current_user @@ -222,7 +223,9 @@ def create_app(application): login_manager.session_protection = None login_manager.anonymous_user = AnonymousUser - basic_auth = BasicAuth(application) + # basic_auth = BasicAuth(application) + + setup_basic_auth(application) # make sure we handle unicode correctly redis_client.redis_store.decode_responses = True @@ -589,3 +592,17 @@ def init_jinja(application): ] jinja_loader = jinja2.FileSystemLoader(template_folders) application.jinja_loader = jinja_loader + +class CustomBasicAuth(BasicAuth): + """ + Description: + Override BasicAuth to permit anonymous healthcheck at /_status?simple=true + """ + def challenge(self): + if "/_status" in request.url: + if request.args.get('elb', None) or request.args.get('simple', None): + return jsonify(status="ok"), 200 + return super(CustomBasicAuth, self).challenge() + +def setup_basic_auth(application): + application.basic_auth = CustomBasicAuth(application) diff --git a/app/config.py b/app/config.py index f16963582..c6c0d1fc8 100644 --- a/app/config.py +++ b/app/config.py @@ -23,7 +23,7 @@ class Config(object): # Logging DEBUG = False - NOTIFY_LOG_PATH = os.getenv('NOTIFY_LOG_PATH') + NOTIFY_LOG_PATH = os.environ.get('NOTIFY_LOG_PATH', 'application.log') ADMIN_CLIENT_USER_NAME = 'notify-admin' @@ -40,7 +40,7 @@ class Config(object): HEADER_COLOUR = '#81878b' # mix(govuk-colour("dark-grey"), govuk-colour("mid-grey")) HTTP_PROTOCOL = 'http' NOTIFY_APP_NAME = 'admin' - NOTIFY_LOG_LEVEL = 'DEBUG' + NOTIFY_LOG_LEVEL = os.environ.get('NOTIFY_LOG_LEVEL', 'DEBUG') PERMANENT_SESSION_LIFETIME = 20 * 60 * 60 # 20 hours SEND_FILE_MAX_AGE_DEFAULT = 365 * 24 * 60 * 60 # 1 year SESSION_COOKIE_HTTPONLY = True diff --git a/app/custom_auth.py b/app/custom_auth.py new file mode 100644 index 000000000..3989878c3 --- /dev/null +++ b/app/custom_auth.py @@ -0,0 +1,17 @@ +from flask_basicauth import BasicAuth +from flask import jsonify, request + +class CustomBasicAuth(BasicAuth): + """ + Description: + + Usage: + + """ + + def check_credentials(self, username, password): + # here, for example, you can search user in the database by passed `username` and `password`, etc. + return username == 'user' and password == 'password' + + +custom_basic_auth = CustomBasicAuth() \ No newline at end of file diff --git a/app/main/views/index.py b/app/main/views/index.py index 06a6ecfc4..e0e6ae7e7 100644 --- a/app/main/views/index.py +++ b/app/main/views/index.py @@ -30,7 +30,8 @@ def index(): return render_template( 'views/signedout.html', sms_rate=CURRENT_SMS_RATE, - counts=status_api_client.get_count_of_live_services_and_organisations() + counts={"organisations":0,"services":1} + # counts=status_api_client.get_count_of_live_services_and_organisations() ) diff --git a/app/status/views/healthcheck.py b/app/status/views/healthcheck.py index 11b5871af..7e54469ac 100644 --- a/app/status/views/healthcheck.py +++ b/app/status/views/healthcheck.py @@ -1,9 +1,23 @@ from flask import current_app, jsonify, request from notifications_python_client.errors import HTTPError -from app import status_api_client, version +from app import status_api_client, version, basic_auth from app.status import status +from functools import wraps + + +def health_check(): + def wrapper(fn): + @wraps(fn) + def decorator(*args, **kwargs): + return jsonify(status="ok"), 200 + # if '/_status' in request.url: + # return jsonify(status="ok"), 200 + # else: + # return fn(*args, **kwargs) + return decorator + return wrapper @status.route('/_status', methods=['GET']) def show_status(): diff --git a/application.log.json b/application.log.json new file mode 100644 index 000000000..83e31fd48 --- /dev/null +++ b/application.log.json @@ -0,0 +1,18 @@ +{"name": "app", "levelname": "INFO", "message": "Logging configured", "pathname": "/home/vscode/.local/lib/python3.9/site-packages/notifications_utils/logging.py", "lineno": 37, "time": "2022-07-01T04:52:54", "requestId": "no-request-id", "application": "admin", "service_id": "no-service-id", "logType": "application"} +{"name": "app", "levelname": "ERROR", "message": "The session is unavailable because no secret key was set. Set the secret_key on the application to something unique and secret.", "pathname": "/workspace/app/__init__.py", "lineno": 493, "exc_info": "Traceback (most recent call last):\n File \"/home/vscode/.local/lib/python3.9/site-packages/flask/app.py\", line 1521, in full_dispatch_request\n rv = self.preprocess_request()\n File \"/home/vscode/.local/lib/python3.9/site-packages/flask/app.py\", line 1861, in preprocess_request\n rv = self.ensure_sync(before_func)()\n File \"/workspace/app/__init__.py\", line 306, in make_session_permanent\n session.permanent = True\n File \"/home/vscode/.local/lib/python3.9/site-packages/flask/sessions.py\", line 30, in permanent\n self[\"_permanent\"] = bool(value)\n File \"/home/vscode/.local/lib/python3.9/site-packages/flask/sessions.py\", line 97, in _fail\n raise RuntimeError(\nRuntimeError: The session is unavailable because no secret key was set. Set the secret_key on the application to something unique and secret.", "time": "2022-07-01T04:54:13", "requestId": null, "application": "admin", "service_id": "no-service-id", "logType": "application"} +{"name": "app", "levelname": "INFO", "message": "Logging configured", "pathname": "/home/vscode/.local/lib/python3.9/site-packages/notifications_utils/logging.py", "lineno": 37, "time": "2022-07-01T05:18:26", "requestId": "no-request-id", "application": "admin", "service_id": "no-service-id", "logType": "application"} +{"name": "app", "levelname": "INFO", "message": "Logging configured", "pathname": "/home/vscode/.local/lib/python3.9/site-packages/notifications_utils/logging.py", "lineno": 37, "time": "2022-07-01T05:32:47", "requestId": "no-request-id", "application": "admin", "service_id": "no-service-id", "logType": "application"} +{"name": "app", "levelname": "INFO", "message": "Logging configured", "pathname": "/home/vscode/.local/lib/python3.9/site-packages/notifications_utils/logging.py", "lineno": 37, "time": "2022-07-01T05:32:48", "requestId": "no-request-id", "application": "admin", "service_id": "no-service-id", "logType": "application"} +{"name": "app", "levelname": "INFO", "message": "Logging configured", "pathname": "/home/vscode/.local/lib/python3.9/site-packages/notifications_utils/logging.py", "lineno": 37, "time": "2022-07-01T05:37:27", "requestId": "no-request-id", "application": "admin", "service_id": "no-service-id", "logType": "application"} +{"name": "app", "levelname": "INFO", "message": "Logging configured", "pathname": "/home/vscode/.local/lib/python3.9/site-packages/notifications_utils/logging.py", "lineno": 37, "time": "2022-07-01T05:38:38", "requestId": "no-request-id", "application": "admin", "service_id": "no-service-id", "logType": "application"} +{"name": "app", "levelname": "INFO", "message": "Logging configured", "pathname": "/home/vscode/.local/lib/python3.9/site-packages/notifications_utils/logging.py", "lineno": 37, "time": "2022-07-01T05:38:44", "requestId": "no-request-id", "application": "admin", "service_id": "no-service-id", "logType": "application"} +{"name": "app", "levelname": "INFO", "message": "Logging configured", "pathname": "/home/vscode/.local/lib/python3.9/site-packages/notifications_utils/logging.py", "lineno": 37, "time": "2022-07-01T05:39:27", "requestId": "no-request-id", "application": "admin", "service_id": "no-service-id", "logType": "application"} +{"name": "app", "levelname": "INFO", "message": "Logging configured", "pathname": "/home/vscode/.local/lib/python3.9/site-packages/notifications_utils/logging.py", "lineno": 37, "time": "2022-07-01T05:39:28", "requestId": "no-request-id", "application": "admin", "service_id": "no-service-id", "logType": "application"} +{"name": "app", "levelname": "INFO", "message": "Logging configured", "pathname": "/home/vscode/.local/lib/python3.9/site-packages/notifications_utils/logging.py", "lineno": 37, "time": "2022-07-01T05:40:02", "requestId": "no-request-id", "application": "admin", "service_id": "no-service-id", "logType": "application"} +{"name": "app", "levelname": "INFO", "message": "Logging configured", "pathname": "/home/vscode/.local/lib/python3.9/site-packages/notifications_utils/logging.py", "lineno": 37, "time": "2022-07-01T05:40:03", "requestId": "no-request-id", "application": "admin", "service_id": "no-service-id", "logType": "application"} +{"name": "app", "levelname": "INFO", "message": "Logging configured", "pathname": "/home/vscode/.local/lib/python3.9/site-packages/notifications_utils/logging.py", "lineno": 37, "time": "2022-07-01T05:40:23", "requestId": "no-request-id", "application": "admin", "service_id": "no-service-id", "logType": "application"} +{"name": "app", "levelname": "INFO", "message": "Logging configured", "pathname": "/home/vscode/.local/lib/python3.9/site-packages/notifications_utils/logging.py", "lineno": 37, "time": "2022-07-01T05:40:25", "requestId": "no-request-id", "application": "admin", "service_id": "no-service-id", "logType": "application"} +{"name": "app", "levelname": "INFO", "message": "Logging configured", "pathname": "/home/vscode/.local/lib/python3.9/site-packages/notifications_utils/logging.py", "lineno": 37, "time": "2022-07-01T05:47:05", "requestId": "no-request-id", "application": "admin", "service_id": "no-service-id", "logType": "application"} +{"name": "app", "levelname": "INFO", "message": "Logging configured", "pathname": "/home/vscode/.local/lib/python3.9/site-packages/notifications_utils/logging.py", "lineno": 37, "time": "2022-07-01T05:47:06", "requestId": "no-request-id", "application": "admin", "service_id": "no-service-id", "logType": "application"} +{"name": "app", "levelname": "INFO", "message": "Logging configured", "pathname": "/home/vscode/.local/lib/python3.9/site-packages/notifications_utils/logging.py", "lineno": 37, "time": "2022-07-01T05:53:38", "requestId": "no-request-id", "application": "admin", "service_id": "no-service-id", "logType": "application"} +{"name": "app", "levelname": "INFO", "message": "Logging configured", "pathname": "/home/vscode/.local/lib/python3.9/site-packages/notifications_utils/logging.py", "lineno": 37, "time": "2022-07-01T05:53:39", "requestId": "no-request-id", "application": "admin", "service_id": "no-service-id", "logType": "application"} diff --git a/manifest.yml b/manifest.yml index 2c99307a5..179a56b92 100644 --- a/manifest.yml +++ b/manifest.yml @@ -25,13 +25,16 @@ applications: # Credentials variables ADMIN_CLIENT_SECRET: ((ADMIN_CLIENT_SECRET)) - ADMIN_BASE_URL: notifications-admin.app.cloud.gov - API_HOST_NAME: notifications-api.app.cloud.gov + ADMIN_BASE_URL: https://notifications-admin.app.cloud.gov + API_HOST_NAME: https://notifications-api.app.cloud.gov DANGEROUS_SALT: ((DANGEROUS_SALT)) SECRET_KEY: ((SECRET_KEY)) AWS_REGION: us-west-2 AWS_ACCESS_KEY_ID: ((AWS_ACCESS_KEY_ID)) AWS_SECRET_ACCESS_KEY: ((AWS_SECRET_ACCESS_KEY)) + BASIC_AUTH_USERNAME: ((BASIC_AUTH_USERNAME)) + BASIC_AUTH_PASSWORD: ((BASIC_AUTH_PASSWORD)) + NOTIFY_LOG_LEVEL: ((NOTIFY_LOG_LEVEL)) NOTIFY_BILLING_DETAILS: [] diff --git a/varsfile.sample b/varsfile.sample index cc0fef4ee..c4c7a6d54 100644 --- a/varsfile.sample +++ b/varsfile.sample @@ -7,3 +7,4 @@ AWS_ACCESS_KEY_ID: asdf AWS_SECRET_ACCESS_KEY: asdf BASIC_AUTH_USERNAME: asdf BASIC_AUTH_PASSWORD: asdf +NOTIFY_LOG_LEVEL: asdf