diff --git a/app/job/rest.py b/app/job/rest.py index 9a7de309c..938c19450 100644 --- a/app/job/rest.py +++ b/app/job/rest.py @@ -58,8 +58,17 @@ def is_valid_id(id): return bool(re.match(r"^[a-zA-Z0-9_-]{1,50}$", id)) +def check_suspicious_id(id): + if not is_valid_id(id): + abort(403) + if is_suspicious_input(id): + abort(403) + + @job_blueprint.route("/", methods=["GET"]) def get_job_by_service_and_job_id(service_id, job_id): + check_suspicious_id(service_id) + check_suspicious_id(job_id) job = dao_get_job_by_service_id_and_job_id(service_id, job_id) statistics = dao_get_notification_outcomes_for_job(service_id, job_id) data = JobSchema(session=db.session).dump(job) @@ -73,6 +82,9 @@ def get_job_by_service_and_job_id(service_id, job_id): @job_blueprint.route("//cancel", methods=["POST"]) def cancel_job(service_id, job_id): + check_suspicious_id(service_id) + check_suspicious_id(job_id) + job = dao_get_future_scheduled_job_by_id_and_service_id(job_id, service_id) job.job_status = JobStatus.CANCELLED dao_update_job(job) @@ -82,6 +94,9 @@ def cancel_job(service_id, job_id): @job_blueprint.route("//notifications", methods=["GET"]) def get_all_notifications_for_service_job(service_id, job_id): + check_suspicious_id(service_id) + check_suspicious_id(job_id) + data = notifications_filter_schema.load(request.args) page = data["page"] if "page" in data else 1 page_size = ( @@ -143,6 +158,9 @@ def get_all_notifications_for_service_job(service_id, job_id): @job_blueprint.route("//recent_notifications", methods=["GET"]) def get_recent_notifications_for_service_job(service_id, job_id): + check_suspicious_id(service_id) + check_suspicious_id(job_id) + data = notifications_filter_schema.load(request.args) page = data["page"] if "page" in data else 1 page_size = ( @@ -208,16 +226,9 @@ def get_recent_notifications_for_service_job(service_id, job_id): @job_blueprint.route("//notification_count", methods=["GET"]) def get_notification_count_for_job_id(service_id, job_id): - if is_suspicious_input(service_id) or is_suspicious_input(job_id): - current_app.logger.error( - f"Service Id {service_id} is suspicious input or job id {job_id} is." - ) - abort(403) - if not is_valid_id(service_id) or not is_valid_id(job_id): - current_app.logger.error( - f"service id {service_id} or job_id {job_id} is not a valid id" - ) - abort(403) + check_suspicious_id(service_id) + check_suspicious_id(job_id) + dao_get_job_by_service_id_and_job_id(service_id, job_id) count = dao_get_notification_count_for_job_id(job_id=job_id) return jsonify(count=count), 200 @@ -225,6 +236,7 @@ def get_notification_count_for_job_id(service_id, job_id): @job_blueprint.route("", methods=["GET"]) def get_jobs_by_service(service_id): + check_suspicious_id(service_id) if request.args.get("limit_days"): try: limit_days = int(request.args["limit_days"]) @@ -258,6 +270,8 @@ def get_jobs_by_service(service_id): @job_blueprint.route("", methods=["POST"]) def create_job(service_id): + check_suspicious_id(service_id) + """Entry point from UI for one-off messages as well as CSV uploads.""" service = dao_fetch_service_by_id(service_id) if not service.active: @@ -277,6 +291,7 @@ def create_job(service_id): ) data["template"] = data.pop("template_id") + check_suspicious_id(data["template"]) template = dao_get_template_by_id(data["template"]) if data.get("valid") != "True": @@ -301,6 +316,7 @@ def create_job(service_id): dao_create_job(job) sender_id = data.get("sender_id") + check_suspicious_id(sender_id) # Kick off job in tasks.py if job.job_status == JobStatus.PENDING: process_job.apply_async( @@ -315,6 +331,8 @@ def create_job(service_id): @job_blueprint.route("/scheduled-job-stats", methods=["GET"]) def get_scheduled_job_stats(service_id): + check_suspicious_id(service_id) + count, soonest_scheduled_for = dao_get_scheduled_job_stats(service_id) return ( jsonify(