mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-08-03 16:32:15 +02:00
Merge remote-tracking branch 'origin/main' into rjm/472-email-domain-in-review
This commit is contained in:
commit
76b0a72ad4
41 changed files with 684 additions and 93 deletions
|
@ -24,9 +24,9 @@ django-fsm = "*"
|
|||
django-phonenumber-field = {extras = ["phonenumberslite"], version = "*"}
|
||||
boto3 = "*"
|
||||
typing-extensions ='*'
|
||||
django-login-required-middleware = "*"
|
||||
fred-epplib = {git = "https://github.com/cisagov/epplib.git", ref = "master"}
|
||||
|
||||
|
||||
[dev-packages]
|
||||
django-debug-toolbar = "*"
|
||||
nplusone = "*"
|
||||
|
|
35
src/Pipfile.lock
generated
35
src/Pipfile.lock
generated
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "fd7d0efa9a87dfe4b2bb228ee0e7978fba16c7cfdd3c443870900cfe899e2cfd"
|
||||
"sha256": "1242c67b31261243a35128410d4a928fca3729ddac13b8c8e25adf31445c6328"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {},
|
||||
|
@ -306,6 +306,13 @@
|
|||
"index": "pypi",
|
||||
"version": "==2.8.1"
|
||||
},
|
||||
"django-login-required-middleware": {
|
||||
"hashes": [
|
||||
"sha256:847ae9a69fd7a07618ed53192b3c06946af70a0caf6d0f4eb40a8f37593cd970"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.9.0"
|
||||
},
|
||||
"django-phonenumber-field": {
|
||||
"extras": [
|
||||
"phonenumberslite"
|
||||
|
@ -791,11 +798,11 @@
|
|||
},
|
||||
"typing-extensions": {
|
||||
"hashes": [
|
||||
"sha256:06006244c70ac8ee83fa8282cb188f697b8db25bc8b4df07be1873c43897060c",
|
||||
"sha256:3a8b36f13dd5fdc5d1b16fe317f5668545de77fa0b8e02006381fd49d731ab98"
|
||||
"sha256:88a4153d8505aabbb4e13aacb7c486c2b4a33ca3b3f807914a9b4c844c471c26",
|
||||
"sha256:d91d5919357fe7f681a9f2b5b4cb2a5f1ef0a1e9f59c4d8ff0d3491e05c0ffd5"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.6.2"
|
||||
"version": "==4.6.3"
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
|
@ -951,19 +958,19 @@
|
|||
},
|
||||
"django-stubs": {
|
||||
"hashes": [
|
||||
"sha256:93baff824f0a056e71036b423b942a74f07b909e45e3fa38185b910f597c5c08",
|
||||
"sha256:d2c671989efb3f7b0fa91e461909ad5a5a52155fe7fe6d1f2058cb88e3afb123"
|
||||
"sha256:66477bdba25407623f4079205e58f3c7265a4f0d8f7c9f540a6edc16f8883a5b",
|
||||
"sha256:8c15d5f7b05926805cfb25f2bfbf3509c37792fbd8aec5aedea358b85d8bccd5"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.2.0"
|
||||
"version": "==4.2.1"
|
||||
},
|
||||
"django-stubs-ext": {
|
||||
"hashes": [
|
||||
"sha256:55b2e3077f883e0131a7596f8ff8b19f8fc3ca325a3318ccacf5331acb2601e4",
|
||||
"sha256:7789f0caeca7152fef07ad6b94dec7310a05d0b8dab77f7979e19db0037b5127"
|
||||
"sha256:2696d6f7d8538341b060cffa9565c72ea797e866687e040b86d29cad8799e5fe",
|
||||
"sha256:4b6b63e49f4ba30d93ec46f87507648c99c9de6911e651ad69db7084fd5b2f4e"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==4.2.0"
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==4.2.1"
|
||||
},
|
||||
"django-webtest": {
|
||||
"hashes": [
|
||||
|
@ -1306,11 +1313,11 @@
|
|||
},
|
||||
"typing-extensions": {
|
||||
"hashes": [
|
||||
"sha256:06006244c70ac8ee83fa8282cb188f697b8db25bc8b4df07be1873c43897060c",
|
||||
"sha256:3a8b36f13dd5fdc5d1b16fe317f5668545de77fa0b8e02006381fd49d731ab98"
|
||||
"sha256:88a4153d8505aabbb4e13aacb7c486c2b4a33ca3b3f807914a9b4c844c471c26",
|
||||
"sha256:d91d5919357fe7f681a9f2b5b4cb2a5f1ef0a1e9f59c4d8ff0d3491e05c0ffd5"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.6.2"
|
||||
"version": "==4.6.3"
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
|
|
|
@ -104,6 +104,9 @@ class AvailableAPITest(TestCase):
|
|||
|
||||
def test_available_post(self):
|
||||
"""Cannot post to the /available/ API endpoint."""
|
||||
# have to log in to test the correct thing now that we require login
|
||||
# for all URLs by default
|
||||
self.client.force_login(self.user)
|
||||
with less_console_noise():
|
||||
response = self.client.post(API_BASE_PATH + "nonsense")
|
||||
self.assertEqual(response.status_code, 405)
|
||||
|
|
|
@ -124,7 +124,6 @@ h2 {
|
|||
}
|
||||
|
||||
/* Make "placeholder" links visually obvious */
|
||||
a[href^="https://federalist-"]::after,
|
||||
a[href$="todo"]::after {
|
||||
background-color: yellow;
|
||||
color: color(blue-80v);
|
||||
|
|
|
@ -48,6 +48,7 @@ env_db_url = env.dj_db_url("DATABASE_URL")
|
|||
env_debug = env.bool("DJANGO_DEBUG", default=False)
|
||||
env_log_level = env.str("DJANGO_LOG_LEVEL", "DEBUG")
|
||||
env_base_url = env.str("DJANGO_BASE_URL")
|
||||
env_getgov_public_site_url = env.str("GETGOV_PUBLIC_SITE_URL", "")
|
||||
|
||||
secret_login_key = b64decode(secret("DJANGO_SECRET_LOGIN_KEY", ""))
|
||||
secret_key = secret("DJANGO_SECRET_KEY")
|
||||
|
@ -62,8 +63,6 @@ secret_registry_key = b64decode(secret("REGISTRY_KEY", ""))
|
|||
secret_registry_key_passphrase = secret("REGISTRY_KEY_PASSPHRASE", "")
|
||||
secret_registry_hostname = secret("REGISTRY_HOSTNAME")
|
||||
|
||||
secret_getgov_public_site_url = secret("GETGOV_PUBLIC_SITE_URL", "")
|
||||
|
||||
# region: Basic Django Config-----------------------------------------------###
|
||||
|
||||
# Build paths inside the project like this: BASE_DIR / "subdir".
|
||||
|
@ -134,6 +133,8 @@ MIDDLEWARE = [
|
|||
"django.middleware.csrf.CsrfViewMiddleware",
|
||||
# add `user` (the currently-logged-in user) to incoming HttpRequest objects
|
||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||
# Require login for every single request by default
|
||||
"login_required.middleware.LoginRequiredMiddleware",
|
||||
# provide framework for displaying messages to the user, see documentation
|
||||
"django.contrib.messages.middleware.MessageMiddleware",
|
||||
# provide clickjacking protection via the X-Frame-Options header
|
||||
|
@ -461,6 +462,12 @@ AUTHENTICATION_BACKENDS = [
|
|||
# the login_required() decorator, LoginRequiredMixin, or AccessMixin
|
||||
LOGIN_URL = "/openid/login"
|
||||
|
||||
# We don't want the OIDC app to be login-required because then it can't handle
|
||||
# the initial login requests without erroring.
|
||||
LOGIN_REQUIRED_IGNORE_PATHS = [
|
||||
r"/openid/(.+)$",
|
||||
]
|
||||
|
||||
# where to go after logging out
|
||||
LOGOUT_REDIRECT_URL = "home"
|
||||
|
||||
|
@ -509,7 +516,7 @@ STATIC_URL = "public/"
|
|||
|
||||
# Base URL of our separate static public website. Used by the
|
||||
# {% public_site_url subdir/path %} template tag
|
||||
GETGOV_PUBLIC_SITE_URL = secret_getgov_public_site_url
|
||||
GETGOV_PUBLIC_SITE_URL = env_getgov_public_site_url
|
||||
|
||||
# endregion
|
||||
# region: Registry----------------------------------------------------------###
|
||||
|
|
|
@ -88,6 +88,11 @@ urlpatterns = [
|
|||
views.DomainYourContactInformationView.as_view(),
|
||||
name="domain-your-contact-information",
|
||||
),
|
||||
path(
|
||||
"domain/<int:pk>/org-name-address",
|
||||
views.DomainOrgNameAddressView.as_view(),
|
||||
name="domain-org-name-address",
|
||||
),
|
||||
path(
|
||||
"domain/<int:pk>/authorizing-official",
|
||||
views.DomainAuthorizingOfficialView.as_view(),
|
||||
|
|
|
@ -59,6 +59,21 @@ class UserFixture:
|
|||
"first_name": "Alysia",
|
||||
"last_name": "Broddrick",
|
||||
},
|
||||
{
|
||||
"username": "55a3bc26-cd1d-4a5c-a8c0-7e1f561ef7f4",
|
||||
"first_name": "Michelle",
|
||||
"last_name": "Rago",
|
||||
},
|
||||
{
|
||||
"username": "8f8e7293-17f7-4716-889b-1990241cbd39",
|
||||
"first_name": "Katherine",
|
||||
"last_name": "Osos",
|
||||
},
|
||||
{
|
||||
"username": "70488e0a-e937-4894-a28c-16f5949effd4",
|
||||
"first_name": "Gaby",
|
||||
"last_name": "DiSarli",
|
||||
},
|
||||
]
|
||||
|
||||
@classmethod
|
||||
|
|
|
@ -3,5 +3,6 @@ from .domain import (
|
|||
DomainAddUserForm,
|
||||
NameserverFormset,
|
||||
DomainSecurityEmailForm,
|
||||
DomainOrgNameAddressForm,
|
||||
ContactForm,
|
||||
)
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
"""Forms for domain management."""
|
||||
|
||||
from django import forms
|
||||
from django.core.validators import RegexValidator
|
||||
from django.forms import formset_factory
|
||||
|
||||
from phonenumber_field.widgets import RegionalPhoneNumberWidget
|
||||
|
||||
from ..models import Contact
|
||||
from ..models import Contact, DomainInformation
|
||||
|
||||
|
||||
class DomainAddUserForm(forms.Form):
|
||||
|
@ -64,3 +65,77 @@ class DomainSecurityEmailForm(forms.Form):
|
|||
"""Form for adding or editing a security email to a domain."""
|
||||
|
||||
security_email = forms.EmailField(label="Security email")
|
||||
|
||||
|
||||
class DomainOrgNameAddressForm(forms.ModelForm):
|
||||
|
||||
"""Form for updating the organization name and mailing address."""
|
||||
|
||||
zipcode = forms.CharField(
|
||||
label="Zip code",
|
||||
validators=[
|
||||
RegexValidator(
|
||||
"^[0-9]{5}(?:-[0-9]{4})?$|^$",
|
||||
message="Enter a zip code in the form of 12345 or 12345-6789.",
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = DomainInformation
|
||||
fields = [
|
||||
"federal_agency",
|
||||
"organization_name",
|
||||
"address_line1",
|
||||
"address_line2",
|
||||
"city",
|
||||
"state_territory",
|
||||
"zipcode",
|
||||
"urbanization",
|
||||
]
|
||||
error_messages = {
|
||||
"federal_agency": {
|
||||
"required": "Select the federal agency for your organization."
|
||||
},
|
||||
"organization_name": {"required": "Enter the name of your organization."},
|
||||
"address_line1": {
|
||||
"required": "Enter the street address of your organization."
|
||||
},
|
||||
"city": {"required": "Enter the city where your organization is located."},
|
||||
"state_territory": {
|
||||
"required": "Select the state, territory, or military post where your"
|
||||
"organization is located."
|
||||
},
|
||||
}
|
||||
widgets = {
|
||||
# We need to set the required attributed for federal_agency and
|
||||
# state/territory because for these fields we are creating an individual
|
||||
# instance of the Select. For the other fields we use the for loop to set
|
||||
# the class's required attribute to true.
|
||||
"federal_agency": forms.Select(
|
||||
attrs={"required": True}, choices=DomainInformation.AGENCY_CHOICES
|
||||
),
|
||||
"organization_name": forms.TextInput,
|
||||
"address_line1": forms.TextInput,
|
||||
"address_line2": forms.TextInput,
|
||||
"city": forms.TextInput,
|
||||
"state_territory": forms.Select(
|
||||
attrs={
|
||||
"required": True,
|
||||
},
|
||||
choices=DomainInformation.StateTerritoryChoices.choices,
|
||||
),
|
||||
"urbanization": forms.TextInput,
|
||||
}
|
||||
|
||||
# the database fields have blank=True so ModelForm doesn't create
|
||||
# required fields by default. Use this list in __init__ to mark each
|
||||
# of these fields as required
|
||||
required = ["organization_name", "address_line1", "city", "zipcode"]
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
for field_name in self.required:
|
||||
self.fields[field_name].required = True
|
||||
self.fields["state_territory"].widget.attrs.pop("maxlength", None)
|
||||
self.fields["zipcode"].widget.attrs.pop("maxlength", None)
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
# Generated by Django 4.2.1 on 2023-06-09 16:38
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("registrar", "0026_alter_domainapplication_address_line2_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="domaininformation",
|
||||
name="address_line1",
|
||||
field=models.TextField(
|
||||
blank=True,
|
||||
help_text="Street address",
|
||||
null=True,
|
||||
verbose_name="Street address",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="domaininformation",
|
||||
name="address_line2",
|
||||
field=models.TextField(
|
||||
blank=True,
|
||||
help_text="Street address line 2",
|
||||
null=True,
|
||||
verbose_name="Street address line 2",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="domaininformation",
|
||||
name="state_territory",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
help_text="State, territory, or military post",
|
||||
max_length=2,
|
||||
null=True,
|
||||
verbose_name="State, territory, or military post",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="domaininformation",
|
||||
name="urbanization",
|
||||
field=models.TextField(
|
||||
blank=True,
|
||||
help_text="Urbanization (Puerto Rico only)",
|
||||
null=True,
|
||||
verbose_name="Urbanization (Puerto Rico only)",
|
||||
),
|
||||
),
|
||||
]
|
|
@ -577,6 +577,10 @@ class DomainApplication(TimeStampedModel):
|
|||
# When an application is moved to in review, we need to send a
|
||||
# confirmation email. This is a side-effect of the state transition
|
||||
updated_domain_application._send_in_review_email()
|
||||
|
||||
@transition(field="status", source=[SUBMITTED, INVESTIGATING], target=WITHDRAWN)
|
||||
def withdraw(self):
|
||||
"""Withdraw an application that has been submitted."""
|
||||
|
||||
# ## Form policies ###
|
||||
#
|
||||
|
|
|
@ -100,11 +100,13 @@ class DomainInformation(TimeStampedModel):
|
|||
null=True,
|
||||
blank=True,
|
||||
help_text="Street address",
|
||||
verbose_name="Street address",
|
||||
)
|
||||
address_line2 = models.TextField(
|
||||
null=True,
|
||||
blank=True,
|
||||
help_text="Street address line 2",
|
||||
verbose_name="Street address line 2",
|
||||
)
|
||||
city = models.TextField(
|
||||
null=True,
|
||||
|
@ -116,6 +118,7 @@ class DomainInformation(TimeStampedModel):
|
|||
null=True,
|
||||
blank=True,
|
||||
help_text="State, territory, or military post",
|
||||
verbose_name="State, territory, or military post",
|
||||
)
|
||||
zipcode = models.CharField(
|
||||
max_length=10,
|
||||
|
@ -128,6 +131,7 @@ class DomainInformation(TimeStampedModel):
|
|||
null=True,
|
||||
blank=True,
|
||||
help_text="Urbanization (Puerto Rico only)",
|
||||
verbose_name="Urbanization (Puerto Rico only)",
|
||||
)
|
||||
|
||||
type_of_work = models.TextField(
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{% extends "base.html" %}
|
||||
{% load i18n static %}
|
||||
{% load url_helpers %}
|
||||
|
||||
{% block title %}{% translate "Unauthorized | " %}{% endblock %}
|
||||
|
||||
|
@ -25,7 +26,7 @@
|
|||
Would you like to <a href="{% url 'login' %}"> try logging in again?</a>
|
||||
</p>
|
||||
<p>
|
||||
If you would like help with this error <a href="https://federalist-877ab29f-16f6-4f12-961c-96cf064cf070.sites.pages.cloud.gov/site/cisagov/getgov-home/contact/"> contact us </a>
|
||||
If you'd like help with this error <a href="{% public_site_url 'contact/' %}"> contact us </a>.
|
||||
</p>
|
||||
|
||||
{% if log_identifier %}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{% extends "base.html" %}
|
||||
{% load i18n static %}
|
||||
{% load url_helpers %}
|
||||
|
||||
{% block title %}{% translate "Forbidden | " %}{% endblock %}
|
||||
|
||||
|
@ -22,12 +23,12 @@
|
|||
{% endif %}
|
||||
<p>
|
||||
You must be an authorized user and need to be signed in to view this page.
|
||||
Would you like to <a href="{% url 'login' %}"> try logging in again?</a>
|
||||
Would you like to <a href="{% url 'login' %}"> try logging in again</a>?
|
||||
</p>
|
||||
<p>
|
||||
If you would like help with this error <a href="https://federalist-877ab29f-16f6-4f12-961c-96cf064cf070.sites.pages.cloud.gov/site/cisagov/getgov-home/contact/"> contact us </a>
|
||||
If you'd like help with this error <a href="{% public_site_url 'contact' %}"> contact us </a>.
|
||||
</p>
|
||||
|
||||
|
||||
{% if log_identifier %}
|
||||
<p>Here's a unique identifier for this error.</p>
|
||||
<p class="text-semibold">{{ log_identifier }}</p>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{% extends "base.html" %}
|
||||
{% load i18n static %}
|
||||
{% load url_helpers %}
|
||||
|
||||
{% block title %}{% translate "Page not found | " %}{% endblock %}
|
||||
|
||||
|
@ -14,7 +15,7 @@
|
|||
{% translate "Status 404" %}
|
||||
</h2>
|
||||
|
||||
<p> Try going to the <a href="/">homepage</a>. If you can’t find what you’re looking for, <a href= "https://federalist-877ab29f-16f6-4f12-961c-96cf064cf070.sites.pages.cloud.gov/site/cisagov/getgov-home/contact/">contact us.</a>
|
||||
<p> Try going to the <a href="/">homepage</a>. If you can’t find what you’re looking for, <a href="{% public_site_url 'contact' %}"> contact us </a>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{% extends "base.html" %}
|
||||
{% load i18n static %}
|
||||
{% load url_helpers %}
|
||||
|
||||
{% block title %}{% translate "Server error | " %}{% endblock %}
|
||||
|
||||
|
@ -18,7 +19,7 @@
|
|||
{% else %}
|
||||
<p>
|
||||
Sorry! Try waiting a few minutes and then reloading the page.
|
||||
<a href="https://federalist-877ab29f-16f6-4f12-961c-96cf064cf070.sites.pages.cloud.gov/site/cisagov/getgov-home/contact/"> Contact us </a> if you need help.
|
||||
<a href="{% public_site_url 'contact' %}"> contact us </a> if you need help.
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
|
|
|
@ -1,22 +1,19 @@
|
|||
{% extends 'application_form.html' %}
|
||||
{% load field_helpers %}
|
||||
{% load field_helpers url_helpers %}
|
||||
|
||||
{% block form_instructions %}
|
||||
<h2 class="margin-bottom-05">
|
||||
Who is the authorizing official for your organization?
|
||||
</h2>
|
||||
|
||||
<p>Your authorizing official is the person within your organization who can authorize
|
||||
your domain request. This is generally the highest-ranking or highest-elected official
|
||||
in your organization. Read more about <a href="{% url 'todo' %}">who can serve as an
|
||||
authorizing official</a>.</p>
|
||||
<p>Your authorizing official is the person within your organization who can authorize your domain request. This is generally the highest-ranking or highest-elected official in your organization.</p>
|
||||
|
||||
<div class="ao_example">
|
||||
{% include "includes/ao_example.html" %}
|
||||
</div>
|
||||
|
||||
<p>We’ll contact your authorizing official to let them know that you made this request
|
||||
and to double check that they approve it.</p>
|
||||
<p>We might contact your authorizing official, or their office, to double check that they approve this request. Read more about <a href="{% public_site_url 'domains/eligibility/#you-must-have-approval-from-an-authorizing-official-within-your-organization' %}">who can serve as an authorizing official</a>.</p>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{% extends 'application_form.html' %}
|
||||
{% load static field_helpers %}
|
||||
{% load static field_helpers url_helpers %}
|
||||
|
||||
{% block form_instructions %}
|
||||
<p>Before requesting a .gov domain, <a href="{% url 'todo' %}">please make sure it
|
||||
meets our naming requirements.</a> Your domain name must:
|
||||
<p>Before requesting a .gov domain, <a href="{% public_site_url 'domains/choosing' %}">please make sure it
|
||||
meets our naming requirements</a>. Your domain name must:
|
||||
<ul class="usa-list">
|
||||
<li>Be available </li>
|
||||
<li>Be unique </li>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% extends "domain_base.html" %}
|
||||
{% load static field_helpers%}
|
||||
{% load static field_helpers url_helpers %}
|
||||
|
||||
{% block title %}Domain authorizing official | {{ domain.name }} | {% endblock %}
|
||||
|
||||
|
@ -11,9 +11,7 @@
|
|||
|
||||
<p>Your authorizing official is the person within your organization who can
|
||||
authorize domain requests. This is generally the highest-ranking or
|
||||
highest-elected official in your organization. <a class="usa-link"
|
||||
href="https://federalist-877ab29f-16f6-4f12-961c-96cf064cf070.sites.pages.cloud.gov/site/cisagov/getgov-home/domains/eligibility/#you-must-have-approval-from-an-authorizing-official-within-your-organization">Read more about who can serve
|
||||
as an authorizing official.</a></p>
|
||||
highest-elected official in your organization. Read more about <a class="usa-link" href="{% public_site_url 'domains/eligibility/#you-must-have-approval-from-an-authorizing-official-within-your-organization' %}">who can serve as an authorizing official</a>.</p>
|
||||
|
||||
{% include "includes/required_fields.html" %}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<a class="usa-button margin-bottom-1" href="{{url}}"> Add DNS name servers </a>
|
||||
{% endif %}
|
||||
|
||||
{% url 'todo' as url %}
|
||||
{% url 'domain-org-name-address' pk=domain.id as url %}
|
||||
{% include "includes/summary_item.html" with title='Organization name and mailing address' value=domain.domain_info address='true' edit_link=url %}
|
||||
|
||||
{% url 'domain-authorizing-official' pk=domain.id as url %}
|
||||
|
|
47
src/registrar/templates/domain_org_name_address.html
Normal file
47
src/registrar/templates/domain_org_name_address.html
Normal file
|
@ -0,0 +1,47 @@
|
|||
{% extends "domain_base.html" %}
|
||||
{% load static field_helpers%}
|
||||
|
||||
{% block title %}Organization name and mailing address | {{ domain.name }} | {% endblock %}
|
||||
|
||||
{% block domain_content %}
|
||||
{# this is right after the messages block in the parent template #}
|
||||
{% include "includes/form_errors.html" with form=form %}
|
||||
|
||||
<h1>Organization name and mailing address </h1>
|
||||
|
||||
<p>The name of your organization will be publicly listed as the domain registrant.</p>
|
||||
|
||||
{% include "includes/required_fields.html" %}
|
||||
|
||||
<form class="usa-form usa-form--large" method="post" novalidate id="form-container">
|
||||
{% csrf_token %}
|
||||
|
||||
{% if domain.domain_info.organization_type == 'federal' %}
|
||||
{% input_with_errors form.federal_agency %}
|
||||
{% endif %}
|
||||
|
||||
{% input_with_errors form.organization_name %}
|
||||
|
||||
{% input_with_errors form.address_line1 %}
|
||||
|
||||
{% input_with_errors form.address_line2 %}
|
||||
|
||||
{% input_with_errors form.city %}
|
||||
|
||||
{% input_with_errors form.state_territory %}
|
||||
|
||||
{% with add_class="usa-input--small" %}
|
||||
{% input_with_errors form.zipcode %}
|
||||
{% endwith %}
|
||||
|
||||
{% input_with_errors form.urbanization %}
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
class="usa-button"
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
</form>
|
||||
|
||||
{% endblock %} {# domain_content #}
|
|
@ -1,5 +1,5 @@
|
|||
{% extends "domain_base.html" %}
|
||||
{% load static field_helpers %}
|
||||
{% load static field_helpers url_helpers %}
|
||||
|
||||
{% block title %}Domain security email | {{ domain.name }} | {% endblock %}
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
|||
|
||||
<h1>Domain security email</h1>
|
||||
|
||||
<p>We strongly recommend that you provide a security email. This email will allow the public to report observed or suspected security issues on your domain. Security emails are made public and included in the <a href="https://federalist-877ab29f-16f6-4f12-961c-96cf064cf070.sites.pages.cloud.gov/site/cisagov/getgov-home/about/data/">.gov domain data</a> we provide.</p>
|
||||
<p>We strongly recommend that you provide a security email. This email will allow the public to report observed or suspected security issues on your domain. Security emails are made public and included in the <a href="{% public_site_url 'about/data/' %}">.gov domain data</a> we provide.</p>
|
||||
|
||||
<p>A security contact should be capable of evaluating or triaging security reports for your entire domain. Use a team email address, not an individual’s email. We recommend using an alias, like security@domain.gov.</p>
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
</li>
|
||||
|
||||
<li class="usa-sidenav__item">
|
||||
{% url 'todo' as url %}
|
||||
{% url 'domain-org-name-address' pk=domain.id as url %}
|
||||
<a href="{{ url }}"
|
||||
{% if request.path == url %}class="usa-current"{% endif %}
|
||||
>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{% load static %}
|
||||
{% load url_helpers %}
|
||||
|
||||
<footer class="usa-footer">
|
||||
<div class="usa-footer__secondary-section">
|
||||
|
@ -26,11 +27,11 @@
|
|||
<address class="usa-footer__address">
|
||||
<div class="usa-footer__contact-info grid-row grid-gap-md">
|
||||
<div class="grid-col-auto">
|
||||
<a href="https://federalist-877ab29f-16f6-4f12-961c-96cf064cf070.sites.pages.cloud.gov/site/cisagov/getgov-home/help/"> Help </a>
|
||||
<a href="{% public_site_url 'help/' %}" class="usa-link"> Help </a>
|
||||
</div>
|
||||
<span class=""> | </span>
|
||||
<div class="grid-col-auto">
|
||||
<a href="https://federalist-877ab29f-16f6-4f12-961c-96cf064cf070.sites.pages.cloud.gov/site/cisagov/getgov-home/contact/" class="usa-link">Contact us</a>
|
||||
<a href="{% public_site_url 'contact/' %}" class="usa-link">Contact us</a>
|
||||
</div>
|
||||
</div>
|
||||
</address>
|
||||
|
@ -73,11 +74,8 @@
|
|||
<div class="usa-identifier__container">
|
||||
<ul class="usa-identifier__required-links-list">
|
||||
<li class="usa-identifier__required-links-item">
|
||||
<a
|
||||
href="https://federalist-877ab29f-16f6-4f12-961c-96cf064cf070.sites.pages.cloud.gov/site/cisagov/getgov-home/about/"
|
||||
class="usa-identifier__required-link usa-link"
|
||||
>About .gov</a
|
||||
>
|
||||
<a href="{% public_site_url 'about/' %}"
|
||||
class="usa-identifier__required-link usa-link">About .gov</a>
|
||||
</li>
|
||||
<li class="usa-identifier__required-links-item">
|
||||
<a
|
||||
|
@ -87,9 +85,7 @@
|
|||
>
|
||||
</li>
|
||||
<li class="usa-identifier__required-links-item">
|
||||
<a href="https://federalist-877ab29f-16f6-4f12-961c-96cf064cf070.sites.pages.cloud.gov/site/cisagov/getgov-home/privacy-policy/" class="usa-identifier__required-link usa-link"
|
||||
>Privacy policy</a
|
||||
>
|
||||
<a href="{% public_site_url 'privacy-policy/' %}" class="usa-identifier__required-link usa-link">Privacy policy</a>
|
||||
</li>
|
||||
<li class="usa-identifier__required-links-item">
|
||||
<a href="https://www.dhs.gov/accessibility" class="usa-identifier__required-link usa-link usa-link--external"
|
||||
|
@ -97,9 +93,8 @@
|
|||
>
|
||||
</li>
|
||||
<li class="usa-identifier__required-links-item">
|
||||
<a href="https://federalist-877ab29f-16f6-4f12-961c-96cf064cf070.sites.pages.cloud.gov/site/cisagov/getgov-home/vulnerability-disclosure-policy/" class="usa-identifier__required-link usa-link"
|
||||
>Vulnerability disclosure policy</a
|
||||
>
|
||||
<a href="{% public_site_url 'vulnerability-disclosure-policy/' %}" class="usa-identifier__required-link usa-link"
|
||||
>Vulnerability disclosure policy</a>
|
||||
</li>
|
||||
<li class="usa-identifier__required-links-item">
|
||||
<a href="https://www.cisa.gov/cisa-no-fear-act-reporting" class="usa-identifier__required-link usa-link"
|
||||
|
|
159
src/registrar/tests/test_url_auth.py
Normal file
159
src/registrar/tests/test_url_auth.py
Normal file
|
@ -0,0 +1,159 @@
|
|||
"""Test that almost all URLs require authentication.
|
||||
|
||||
This uses deep Django URLConf pattern magic and was shamelessly lifted from
|
||||
https://github.com/18F/tock/blob/main/tock/tock/tests/test_url_auth.py
|
||||
"""
|
||||
|
||||
from django.test import TestCase
|
||||
from django.urls import reverse, URLPattern
|
||||
from django.urls.resolvers import URLResolver
|
||||
|
||||
import registrar.config.urls
|
||||
|
||||
from .common import less_console_noise
|
||||
|
||||
# When a URLconf pattern contains named capture groups, we'll use this
|
||||
# dictionary to retrieve a sample value for it, which will be included
|
||||
# in the sample URLs we generate, when attempting to perform a GET
|
||||
# request on the view.
|
||||
SAMPLE_KWARGS = {
|
||||
"app_label": "registrar",
|
||||
"pk": "1",
|
||||
"id": "1",
|
||||
"content_type_id": "2",
|
||||
"object_id": "3",
|
||||
"domain": "whitehouse.gov",
|
||||
}
|
||||
|
||||
# Our test suite will ignore some namespaces.
|
||||
IGNORE_NAMESPACES = [
|
||||
# The Django Debug Toolbar (DJDT) ends up in the URL config but it's always
|
||||
# disabled in production, so don't worry about it.
|
||||
"djdt"
|
||||
]
|
||||
|
||||
# In general, we don't want to have any unnamed views, because that makes it
|
||||
# impossible to generate sample URLs that point at them. We'll make exceptions
|
||||
# for some namespaces that we don't have control over, though.
|
||||
NAMESPACES_WITH_UNNAMED_VIEWS = ["admin", None]
|
||||
|
||||
|
||||
def iter_patterns(urlconf, patterns=None, namespace=None):
|
||||
"""
|
||||
Iterate through all patterns in the given Django URLconf. Yields
|
||||
`(viewname, route)` tuples, where `viewname` is the fully-qualified view name
|
||||
(including its namespace, if any), and `route` is a regular expression that
|
||||
corresponds to the part of the pattern that contains any capturing groups.
|
||||
"""
|
||||
if patterns is None:
|
||||
patterns = urlconf.urlpatterns
|
||||
for pattern in patterns:
|
||||
# Resolve if it's a route or an include
|
||||
if isinstance(pattern, URLPattern):
|
||||
viewname = pattern.name
|
||||
if viewname is None and namespace not in NAMESPACES_WITH_UNNAMED_VIEWS:
|
||||
raise AssertionError(
|
||||
f"namespace {namespace} cannot contain unnamed views"
|
||||
)
|
||||
if namespace and viewname is not None:
|
||||
viewname = f"{namespace}:{viewname}"
|
||||
yield (viewname, pattern.pattern)
|
||||
elif isinstance(pattern, URLResolver):
|
||||
if len(pattern.default_kwargs.keys()) > 0:
|
||||
raise AssertionError("resolvers are not expected to have kwargs")
|
||||
if pattern.namespace and namespace is not None:
|
||||
raise AssertionError("nested namespaces are not currently supported")
|
||||
if pattern.namespace in IGNORE_NAMESPACES:
|
||||
continue
|
||||
yield from iter_patterns(
|
||||
urlconf, pattern.url_patterns, namespace or pattern.namespace
|
||||
)
|
||||
else:
|
||||
raise AssertionError("unknown pattern class")
|
||||
|
||||
|
||||
def iter_sample_urls(urlconf):
|
||||
"""
|
||||
Yields sample URLs for all entries in the given Django URLconf.
|
||||
This gets pretty deep into the muck of RoutePattern
|
||||
https://docs.djangoproject.com/en/2.1/_modules/django/urls/resolvers/
|
||||
"""
|
||||
|
||||
for viewname, route in iter_patterns(urlconf):
|
||||
if not viewname:
|
||||
continue
|
||||
if viewname == "auth_user_password_change":
|
||||
print(route)
|
||||
break
|
||||
named_groups = route.regex.groupindex.keys()
|
||||
kwargs = {}
|
||||
args = ()
|
||||
|
||||
for kwarg in named_groups:
|
||||
if kwarg not in SAMPLE_KWARGS:
|
||||
raise AssertionError(
|
||||
f'Sample value for {kwarg} in pattern "{route}" not found'
|
||||
)
|
||||
kwargs[kwarg] = SAMPLE_KWARGS[kwarg]
|
||||
|
||||
url = reverse(viewname, args=args, kwargs=kwargs)
|
||||
yield (viewname, url)
|
||||
|
||||
|
||||
class TestURLAuth(TestCase):
|
||||
"""
|
||||
Tests to ensure that most URLs in a Django URLconf are protected by
|
||||
authentication.
|
||||
"""
|
||||
|
||||
# We won't test that the following URLs are protected by auth.
|
||||
# Note that the trailing slash is wobbly depending on how the URL was defined.
|
||||
IGNORE_URLS = [
|
||||
# These are the OIDC auth endpoints that always need
|
||||
# to be public.
|
||||
"/openid/login/",
|
||||
"/openid/logout/",
|
||||
"/openid/callback",
|
||||
"/openid/callback/login/",
|
||||
"/openid/callback/logout/",
|
||||
]
|
||||
|
||||
def assertURLIsProtectedByAuth(self, url):
|
||||
"""
|
||||
Make a GET request to the given URL, and ensure that it either redirects
|
||||
to login or denies access outright.
|
||||
"""
|
||||
|
||||
try:
|
||||
with less_console_noise():
|
||||
response = self.client.get(url)
|
||||
except Exception as e:
|
||||
# It'll be helpful to provide information on what URL was being
|
||||
# accessed at the time the exception occurred. Python 3 will
|
||||
# also include a full traceback of the original exception, so
|
||||
# we don't need to worry about hiding the original cause.
|
||||
raise AssertionError(f'Accessing {url} raised "{e}"', e)
|
||||
|
||||
code = response.status_code
|
||||
if code == 302:
|
||||
redirect = response["location"]
|
||||
self.assertRegex(
|
||||
redirect,
|
||||
r"^\/openid\/login",
|
||||
f"GET {url} should redirect to login or deny access, but instead "
|
||||
f"it redirects to {redirect}",
|
||||
)
|
||||
elif code == 401 or code == 403:
|
||||
pass
|
||||
else:
|
||||
raise AssertionError(
|
||||
f"GET {url} returned HTTP {code}, but should redirect to login or "
|
||||
"deny access",
|
||||
)
|
||||
|
||||
def test_login_required_all_urls(self):
|
||||
"""All URLs redirect to the login view."""
|
||||
for viewname, url in iter_sample_urls(registrar.config.urls):
|
||||
if url not in self.IGNORE_URLS:
|
||||
with self.subTest(viewname=viewname):
|
||||
self.assertURLIsProtectedByAuth(url)
|
|
@ -36,10 +36,9 @@ class TestViews(TestCase):
|
|||
self.assertContains(response, "OK", status_code=200)
|
||||
|
||||
def test_home_page(self):
|
||||
"""Home page should be available without a login."""
|
||||
"""Home page should NOT be available without a login."""
|
||||
response = self.client.get("/")
|
||||
self.assertContains(response, "registrar", status_code=200)
|
||||
self.assertContains(response, "Sign in")
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
||||
def test_whoami_page_no_user(self):
|
||||
"""Whoami page not accessible without a logged-in user."""
|
||||
|
@ -1059,6 +1058,7 @@ class TestDomainPermissions(TestWithDomainPermissions):
|
|||
"domain-users",
|
||||
"domain-users-add",
|
||||
"domain-nameservers",
|
||||
"domain-org-name-address",
|
||||
"domain-authorizing-official",
|
||||
"domain-your-contact-information",
|
||||
"domain-security-email",
|
||||
|
@ -1079,6 +1079,7 @@ class TestDomainPermissions(TestWithDomainPermissions):
|
|||
"domain-users",
|
||||
"domain-users-add",
|
||||
"domain-nameservers",
|
||||
"domain-org-name-address",
|
||||
"domain-authorizing-official",
|
||||
"domain-your-contact-information",
|
||||
"domain-security-email",
|
||||
|
@ -1316,6 +1317,42 @@ class TestDomainDetail(TestWithDomainPermissions, WebTest):
|
|||
)
|
||||
self.assertContains(page, "Testy")
|
||||
|
||||
def test_domain_org_name_address(self):
|
||||
"""Can load domain's org name and mailing address page."""
|
||||
page = self.client.get(
|
||||
reverse("domain-org-name-address", kwargs={"pk": self.domain.id})
|
||||
)
|
||||
# once on the sidebar, once in the page title, once as H1
|
||||
self.assertContains(page, "Organization name and mailing address", count=3)
|
||||
|
||||
def test_domain_org_name_address_content(self):
|
||||
"""Org name and address information appears on the page."""
|
||||
self.domain_information.organization_name = "Town of Igorville"
|
||||
self.domain_information.save()
|
||||
page = self.app.get(
|
||||
reverse("domain-org-name-address", kwargs={"pk": self.domain.id})
|
||||
)
|
||||
self.assertContains(page, "Town of Igorville")
|
||||
|
||||
def test_domain_org_name_address_form(self):
|
||||
"""Submitting changes works on the org name address page."""
|
||||
self.domain_information.organization_name = "Town of Igorville"
|
||||
self.domain_information.save()
|
||||
org_name_page = self.app.get(
|
||||
reverse("domain-org-name-address", kwargs={"pk": self.domain.id})
|
||||
)
|
||||
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
|
||||
|
||||
org_name_page.form["organization_name"] = "Not igorville"
|
||||
org_name_page.form["city"] = "Faketown"
|
||||
|
||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||
success_result_page = org_name_page.form.submit()
|
||||
self.assertEqual(success_result_page.status_code, 200)
|
||||
|
||||
self.assertContains(success_result_page, "Not igorville")
|
||||
self.assertContains(success_result_page, "Faketown")
|
||||
|
||||
def test_domain_your_contact_information(self):
|
||||
"""Can load domain's your contact information page."""
|
||||
page = self.client.get(
|
||||
|
|
|
@ -2,6 +2,7 @@ from .application import *
|
|||
from .domain import (
|
||||
DomainView,
|
||||
DomainAuthorizingOfficialView,
|
||||
DomainOrgNameAddressView,
|
||||
DomainNameserversView,
|
||||
DomainYourContactInformationView,
|
||||
DomainSecurityEmailView,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import logging
|
||||
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.http import Http404, HttpResponse, HttpResponseRedirect
|
||||
from django.shortcuts import redirect, render
|
||||
from django.urls import resolve, reverse
|
||||
|
@ -44,7 +43,7 @@ class Step(StrEnum):
|
|||
REVIEW = "review"
|
||||
|
||||
|
||||
class ApplicationWizard(LoginRequiredMixin, TemplateView):
|
||||
class ApplicationWizard(TemplateView):
|
||||
"""
|
||||
A common set of methods and configuration.
|
||||
|
||||
|
@ -502,6 +501,6 @@ class ApplicationWithdrawn(DomainApplicationPermissionView):
|
|||
to withdraw and send back to homepage.
|
||||
"""
|
||||
application = DomainApplication.objects.get(id=self.kwargs["pk"])
|
||||
application.status = "withdrawn"
|
||||
application.withdraw()
|
||||
application.save()
|
||||
return HttpResponseRedirect(reverse("home"))
|
||||
|
|
|
@ -22,10 +22,11 @@ from registrar.models import (
|
|||
)
|
||||
|
||||
from ..forms import (
|
||||
DomainAddUserForm,
|
||||
NameserverFormset,
|
||||
DomainSecurityEmailForm,
|
||||
ContactForm,
|
||||
DomainOrgNameAddressForm,
|
||||
DomainAddUserForm,
|
||||
DomainSecurityEmailForm,
|
||||
NameserverFormset,
|
||||
)
|
||||
from ..utility.email import send_templated_email, EmailSendingError
|
||||
from .utility import DomainPermissionView, DomainInvitationPermissionDeleteView
|
||||
|
@ -41,6 +42,47 @@ class DomainView(DomainPermissionView):
|
|||
template_name = "domain_detail.html"
|
||||
|
||||
|
||||
class DomainOrgNameAddressView(DomainPermissionView, FormMixin):
|
||||
"""Organization name and mailing address view"""
|
||||
|
||||
model = Domain
|
||||
template_name = "domain_org_name_address.html"
|
||||
context_object_name = "domain"
|
||||
form_class = DomainOrgNameAddressForm
|
||||
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
"""Add domain_info.organization_name instance to make a bound form."""
|
||||
form_kwargs = super().get_form_kwargs(*args, **kwargs)
|
||||
form_kwargs["instance"] = self.get_object().domain_info
|
||||
return form_kwargs
|
||||
|
||||
def get_success_url(self):
|
||||
"""Redirect to the overview page for the domain."""
|
||||
return reverse("domain-org-name-address", kwargs={"pk": self.object.pk})
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
"""Form submission posts to this view.
|
||||
|
||||
This post method harmonizes using DetailView and FormMixin together.
|
||||
"""
|
||||
self.object = self.get_object()
|
||||
form = self.get_form()
|
||||
if form.is_valid():
|
||||
return self.form_valid(form)
|
||||
else:
|
||||
return self.form_invalid(form)
|
||||
|
||||
def form_valid(self, form):
|
||||
"""The form is valid, save the organization name and mailing address."""
|
||||
form.save()
|
||||
|
||||
messages.success(
|
||||
self.request, "The organization name and mailing address has been updated."
|
||||
)
|
||||
# superclass has the redirect
|
||||
return super().form_valid(form)
|
||||
|
||||
|
||||
class DomainAuthorizingOfficialView(DomainPermissionView, FormMixin):
|
||||
|
||||
"""Domain authorizing official editing view."""
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
from django.http import HttpResponse
|
||||
|
||||
from login_required import login_not_required
|
||||
|
||||
|
||||
# the health check endpoint needs to be globally available so that the
|
||||
# PaaS orchestrator can make sure the app has come up properly
|
||||
@login_not_required
|
||||
def health(request):
|
||||
return HttpResponse(
|
||||
'<html lang="en"><head><title>OK - Get.gov</title></head><body>OK</body>'
|
||||
|
|
|
@ -17,6 +17,7 @@ django-auditlog==2.3.0
|
|||
django-cache-url==3.4.4
|
||||
django-csp==3.7
|
||||
django-fsm==2.8.1
|
||||
django-login-required-middleware==0.9.0
|
||||
django-phonenumber-field[phonenumberslite]==7.1.0
|
||||
django-widget-tweaks==1.4.12
|
||||
environs[django]==9.5.0
|
||||
|
@ -47,6 +48,6 @@ s3transfer==0.6.1 ; python_version >= '3.7'
|
|||
setuptools==67.8.0 ; python_version >= '3.7'
|
||||
six==1.16.0 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
|
||||
sqlparse==0.4.4 ; python_version >= '3.5'
|
||||
typing-extensions==4.6.2
|
||||
typing-extensions==4.6.3
|
||||
urllib3==1.26.16 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'
|
||||
whitenoise==6.4.0
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
10027 OUTOFSCOPE http://app:8080/public/debug_toolbar/js/toolbar.js
|
||||
# USWDS.min.js contains suspicious words "query", "select", "from" in ordinary usage
|
||||
10027 OUTOFSCOPE http://app:8080/public/js/uswds.min.js
|
||||
# UNCLEAR WHY THIS ONE IS FAILING. Giving 404 error.
|
||||
10027 OUTOFSCOPE http://app:8080/public/js/uswds-init.min.js
|
||||
# get-gov.js contains suspicious word "from" as in `Array.from()`
|
||||
10027 OUTOFSCOPE http://app:8080/public/js/get-gov.js
|
||||
10028 FAIL (Open Redirect - Passive/beta)
|
||||
|
@ -53,6 +55,7 @@
|
|||
10038 OUTOFSCOPE http://app:8080/users/add
|
||||
10038 OUTOFSCOPE http://app:8080/nameservers
|
||||
10038 OUTOFSCOPE http://app:8080/your-contact-information
|
||||
10038 OUTOFSCOPE http://app:8080/authorizing-official
|
||||
10038 OUTOFSCOPE http://app:8080/security-email
|
||||
10038 OUTOFSCOPE http://app:8080/delete
|
||||
10038 OUTOFSCOPE http://app:8080/withdraw
|
||||
|
@ -61,6 +64,7 @@
|
|||
10038 OUTOFSCOPE http://app:8080/todo
|
||||
# OIDC isn't configured in the test environment and DEBUG=True so this gives a 500 without CSP headers
|
||||
10038 OUTOFSCOPE http://app:8080/openid/login/
|
||||
10038 OUTOFSCOPE http://app:8080/openid/logout/
|
||||
10039 FAIL (X-Backend-Server Header Information Leak - Passive/beta)
|
||||
10040 FAIL (Secure Pages Include Mixed Content - Passive/release)
|
||||
10041 FAIL (HTTP to HTTPS Insecure Transition in Form Post - Passive/beta)
|
||||
|
@ -83,6 +87,10 @@
|
|||
10062 FAIL (PII Disclosure - Passive/beta)
|
||||
10095 FAIL (Backup File Disclosure - Active/beta)
|
||||
10096 FAIL (Timestamp Disclosure - Passive/release)
|
||||
# Our sortable table of domains uses timestamps as sort keys so this appears as
|
||||
# a false-positive to the OWASP scanner
|
||||
10096 OUTOFSCOPE http://app:8080
|
||||
10096 OUTOFSCOPE http://app:8080/
|
||||
10097 FAIL (Hash Disclosure - Passive/beta)
|
||||
10098 FAIL (Cross-Domain Misconfiguration - Passive/release)
|
||||
10104 FAIL (User Agent Fuzzer - Active/beta)
|
||||
|
@ -147,6 +155,7 @@
|
|||
# OIDC isn't configured in the test environment and DEBUG=True so these error pages
|
||||
# trigger this rule in a way that they won't in production
|
||||
90022 OUTOFSCOPE http://app:8080/openid/login/
|
||||
90022 OUTOFSCOPE http://app:8080/openid/logout/
|
||||
90023 FAIL (XML External Entity Attack - Active/beta)
|
||||
90024 FAIL (Generic Padding Oracle - Active/beta)
|
||||
90025 FAIL (Expression Language Injection - Active/beta)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue