Merge branch 'staging' into safe_redirect

This commit is contained in:
graham-dds 2020-01-30 10:42:33 -05:00 committed by GitHub
commit 05ef9131dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 130 additions and 21 deletions

View File

@ -257,6 +257,7 @@ To generate coverage reports for the Javascript tests:
- `SESSION_COOKIE_DOMAIN`: String value specifying the name to use for the session cookie. This should be set to the root domain so that it is valid for both the main site and the authentication subdomain. https://flask.palletsprojects.com/en/1.1.x/config/#SESSION_COOKIE_DOMAIN
- `SESSION_KEY_PREFIX`: A prefix that is added before all session keys: https://pythonhosted.org/Flask-Session/#configuration
- `SESSION_TYPE`: String value specifying the cookie storage backend. https://pythonhosted.org/Flask-Session/
- `SESSION_COOKIE_SECURE`: https://flask.palletsprojects.com/en/1.1.x/config/#SESSION_COOKIE_SECURE
- `SESSION_USE_SIGNER`: Boolean value specifying if the cookie sid should be signed.
- `SQLALCHEMY_ECHO`: Boolean value specifying if SQLAlchemy should log queries to stdout.
- `STATIC_URL`: URL specifying where static assets are hosted.

View File

@ -70,7 +70,12 @@ def update_task_order(form, portfolio_id=None, task_order_id=None, flash_invalid
def update_and_render_next(
form_data, next_page, current_template, portfolio_id=None, task_order_id=None
form_data,
next_page,
current_template,
portfolio_id=None,
task_order_id=None,
previous=False,
):
form = None
if task_order_id:
@ -80,8 +85,9 @@ def update_and_render_next(
form = TaskOrderForm(form_data)
task_order = update_task_order(form, portfolio_id, task_order_id)
if task_order:
return redirect(url_for(next_page, task_order_id=task_order.id))
if task_order or previous:
to_id = task_order.id if task_order else task_order_id
return redirect(url_for(next_page, task_order_id=to_id))
else:
return (
render_task_orders_edit(
@ -210,12 +216,21 @@ def form_step_two_add_number(task_order_id):
@task_orders_bp.route("/task_orders/<task_order_id>/form/step_2", methods=["POST"])
@user_can(Permissions.CREATE_TASK_ORDER, message="update task order form")
def submit_form_step_two_add_number(task_order_id):
previous = http_request.args.get("previous", "False").lower() == "true"
form_data = {**http_request.form}
next_page = "task_orders.form_step_three_add_clins"
next_page = (
"task_orders.form_step_three_add_clins"
if not previous
else "task_orders.form_step_one_add_pdf"
)
current_template = "task_orders/step_2.html"
return update_and_render_next(
form_data, next_page, current_template, task_order_id=task_order_id
form_data,
next_page,
current_template,
task_order_id=task_order_id,
previous=previous,
)
@ -230,12 +245,21 @@ def form_step_three_add_clins(task_order_id):
@task_orders_bp.route("/task_orders/<task_order_id>/form/step_3", methods=["POST"])
@user_can(Permissions.CREATE_TASK_ORDER, message="update task order form")
def submit_form_step_three_add_clins(task_order_id):
previous = http_request.args.get("previous", "False").lower() == "true"
form_data = {**http_request.form}
next_page = "task_orders.form_step_four_review"
next_page = (
"task_orders.form_step_four_review"
if not previous
else "task_orders.form_step_two_add_number"
)
current_template = "task_orders/step_3.html"
return update_and_render_next(
form_data, next_page, current_template, task_order_id=task_order_id
form_data,
next_page,
current_template,
task_order_id=task_order_id,
previous=previous,
)

View File

@ -43,6 +43,7 @@ SERVER_NAME
SESSION_COOKIE_NAME=atat
SESSION_COOKIE_DOMAIN
SESSION_KEY_PREFIX=session:
SESSION_COOKIE_SECURE=false
SESSION_TYPE = redis
SESSION_USE_SIGNER = True
SQLALCHEMY_ECHO = False

View File

@ -32,6 +32,7 @@ data:
REDIS_HOST: atat.redis.cache.windows.net:6380
REDIS_TLS: "true"
SESSION_COOKIE_DOMAIN: atat.code.mil
SESSION_COOKIE_SECURE: "true"
STATIC_URL: https://atat-cdn.azureedge.net/static/
TZ: UTC
UWSGI_CONFIG_FULLPATH: /opt/atat/atst/uwsgi.ini

View File

@ -10,7 +10,7 @@ data:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; always";
# Set SSL protocols, ciphers, and related options
ssl_protocols TLSv1.3 TLSv1.2;
ssl_ciphers TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_ciphers TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:!EXPORT;
ssl_prefer_server_ciphers on;
ssl_ecdh_curve X25519:prime256v1:secp384r1;
ssl_dhparam /etc/ssl/dhparam.pem;

View File

@ -14,10 +14,14 @@
{% call Modal(name='cancel', dismissable=True) %}
<div class="task-order__modal-cancel">
<h1>Do you want to save this draft?</h1>
<h1>{{ 'task_orders.form.builder_base.cancel_modal' | translate }}</h1>
<div class="action-group">
<button formaction="{{ cancel_discard_url }}" class="usa-button usa-button-primary" type="submit">No, delete it</button>
<button formaction="{{ cancel_save_url }}" class="usa-button usa-button-primary" type="submit">Yes, save for later</button>
<button formaction="{{ cancel_discard_url }}" class="usa-button usa-button-primary" type="submit">
{{ "task_orders.form.builder_base.delete_draft" | translate }}
</button>
<button formaction="{{ cancel_save_url }}" class="usa-button usa-button-primary" type="submit">
{{ "task_orders.form.builder_base.save_draft" | translate }}
</button>
</div>
</div>
{% endcall %}
@ -39,9 +43,20 @@
{% endblock %}
{% if step != "1" %}
<a class="usa-button usa-button-secondary" href="{{ previous_button_link }}">
Previous
</a>
{% if step == "2" or step == "3" -%}
<button
type="submit"
class="usa-button usa-button-secondary"
formaction="{{ previous_button_link }}">
{{ "common.previous" | translate }}
</button>
{% else -%}
<a
class="usa-button usa-button-secondary"
href="{{ previous_button_link }}">
{{ "common.previous" | translate }}
</a>
{%- endif %}
{% endif %}
<a

View File

@ -7,7 +7,7 @@
{%- endif %}
{% if to_number %}
<p>
<strong>Task Order Number:</strong> {{ to_number }}
{{ "task_orders.form.builder_base.to_number" | translate({ "number": to_number }) | safe }}
</p>
{% endif %}
{% if description %}

View File

@ -10,7 +10,7 @@
{% set action = url_for("task_orders.submit_form_step_one_add_pdf", portfolio_id=portfolio.id) %}
{% endif %}
{% set next_button_text = "Next: Add TO Number" %}
{% set next_button_text = "task_orders.form.step_1.next_button" | translate %}
{% set step = "1" %}
{% set sticky_cta_text = 'task_orders.form.sticky_header_text' | translate %}

View File

@ -4,8 +4,8 @@
{% from "task_orders/form_header.html" import TOFormStepHeader %}
{% set action = url_for("task_orders.submit_form_step_two_add_number", task_order_id=task_order_id) %}
{% set next_button_text = "Next: Add Base CLIN" %}
{% set previous_button_link = url_for("task_orders.form_step_one_add_pdf", task_order_id=task_order_id) %}
{% set next_button_text = "task_orders.form.step_2.next_button" | translate %}
{% set previous_button_link = url_for("task_orders.submit_form_step_two_add_number", task_order_id=task_order_id, previous=True) %}
{% set step = "2" %}
{% set sticky_cta_text = 'task_orders.form.sticky_header_text' | translate %}

View File

@ -6,7 +6,7 @@
{% set action = url_for("task_orders.submit_form_step_three_add_clins", task_order_id=task_order_id) %}
{% set next_button_text = "task_orders.form.step_3.next_button" | translate %}
{% set previous_button_link = url_for("task_orders.form_step_two_add_number", task_order_id=task_order_id) %}
{% set previous_button_link = url_for("task_orders.submit_form_step_three_add_clins", task_order_id=task_order_id, previous=True) %}
{% set step = "3" %}
{% set sticky_cta_text = 'task_orders.form.sticky_header_text' | translate %}

View File

@ -12,7 +12,7 @@
<a
href="{{ action }}"
class="usa-button usa-button-primary">
Next: Confirm
{{ "task_orders.form.step_4.next_button" | translate }}
</a>
{% endblock %}

View File

@ -458,3 +458,61 @@ def test_task_order_form_shows_errors(client, user_session, task_order):
body = response.data.decode()
assert "There were some errors" in body
assert "Not a valid decimal" in body
def test_update_and_render_next_handles_previous_valid_data(
client, user_session, task_order
):
user_session(task_order.portfolio.owner)
form_data = {"number": "0000000000000"}
original_number = task_order.number
response = client.post(
url_for(
"task_orders.submit_form_step_two_add_number",
task_order_id=task_order.id,
previous=True,
),
data=form_data,
)
assert response.status_code == 302
assert task_order.number == "0000000000000"
assert task_order.number != original_number
def test_update_and_render_next_handles_previous_invalid_data(
client, user_session, task_order
):
clin_list = [
{
"jedi_clin_type": "JEDI_CLIN_1",
"number": "12312",
"start_date": "01/01/2020",
"end_date": "01/01/2021",
"obligated_amount": "5000",
"total_amount": "10000",
},
]
TaskOrders.create_clins(task_order.id, clin_list)
assert len(task_order.clins) == 2
user_session(task_order.portfolio.owner)
form_data = {
"clins-0-jedi_clin_type": "JEDI_CLIN_1",
"clins-0-number": "12312",
"clins-0-start_date": "01/01/2020",
"clins-0-end_date": "01/01/2021",
"clins-0-obligated_amount": "5000",
"clins-0-total_amount": "10000",
"clins-1-jedi_clin_type": "JEDI_CLIN_1",
"clins-1-number": "1212",
}
response = client.post(
url_for(
"task_orders.submit_form_step_three_add_clins",
task_order_id=task_order.id,
previous=True,
),
data=form_data,
)
assert len(task_order.clins) == 2

View File

@ -524,11 +524,16 @@ task_orders:
tooltip:
obligated_funds: Funds committed to fund your portfolio. This may represent 100% of your total Task Order value, or a portion of it.
total_value: All obligated and projected funds for the Task Orders Base and Option CLINs.
expended_funds: All funds spend from the Task Order so far.
expended_funds: All funds spent from the Task Order so far.
form:
add_clin: Add Another CLIN
add_to_header: Enter the Task Order number
add_to_description: Please input your 13-digit Task Order number. This number may be listed under "Order Number" if your Contracting Officer used form 1149, or "Delivery Order/Call No." if form 1155 was used. Moving forward, this portion of funding will be referenced by the recorded Task Order number.
builder_base:
cancel_modal: Do you want to save this draft?
delete_draft: No, delete it
save_draft: Yes, save for later
to_number: "<strong>Task Order Number:</strong> {number}"
clin_title: Enter Contract Line Items
clin_description: "Refer to your task order to locate your Contract Line Item Numbers (CLINs)."
clin_details: CLIN Details
@ -551,12 +556,16 @@ task_orders:
step_1:
title: Upload your approved Task Order (TO)
description: Upload your approved Task Order here. You are required to confirm you have the appropriate signature. You will have the ability to add additional approved Task Orders with more funding to this Portfolio in the future.
next_button: "Next: Add TO Number"
step_2:
next_button: "Next: Add Base CLIN"
step_3:
next_button: "Next: Review Task Order"
percent_obligated: "% of Funds Obligated"
step_4:
documents: Documents
clins: CLIN Summary
next_button: "Next: Confirm"
step_5:
cta_text: Verify Your Information
description: Prior to submitting the Task Order, you must acknowledge, by marking the appropriate box below, that the uploaded Task Order is signed by an appropriate, duly warranted Contracting Officer who has the authority to execute the uploaded Task Order on your Agencys behalf and has authorized you to upload the Task Order in accordance with Agency policy and procedures. You must further acknowledge, by marking the appropriate box below, that all information entered herein matches that of the submitted Task Order.