From b302f843d76e981dd83fa6e0c0ca0221630f9515 Mon Sep 17 00:00:00 2001 From: Deepsingh Chhabda Date: Thu, 23 Feb 2023 16:09:56 -0500 Subject: [PATCH] disable edit submission for priv --- pybossa/forms/forms.py | 4 ++- pybossa/themes/default | 2 +- pybossa/view/projects.py | 70 +++++++++++++++++++++++----------------- 3 files changed, 45 insertions(+), 31 deletions(-) diff --git a/pybossa/forms/forms.py b/pybossa/forms/forms.py index 43a724ecc1..babc469449 100644 --- a/pybossa/forms/forms.py +++ b/pybossa/forms/forms.py @@ -136,7 +136,9 @@ class ProjectUpdateForm(ProjectForm): short_name = TextField(label=None, widget=HiddenInput()) long_description = TextAreaField(lazy_gettext('Long Description')) allow_anonymous_contributors = BooleanField(lazy_gettext('Allow Anonymous Contributors')) - allow_taskrun_edit = BooleanField(lazy_gettext('Allow Editing of Task Submissions')) + private_instance = data_access.data_access_levels.get("valid_access_levels", []) == ["L1", "L2", "L3", "L4"] + if not private_instance: + allow_taskrun_edit = BooleanField(lazy_gettext('Allow Editing of Task Submissions')) zip_download = BooleanField(lazy_gettext('Allow ZIP data download')) category_id = SelectField(lazy_gettext('Category'), coerce=int) hidden = BooleanField(lazy_gettext('Hide?')) diff --git a/pybossa/themes/default b/pybossa/themes/default index ed8192fbe6..8b77ed2e6f 160000 --- a/pybossa/themes/default +++ b/pybossa/themes/default @@ -1 +1 @@ -Subproject commit ed8192fbe60fd2f339a0c9f08957842446465255 +Subproject commit 8b77ed2e6f7eebad0e762d94e11273aedf782158 diff --git a/pybossa/view/projects.py b/pybossa/view/projects.py index d1a582a67c..c8e4f9827e 100644 --- a/pybossa/view/projects.py +++ b/pybossa/view/projects.py @@ -823,7 +823,8 @@ def handle_valid_form(form): 'input_data': form.input_data_class.data, 'output_data': form.output_data_class.data } - new_project.info["allow_taskrun_edit"] = form.allow_taskrun_edit.data + if "allow_taskrun_edit" in form: + new_project.info["allow_taskrun_edit"] = form.allow_taskrun_edit.data project_repo.update(new_project) auditlogger.add_log_entry(old_project, new_project, current_user) @@ -854,7 +855,7 @@ def handle_valid_form(form): project.kpi = project.info.get('kpi') project.input_data_class = project.info.get('data_classification', {}).get('input_data') project.output_data_class = project.info.get('data_classification', {}).get('output_data') - project.allow_taskrun_edit = project.info.get("allow_taskrun_edit") + project.allow_taskrun_edit = project.info.get("allow_taskrun_edit") or False ensure_amp_config_applied_to_project(project, project.info.get('annotation_config', {})) form = dynamic_project_form(ProjectUpdateForm, None, data_access_levels, obj=project, products=prodsubprods, data_classes=data_classes) @@ -1349,6 +1350,11 @@ def task_presenter(short_name, task_id, task_submitter_id=None): tp_code = process_table_component(tp_code, user_response, task) template_args["project"]["info"]["task_presenter"] = tp_code + # with edit submission, pass task run id so that taskrun can be updated + if request.args.get("mode") == "edit_submission": + template_args["taskrun_id"] = taskruns[0].id + template_args["taskrun_user_id"] = taskruns[0].user_id + def respond(tmpl): response = dict(template=tmpl, **template_args) return handle_content_type(response) @@ -1356,33 +1362,39 @@ def respond(tmpl): if not (task.project_id == project.id): return respond('/projects/task/wrong.html') - guard = ContributionsGuard(sentinel.master, - timeout=project.info.get('timeout')) - guard.stamp(task, get_user_id_or_ip()) - - # Verify the worker has an unexpired lock on the task. Otherwise, task will fail to submit. - timeout, ttl = fetch_lock_for_user(task.project_id, task_id, user_id) - remaining_time = float(ttl) - time.time() if ttl else None - if (not remaining_time or remaining_time <= 0) and mode != 'read_only': - current_app.logger.info("unable to lock task or task expired. \ - project %s, task %s, user %s, remaining time %s, mode %s", - task.project_id, task_id, user_id, remaining_time, mode) - flash(gettext("Unable to lock task or task expired. Please cancel and begin a new task."), "error") - else: - if mode != 'read_only': - # Set the original timeout seconds to display in the message. - template_args['project']['original_timeout'] = timeout - # Set the seconds remaining to display in the message. - template_args['project']['timeout'] = remaining_time - current_app.logger.info("User %s present task %s, remaining time %s, original timeout %s", - user_id, task_id, remaining_time, timeout) - - if not guard.check_task_presented_timestamp(task, get_user_id_or_ip()): - guard.stamp_presented_time(task, get_user_id_or_ip()) - - if has_no_presenter(project): - flash(gettext("Sorry, but this project is still a draft and does " - "not have a task presenter."), "error") + # bypass lock check for the submitter when submitter can edit their response + bypass_lock_check = request.args.get("mode") == "edit_submission" and \ + project.info.get("allow_taskrun_edit") and \ + current_user.id == task_submitter_id + + if not bypass_lock_check: + guard = ContributionsGuard(sentinel.master, + timeout=project.info.get('timeout')) + guard.stamp(task, get_user_id_or_ip()) + + # Verify the worker has an unexpired lock on the task. Otherwise, task will fail to submit. + timeout, ttl = fetch_lock_for_user(task.project_id, task_id, user_id) + remaining_time = float(ttl) - time.time() if ttl else None + if (not remaining_time or remaining_time <= 0) and mode != 'read_only': + current_app.logger.info("unable to lock task or task expired. \ + project %s, task %s, user %s, remaining time %s, mode %s", + task.project_id, task_id, user_id, remaining_time, mode) + flash(gettext("Unable to lock task or task expired. Please cancel and begin a new task."), "error") + else: + if mode != 'read_only': + # Set the original timeout seconds to display in the message. + template_args['project']['original_timeout'] = timeout + # Set the seconds remaining to display in the message. + template_args['project']['timeout'] = remaining_time + current_app.logger.info("User %s present task %s, remaining time %s, original timeout %s", + user_id, task_id, remaining_time, timeout) + + if not guard.check_task_presented_timestamp(task, get_user_id_or_ip()): + guard.stamp_presented_time(task, get_user_id_or_ip()) + + if has_no_presenter(project): + flash(gettext("Sorry, but this project is still a draft and does " + "not have a task presenter."), "error") return respond('/projects/presenter.html')