diff --git a/.secrets.baseline b/.secrets.baseline
index 5e2be19d..ccfc932e 100644
--- a/.secrets.baseline
+++ b/.secrets.baseline
@@ -3,7 +3,7 @@
"files": "^.secrets.baseline$|^.*pgsslrootcert.yml$",
"lines": null
},
- "generated_at": "2020-01-09T16:55:07Z",
+ "generated_at": "2020-01-16T16:10:27Z",
"plugins_used": [
{
"base64_limit": 4.5,
diff --git a/atst/forms/application.py b/atst/forms/application.py
index de6294cd..3fda8f8f 100644
--- a/atst/forms/application.py
+++ b/atst/forms/application.py
@@ -1,14 +1,14 @@
from .forms import BaseForm, remove_empty_string
from wtforms.fields import StringField, TextAreaField, FieldList
-from wtforms.validators import Required, Optional
-from atst.forms.validators import ListItemRequired, ListItemsUnique
+from wtforms.validators import Required, Optional, Length
+from atst.forms.validators import ListItemRequired, ListItemsUnique, Name, AlphaNumeric
from atst.utils.localization import translate
class EditEnvironmentForm(BaseForm):
name = StringField(
label=translate("forms.environments.name_label"),
- validators=[Required()],
+ validators=[Required(), Name(), Length(max=100)],
filters=[remove_empty_string],
)
@@ -16,12 +16,12 @@ class EditEnvironmentForm(BaseForm):
class NameAndDescriptionForm(BaseForm):
name = StringField(
label=translate("forms.application.name_label"),
- validators=[Required()],
+ validators=[Required(), Name(), Length(max=100)],
filters=[remove_empty_string],
)
description = TextAreaField(
label=translate("forms.application.description_label"),
- validators=[Optional()],
+ validators=[Optional(), Length(max=1_000)],
filters=[remove_empty_string],
)
@@ -31,6 +31,7 @@ class EnvironmentsForm(BaseForm):
StringField(
label=translate("forms.application.environment_names_label"),
filters=[remove_empty_string],
+ validators=[AlphaNumeric(), Length(max=100)],
),
validators=[
ListItemRequired(
diff --git a/atst/forms/application_member.py b/atst/forms/application_member.py
index ec873f77..62c5ddfe 100644
--- a/atst/forms/application_member.py
+++ b/atst/forms/application_member.py
@@ -1,5 +1,6 @@
from flask_wtf import FlaskForm
from wtforms.fields import FormField, FieldList, HiddenField, BooleanField
+from wtforms.validators import UUID
from wtforms import Form
from .member import NewForm as BaseNewMemberForm
@@ -7,11 +8,13 @@ from .data import ENV_ROLES, ENV_ROLE_NO_ACCESS as NO_ACCESS
from atst.forms.fields import SelectField
from atst.domain.permission_sets import PermissionSets
from atst.utils.localization import translate
+from atst.forms.validators import AlphaNumeric
+from wtforms.validators import Length
class EnvironmentForm(Form):
- environment_id = HiddenField()
- environment_name = HiddenField()
+ environment_id = HiddenField(validators=[UUID()])
+ environment_name = HiddenField(validators=[AlphaNumeric(), Length(max=100)])
role = SelectField(
environment_name,
choices=ENV_ROLES,
diff --git a/atst/forms/ccpo_user.py b/atst/forms/ccpo_user.py
index e9e07ec2..7fafb88c 100644
--- a/atst/forms/ccpo_user.py
+++ b/atst/forms/ccpo_user.py
@@ -2,12 +2,12 @@ from flask_wtf import FlaskForm
from wtforms.validators import Required, Length
from wtforms.fields import StringField
-from atst.forms.validators import IsNumber
+from atst.forms.validators import Number
from atst.utils.localization import translate
class CCPOUserForm(FlaskForm):
dod_id = StringField(
translate("forms.new_member.dod_id_label"),
- validators=[Required(), Length(min=10, max=10), IsNumber()],
+ validators=[Required(), Length(min=10, max=10), Number()],
)
diff --git a/atst/forms/edit_user.py b/atst/forms/edit_user.py
index 835db7e3..9d2a8ffc 100644
--- a/atst/forms/edit_user.py
+++ b/atst/forms/edit_user.py
@@ -9,22 +9,26 @@ from .forms import BaseForm
from .data import SERVICE_BRANCHES
from atst.models.user import User
from atst.utils.localization import translate
+from wtforms.validators import Length
+from atst.forms.validators import Number
from .validators import Name, DateRange, PhoneNumber
USER_FIELDS = {
"first_name": StringField(
- translate("forms.edit_user.first_name_label"), validators=[Name()]
+ translate("forms.edit_user.first_name_label"),
+ validators=[Name(), Length(max=100)],
),
"last_name": StringField(
- translate("forms.edit_user.last_name_label"), validators=[Name()]
+ translate("forms.edit_user.last_name_label"),
+ validators=[Name(), Length(max=100)],
),
"email": EmailField(translate("forms.edit_user.email_label"), validators=[Email()]),
"phone_number": TelField(
translate("forms.edit_user.phone_number_label"), validators=[PhoneNumber()]
),
- "phone_ext": StringField("Extension"),
+ "phone_ext": StringField("Extension", validators=[Number(), Length(max=10)]),
"service_branch": SelectField(
translate("forms.edit_user.service_branch_label"), choices=SERVICE_BRANCHES
),
diff --git a/atst/forms/member.py b/atst/forms/member.py
index a97d5852..4bfb2269 100644
--- a/atst/forms/member.py
+++ b/atst/forms/member.py
@@ -3,16 +3,18 @@ from wtforms.fields.html5 import EmailField, TelField
from wtforms.validators import Required, Email, Length, Optional
from wtforms.fields import StringField
-from atst.forms.validators import IsNumber, PhoneNumber
+from atst.forms.validators import Number, PhoneNumber, Name
from atst.utils.localization import translate
class NewForm(FlaskForm):
first_name = StringField(
- label=translate("forms.new_member.first_name_label"), validators=[Required()]
+ label=translate("forms.new_member.first_name_label"),
+ validators=[Required(), Name(), Length(max=100)],
)
last_name = StringField(
- label=translate("forms.new_member.last_name_label"), validators=[Required()]
+ label=translate("forms.new_member.last_name_label"),
+ validators=[Required(), Name(), Length(max=100)],
)
email = EmailField(
translate("forms.new_member.email_label"), validators=[Required(), Email()]
@@ -21,8 +23,8 @@ class NewForm(FlaskForm):
translate("forms.new_member.phone_number_label"),
validators=[Optional(), PhoneNumber()],
)
- phone_ext = StringField("Extension")
+ phone_ext = StringField("Extension", validators=[Number(), Length(max=10)])
dod_id = StringField(
translate("forms.new_member.dod_id_label"),
- validators=[Required(), Length(min=10), IsNumber()],
+ validators=[Required(), Length(min=10), Number()],
)
diff --git a/atst/forms/portfolio.py b/atst/forms/portfolio.py
index 591cc080..7c4e6644 100644
--- a/atst/forms/portfolio.py
+++ b/atst/forms/portfolio.py
@@ -4,6 +4,7 @@ from wtforms.fields import (
TextAreaField,
)
from wtforms.validators import Length, InputRequired
+from atst.forms.validators import Name
from wtforms.widgets import ListWidget, CheckboxInput
from .forms import BaseForm
@@ -20,10 +21,13 @@ class PortfolioForm(BaseForm):
min=4,
max=100,
message=translate("forms.portfolio.name.length_validation_message"),
- )
+ ),
+ Name(),
],
)
- description = TextAreaField(translate("forms.portfolio.description.label"),)
+ description = TextAreaField(
+ translate("forms.portfolio.description.label"), validators=[Length(max=1_000)]
+ )
class PortfolioCreationForm(PortfolioForm):
diff --git a/atst/forms/task_order.py b/atst/forms/task_order.py
index fab3707c..6b209bf8 100644
--- a/atst/forms/task_order.py
+++ b/atst/forms/task_order.py
@@ -7,18 +7,23 @@ from wtforms.fields import (
HiddenField,
)
from wtforms.fields.html5 import DateField
-from wtforms.validators import Required, Length, NumberRange, ValidationError, Regexp
+from wtforms.validators import (
+ Required,
+ Length,
+ NumberRange,
+ ValidationError,
+)
from flask_wtf import FlaskForm
-from numbers import Number
+import numbers
+from atst.forms.validators import Number, AlphaNumeric
from .data import JEDI_CLIN_TYPES
from .fields import SelectField
from .forms import BaseForm, remove_empty_string
from atst.utils.localization import translate
-from .validators import REGEX_ALPHA_NUMERIC
from flask import current_app as app
-MAX_CLIN_AMOUNT = 1000000000
+MAX_CLIN_AMOUNT = 1_000_000_000
def coerce_enum(enum_inst):
@@ -30,8 +35,8 @@ def coerce_enum(enum_inst):
def validate_funding(form, field):
if (
- isinstance(form.total_amount.data, Number)
- and isinstance(field.data, Number)
+ isinstance(form.total_amount.data, numbers.Number)
+ and isinstance(field.data, numbers.Number)
and form.total_amount.data < field.data
):
raise ValidationError(
@@ -62,7 +67,10 @@ class CLINForm(FlaskForm):
coerce=coerce_enum,
)
- number = StringField(label=translate("task_orders.form.clin_number_label"))
+ number = StringField(
+ label=translate("task_orders.form.clin_number_label"),
+ validators=[Number(), Length(max=4)],
+ )
start_date = DateField(
translate("task_orders.form.pop_start"),
description=translate("task_orders.form.pop_example"),
@@ -120,7 +128,7 @@ class AttachmentForm(BaseForm):
Length(
max=100, message=translate("forms.attachment.filename.length_error")
),
- Regexp(regex=REGEX_ALPHA_NUMERIC),
+ AlphaNumeric(),
],
)
object_name = HiddenField(
@@ -129,7 +137,7 @@ class AttachmentForm(BaseForm):
Length(
max=40, message=translate("forms.attachment.object_name.length_error")
),
- Regexp(regex=REGEX_ALPHA_NUMERIC),
+ AlphaNumeric(),
],
)
accept = ".pdf,application/pdf"
@@ -142,6 +150,7 @@ class TaskOrderForm(BaseForm):
number = StringField(
label=translate("forms.task_order.number_description"),
filters=[remove_empty_string],
+ validators=[Number(), Length(max=13)],
)
pdf = FormField(
AttachmentForm,
diff --git a/atst/forms/validators.py b/atst/forms/validators.py
index 50cbe3cd..1bbcd645 100644
--- a/atst/forms/validators.py
+++ b/atst/forms/validators.py
@@ -2,15 +2,12 @@ from datetime import datetime
import re
from werkzeug.datastructures import FileStorage
-from wtforms.validators import ValidationError
+from wtforms.validators import ValidationError, Regexp
import pendulum
from atst.utils.localization import translate
-REGEX_ALPHA_NUMERIC = "^[A-Za-z0-9\-_ \.]*$"
-
-
def DateRange(lower_bound=None, upper_bound=None, message=None):
def _date_range(form, field):
if field.data is None:
@@ -34,7 +31,7 @@ def DateRange(lower_bound=None, upper_bound=None, message=None):
return _date_range
-def IsNumber(message=translate("forms.validators.is_number_message")):
+def Number(message=translate("forms.validators.is_number_message")):
def _is_number(form, field):
if field.data:
try:
@@ -101,3 +98,7 @@ def FileLength(max_length=50000000, message=None):
field.data.seek(0)
return _file_length
+
+
+def AlphaNumeric(message=translate("forms.validators.alpha_numeric_message")):
+ return Regexp(regex=r"^[A-Za-z0-9\-_ \.]*$", message=message)
diff --git a/tests/factories.py b/tests/factories.py
index e47aa897..d9af7c40 100644
--- a/tests/factories.py
+++ b/tests/factories.py
@@ -37,6 +37,10 @@ def random_task_order_number():
return "".join(random.choices(string.digits, k=10))
+def random_clin_number():
+ return "".join(random.choices(string.digits, k=4))
+
+
def random_past_date(year_min=1, year_max=5):
return _random_date(year_min, year_max, operator.sub)
@@ -327,7 +331,7 @@ class CLINFactory(Base):
model = CLIN
task_order = factory.SubFactory(TaskOrderFactory)
- number = factory.LazyFunction(random_task_order_number)
+ number = factory.LazyFunction(random_clin_number)
start_date = datetime.date.today()
end_date = factory.LazyFunction(random_future_date)
total_amount = factory.LazyFunction(lambda *args: random.randint(50000, 999999))
diff --git a/tests/forms/test_application_member.py b/tests/forms/test_application_member.py
index fc056223..180c6949 100644
--- a/tests/forms/test_application_member.py
+++ b/tests/forms/test_application_member.py
@@ -1,13 +1,12 @@
-from wtforms.validators import ValidationError
+import uuid
-from atst.domain.permission_sets import PermissionSets
-from atst.forms.data import ENV_ROLES, ENV_ROLE_NO_ACCESS as NO_ACCESS
+from atst.forms.data import ENV_ROLES
from atst.forms.application_member import *
def test_environment_form():
form_data = {
- "environment_id": 123,
+ "environment_id": str(uuid.uuid4()),
"environment_name": "testing",
"role": ENV_ROLES[0][0],
"disabled": True,
@@ -17,12 +16,13 @@ def test_environment_form():
def test_environment_form_default_no_access():
- form_data = {"environment_id": 123, "environment_name": "testing"}
+ env_id = str(uuid.uuid4())
+ form_data = {"environment_id": env_id, "environment_name": "testing"}
form = EnvironmentForm(data=form_data)
assert form.validate()
assert form.data == {
- "environment_id": 123,
+ "environment_id": env_id,
"environment_name": "testing",
"role": None,
"disabled": False,
@@ -31,7 +31,7 @@ def test_environment_form_default_no_access():
def test_environment_form_invalid():
form_data = {
- "environment_id": 123,
+ "environment_id": str(uuid.uuid4()),
"environment_name": "testing",
"role": "not a real choice",
}
diff --git a/tests/forms/test_validators.py b/tests/forms/test_validators.py
index 302f609e..8f290484 100644
--- a/tests/forms/test_validators.py
+++ b/tests/forms/test_validators.py
@@ -4,16 +4,16 @@ import pytest
from atst.forms.validators import *
-class TestIsNumber:
+class TestNumber:
@pytest.mark.parametrize("valid", ["0", "12", "-12"])
- def test_IsNumber_accepts_integers(self, valid, dummy_form, dummy_field):
- validator = IsNumber()
+ def test_Number_accepts_integers(self, valid, dummy_form, dummy_field):
+ validator = Number()
dummy_field.data = valid
validator(dummy_form, dummy_field)
@pytest.mark.parametrize("invalid", ["12.1", "two"])
- def test_IsNumber_rejects_anything_else(self, invalid, dummy_form, dummy_field):
- validator = IsNumber()
+ def test_Number_rejects_anything_else(self, invalid, dummy_form, dummy_field):
+ validator = Number()
dummy_field.data = invalid
with pytest.raises(ValidationError):
validator(dummy_form, dummy_field)
diff --git a/tests/routes/applications/test_settings.py b/tests/routes/applications/test_settings.py
index 523a1346..d990f6ad 100644
--- a/tests/routes/applications/test_settings.py
+++ b/tests/routes/applications/test_settings.py
@@ -401,10 +401,10 @@ def test_create_member(monkeypatch, client, user_session, session):
"user_data-last_name": user.last_name,
"user_data-dod_id": user.dod_id,
"user_data-email": user.email,
- "environment_roles-0-environment_id": env.id,
+ "environment_roles-0-environment_id": str(env.id),
"environment_roles-0-role": "ADMIN",
"environment_roles-0-environment_name": env.name,
- "environment_roles-1-environment_id": env_1.id,
+ "environment_roles-1-environment_id": str(env_1.id),
"environment_roles-1-role": NO_ACCESS,
"environment_roles-1-environment_name": env_1.name,
"perms_env_mgmt": True,
@@ -527,13 +527,13 @@ def test_update_member(client, user_session, session):
application_role_id=app_role.id,
),
data={
- "environment_roles-0-environment_id": env.id,
+ "environment_roles-0-environment_id": str(env.id),
"environment_roles-0-role": "CONTRIBUTOR",
"environment_roles-0-environment_name": env.name,
- "environment_roles-1-environment_id": env_1.id,
+ "environment_roles-1-environment_id": str(env_1.id),
"environment_roles-1-environment_name": env_1.name,
"environment_roles-1-disabled": "True",
- "environment_roles-2-environment_id": env_2.id,
+ "environment_roles-2-environment_id": str(env_2.id),
"environment_roles-2-role": "BILLING_READ",
"environment_roles-2-environment_name": env_2.name,
"perms_env_mgmt": True,
@@ -694,10 +694,10 @@ def test_handle_create_member(monkeypatch, set_g, session):
"user_data-last_name": user.last_name,
"user_data-dod_id": user.dod_id,
"user_data-email": user.email,
- "environment_roles-0-environment_id": env.id,
+ "environment_roles-0-environment_id": str(env.id),
"environment_roles-0-role": "ADMIN",
"environment_roles-0-environment_name": env.name,
- "environment_roles-1-environment_id": env_1.id,
+ "environment_roles-1-environment_id": str(env_1.id),
"environment_roles-1-role": NO_ACCESS,
"environment_roles-1-environment_name": env_1.name,
"perms_env_mgmt": True,
@@ -731,10 +731,10 @@ def test_handle_update_member_success(set_g):
form_data = ImmutableMultiDict(
{
- "environment_roles-0-environment_id": env.id,
+ "environment_roles-0-environment_id": str(env.id),
"environment_roles-0-role": "ADMIN",
"environment_roles-0-environment_name": env.name,
- "environment_roles-1-environment_id": env_1.id,
+ "environment_roles-1-environment_id": str(env_1.id),
"environment_roles-1-role": NO_ACCESS,
"environment_roles-1-environment_name": env_1.name,
"perms_env_mgmt": True,
@@ -742,6 +742,7 @@ def test_handle_update_member_success(set_g):
"perms_del_env": True,
}
)
+
handle_update_member(application.id, app_role.id, form_data)
assert len(application.roles) == 1
@@ -771,10 +772,10 @@ def test_handle_update_member_with_error(set_g, monkeypatch, mock_logger):
form_data = ImmutableMultiDict(
{
- "environment_roles-0-environment_id": env.id,
+ "environment_roles-0-environment_id": str(env.id),
"environment_roles-0-role": "ADMIN",
"environment_roles-0-environment_name": env.name,
- "environment_roles-1-environment_id": env_1.id,
+ "environment_roles-1-environment_id": str(env_1.id),
"environment_roles-1-role": NO_ACCESS,
"environment_roles-1-environment_name": env_1.name,
"perms_env_mgmt": True,
diff --git a/tests/routes/task_orders/test_new.py b/tests/routes/task_orders/test_new.py
index 446376b7..0aef88ed 100644
--- a/tests/routes/task_orders/test_new.py
+++ b/tests/routes/task_orders/test_new.py
@@ -219,13 +219,13 @@ def test_task_orders_submit_form_step_three_add_clins(client, user_session, task
user_session(task_order.portfolio.owner)
form_data = {
"clins-0-jedi_clin_type": "JEDI_CLIN_1",
- "clins-0-number": "12312",
+ "clins-0-number": "1212",
"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": "12312",
+ "clins-1-number": "1212",
"clins-1-start_date": "01/01/2020",
"clins-1-end_date": "01/01/2021",
"clins-1-obligated_amount": "5000",
@@ -269,7 +269,7 @@ def test_task_orders_submit_form_step_three_add_clins_existing_to(
user_session(task_order.portfolio.owner)
form_data = {
"clins-0-jedi_clin_type": "JEDI_CLIN_1",
- "clins-0-number": "12312",
+ "clins-0-number": "1212",
"clins-0-start_date": "01/01/2020",
"clins-0-end_date": "01/01/2021",
"clins-0-obligated_amount": "5000",
diff --git a/tests/test_access.py b/tests/test_access.py
index 19a8bec3..b0dac527 100644
--- a/tests/test_access.py
+++ b/tests/test_access.py
@@ -668,7 +668,7 @@ def test_task_orders_new_post_routes(post_url_assert_status):
"task_orders.submit_form_step_three_add_clins",
{
"clins-0-jedi_clin_type": "JEDI_CLIN_1",
- "clins-0-number": "12312",
+ "clins-0-number": "1212",
"clins-0-start_date": "01/01/2020",
"clins-0-end_date": "01/01/2021",
"clins-0-obligated_amount": "5000",
diff --git a/translations.yaml b/translations.yaml
index 360fc984..f587d8a1 100644
--- a/translations.yaml
+++ b/translations.yaml
@@ -1,17 +1,17 @@
# How to use text containing html tags in .html files:
- # In the template add the `safe` filter when referencing the string
- # from the template file. ie:
+# In the template add the `safe` filter when referencing the string
+# from the template file. ie:
- # login:
- # title: A title with a link!
+# login:
+# title: A title with a link!
- # `{{ "login.title" | translate | safe }}`
+# `{{ "login.title" | translate | safe }}`
audit_log:
events:
default:
- change: '{from} to {to}'
- changes: 'Changes:'
- details: 'Details:'
+ change: "{from} to {to}"
+ changes: "Changes:"
+ details: "Details:"
base_public:
login: Log in
title_tag: JEDI Cloud
@@ -43,7 +43,7 @@ common:
confirm: Confirm
continue: Continue
delete: Delete
- delete_confirm: 'Please type the word {word} to confirm:'
+ delete_confirm: "Please type the word {word} to confirm:"
dod_id: DoD ID
disable: Disable
email: Email
@@ -87,12 +87,12 @@ flash:
application:
created:
title: Application Saved
- message: '{application_name} has been successfully created. You may continue on to provision environments and assign team members now, or come back and complete these tasks at a later time.'
- updated: 'You have successfully updated the {application_name} application.'
+ message: "{application_name} has been successfully created. You may continue on to provision environments and assign team members now, or come back and complete these tasks at a later time."
+ updated: "You have successfully updated the {application_name} application."
name_error:
- message: 'The application name {name} has already been used in this portfolio. Please enter a unique name.'
+ message: "The application name {name} has already been used in this portfolio. Please enter a unique name."
env_name_error:
- message: 'The environment name {name} has already been used in this application. Please enter a unique name.'
+ message: "The environment name {name} has already been used in this application. Please enter a unique name."
application_invite:
error:
title: Application invitation error
@@ -117,7 +117,7 @@ flash:
message: You have successfully given {user_name} CCPO permissions.
removed:
message: You have successfully removed {user_name}'s CCPO permissions.
- delete_member_success: 'You have successfully deleted {member_name} from the portfolio.'
+ delete_member_success: "You have successfully deleted {member_name} from the portfolio."
deleted_member: Portfolio member deleted
environment_added: 'The environment "{environment_name}" has been added to the application.'
environment:
@@ -139,7 +139,7 @@ flash:
new_portfolio_member:
title: "{user_name}'s invitation has been sent"
message: "{user_name}'s access to this Portfolio is pending until they sign in for the first time."
- new_ppoc_message: 'You have successfully added {ppoc_name} as the primary point of contact. You are no longer the PPoC.'
+ new_ppoc_message: "You have successfully added {ppoc_name} as the primary point of contact. You are no longer the PPoC."
new_ppoc_title: Primary point of contact updated
portfolio_member:
revoked:
@@ -162,7 +162,7 @@ flash:
message: Your session expired due to inactivity. Please log in again to continue.
success: Success!
task_order_number_error:
- message: 'The TO number has already been entered for a JEDI task order #{to_number}. Please double-check the TO number you are entering. If you believe this is in error, please contact support@cloud.mil.'
+ message: "The TO number has already been entered for a JEDI task order #{to_number}. Please double-check the TO number you are entering. If you believe this is in error, please contact support@cloud.mil."
task_order:
insufficient_funds:
title: Insufficient Funds
@@ -172,7 +172,7 @@ flash:
new_application_member:
title: "{user_name}'s invitation has been sent"
message: "{user_name}'s access to this Application is pending until they sign in for the first time."
- updated_application_team_settings: 'You have updated the {application_name} team settings.'
+ updated_application_team_settings: "You have updated the {application_name} team settings."
user:
complete_profile:
title: You must complete your profile
@@ -180,7 +180,7 @@ flash:
updated:
title: User information updated.
footer:
- login: 'Last login:'
+ login: "Last login:"
forms:
application:
description_label: Application Description
@@ -189,7 +189,7 @@ forms:
environment_names_unique_validation_message: Environment names must be unique.
name_label: Application Name
assign_ppoc:
- dod_id: 'Select new primary point of contact:'
+ dod_id: "Select new primary point of contact:"
environments:
name_label: Environment Name
edit_user:
@@ -293,8 +293,9 @@ forms:
is_number_message: Please enter a valid number.
list_item_required_message: Please provide at least one.
list_items_unique_message: Items must be unique
- name_message: 'This field accepts letters, numbers, commas, apostrophes, hyphens, and periods.'
+ name_message: "This field accepts letters, numbers, commas, apostrophes, hyphens, and periods."
phone_number_message: Please enter a valid 5 or 10 digit phone number.
+ alpha_numeric_message: This field may only contain alphanumeric characters.
fragments:
edit_application_form:
explain: AT-AT allows you to create multiple applications within a portfolio. Each application can then be broken down into its own customizable environments.
@@ -308,7 +309,7 @@ fragments:
title: Warning!
assign_user_button_text: Assign member
confirm_alert:
- title: 'Once you assign a new PPoC, you will no longer be able to request portfolio deactivation or manage the PPoC role.'
+ title: "Once you assign a new PPoC, you will no longer be able to request portfolio deactivation or manage the PPoC role."
subtitle: The PPoC has the ability to edit all aspects of a portfolio and is the only one who can manage the PPoC role.
title: Primary point of contact (PPoC)
update_btn: Update
@@ -321,7 +322,7 @@ login:
ccpo_logo_alt_text: Cloud Computing Program Office Logo
certificate_selection:
learn_more: Learn more
- message: 'When you are prompted to select a certificate, please select Email Certificate from the provided choices.'
+ message: "When you are prompted to select a certificate, please select Email Certificate from the provided choices."
title: Certificate Selection
h1_title: Access the JEDI cloud
login_button: Sign in with CAC
@@ -340,23 +341,23 @@ portfolios:
admin:
activity_log_title: Activity log
alert_header: Are you sure you want to delete this member?
- alert_message: 'The member will be removed from the portfolio, but their log history will be retained.'
+ alert_message: "The member will be removed from the portfolio, but their log history will be retained."
alert_title: Warning! You are about to delete a member from the portfolio.
defense_component_label: Department of Defense Component
portfolio_name: Portfolio name
members:
perms_portfolio_mgmt:
- 'False': View Portfolio
- 'True': Edit Portfolio
+ "False": View Portfolio
+ "True": Edit Portfolio
perms_app_mgmt:
- 'False': View Applications
- 'True': Edit Applications
+ "False": View Applications
+ "True": Edit Applications
perms_funding:
- 'False': View Funding
- 'True': Edit Funding
+ "False": View Funding
+ "True": Edit Funding
perms_reporting:
- 'False': View Reporting
- 'True': Edit Reporting
+ "False": View Reporting
+ "True": Edit Reporting
applications:
add_environment: Add an Environment
add_member: Add Team Member
@@ -406,8 +407,8 @@ portfolios:
csp_link: Cloud Service Provider Link
enter_env_name: "Enter environment name:"
environments_heading: Application Environments
- existing_application_title: '{application_name} Application Settings'
- member_count: '{count} members'
+ existing_application_title: "{application_name} Application Settings"
+ member_count: "{count} members"
new_application_title: New Application
settings:
name_description: Application name and description
@@ -444,14 +445,14 @@ portfolios:
new:
verify: Verify Member Information
perms_team_mgmt:
- 'False': View Team
- 'True': Edit Team
+ "False": View Team
+ "True": Edit Team
perms_env_mgmt:
- 'False': View Environments
- 'True': Edit Environments
+ "False": View Environments
+ "True": Edit Environments
perms_del_env:
- 'False': ""
- 'True': Delete Application
+ "False": ""
+ "True": Delete Application
roles:
ADMIN: Admin
BILLING_READ: Billing Read-only
@@ -460,7 +461,7 @@ portfolios:
new:
title: New Portfolio
cta_step_1: Name and Describe Portfolio
- sticky_header_context: 'Step {step} of 1'
+ sticky_header_context: "Step {step} of 1"
save: Save Portfolio
members:
archive_button: Delete member
@@ -477,7 +478,7 @@ portfolios:
sub_message:
can_create_applications: This portfolio has no cloud environments set up, so there is no spending data to report. Create an application with some cloud environments to get started.
cannot_create_applications: This portfolio has no cloud environments set up, so there is no spending data to report. Contact the portfolio owner to set up some cloud environments.
- action_label: 'Add a new application'
+ action_label: "Add a new application"
total_value:
header: Total Portfolio Value
tooltip: Total portfolio value is all obligated and projected funds for all task orders in this portfolio.
@@ -492,10 +493,10 @@ task_orders:
total_amount: CLIN Value
obligated: Amount Obligated
JEDICLINType:
- JEDI_CLIN_1: 'Unclassified IaaS and PaaS (IDIQ CLIN 0001)'
- JEDI_CLIN_2: 'Classified IaaS and PaaS (IDIQ CLIN 0002)'
- JEDI_CLIN_3: 'Unclassified Cloud Support Package (IDIQ CLIN 0003)'
- JEDI_CLIN_4: 'Classified Cloud Support Package (IDIQ CLIN 0004)'
+ JEDI_CLIN_1: "Unclassified IaaS and PaaS (IDIQ CLIN 0001)"
+ JEDI_CLIN_2: "Classified IaaS and PaaS (IDIQ CLIN 0002)"
+ JEDI_CLIN_3: "Unclassified Cloud Support Package (IDIQ CLIN 0003)"
+ JEDI_CLIN_4: "Classified Cloud Support Package (IDIQ CLIN 0004)"
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 Order’s Base and Option CLINs.
@@ -510,7 +511,7 @@ task_orders:
clin_funding: CLIN Funding
clin_number_label: CLIN
clin_type_label: Corresponding IDIQ CLIN
- clin_remove_text: 'Do you want to remove '
+ clin_remove_text: "Do you want to remove "
clin_remove_confirm: Yes, remove CLIN
clin_remove_cancel: No, go back
draft_alert_title: Your information has been saved
@@ -527,18 +528,18 @@ task_orders:
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.
step_3:
- next_button: 'Next: Review Task Order'
- percent_obligated: '% of Funds Obligated'
+ next_button: "Next: Review Task Order"
+ percent_obligated: "% of Funds Obligated"
step_4:
documents: Documents
clins: CLIN Summary
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 Agency’s 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.
- next_button: 'Submit Task Order'
- sticky_header_text: 'Add a Task Order'
+ next_button: "Submit Task Order"
+ sticky_header_text: "Add a Task Order"
sticky_header_review_text: Review Changes
- sticky_header_context: 'Step {step} of 5'
+ sticky_header_context: "Step {step} of 5"
empty_state:
header: Add approved task orders
message: 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.
@@ -550,19 +551,19 @@ task_orders:
acknowledge:
title: Acknowledge Statement
text: I acknowledge, by executing the confirmation above and submitting this verification, that I am subject to potential penalties that may include fines, imprisonment, or both, under the U.S. law and regulations for any false statement or misrepresentation in association with this Task Order submission or on any accompanying documentation.
- status_empty_state: 'This Portfolio has no {status} Task Orders.'
- status_list_title: '{status} Task Orders'
+ status_empty_state: "This Portfolio has no {status} Task Orders."
+ status_list_title: "{status} Task Orders"
summary:
obligated: Total Obligated
total: Total Value
expended: Total Expended
JEDICLINType:
- JEDI_CLIN_1: 'IDIQ CLIN 0001 Unclassified IaaS/PaaS'
- JEDI_CLIN_2: 'IDIQ CLIN 0002 Classified IaaS/PaaS'
- JEDI_CLIN_3: 'IDIQ CLIN 0003 Unclassified Cloud Support Package'
- JEDI_CLIN_4: 'IDIQ CLIN 0004 Classified Cloud Support Package'
+ JEDI_CLIN_1: "IDIQ CLIN 0001 Unclassified IaaS/PaaS"
+ JEDI_CLIN_2: "IDIQ CLIN 0002 Classified IaaS/PaaS"
+ JEDI_CLIN_3: "IDIQ CLIN 0003 Unclassified Cloud Support Package"
+ JEDI_CLIN_4: "IDIQ CLIN 0004 Classified Cloud Support Package"
testing:
example_string: Hello World
- example_with_variables: 'Hello, {name}!'
+ example_with_variables: "Hello, {name}!"
nested:
example: Hello nested example