diff --git a/docs/developer/README.md b/docs/developer/README.md index a06202d8d..f894955e5 100644 --- a/docs/developer/README.md +++ b/docs/developer/README.md @@ -250,7 +250,7 @@ type docker-compose run owasp ``` -# Images, stylesheets, and JavaScript +## Images, stylesheets, and JavaScript We use the U.S. Web Design System (USWDS) for styling our applications. @@ -262,7 +262,7 @@ Assets are stored in `registrar/assets` during development and served from `regi We utilize the [uswds-compile tool](https://designsystem.digital.gov/documentation/getting-started/developers/phase-two-compile/) from USWDS to compile and package USWDS assets. -## Making and viewing style changes +### Making and viewing style changes When you run `docker-compose up` the `node` service in the container will begin to watch for changes in the `registrar/assets` folder, and will recompile once any changes are made. @@ -273,7 +273,11 @@ Within the `registrar/assets` folder, the `_theme` folder contains three files i You can also compile the **Sass** at any time using `npx gulp compile`. Similarly, you can copy over **other static assets** (images and javascript files), using `npx gulp copyAssets`. -## Upgrading USWDS and other JavaScript packages +### CSS class naming conventions + +We use the [CSS Block Element Modifier (BEM)](https://getbem.com/naming/) naming convention for our custom classes. This is in line with how USWDS [approaches](https://designsystem.digital.gov/whats-new/updates/2019/04/08/introducing-uswds-2-0/) their CSS class architecture and helps keep our code cohesive and readable. + +### Upgrading USWDS and other JavaScript packages Version numbers can be manually controlled in `package.json`. Edit that, if desired. diff --git a/src/djangooidc/exceptions.py b/src/djangooidc/exceptions.py index 226337f54..000c47649 100644 --- a/src/djangooidc/exceptions.py +++ b/src/djangooidc/exceptions.py @@ -33,8 +33,8 @@ class AuthenticationFailed(OIDCException): friendly_message = "This login attempt didn't work." -class NoStateDefined(OIDCException): - friendly_message = "The session state is None." +class StateMismatch(AuthenticationFailed): + friendly_message = "State mismatch. This login attempt didn't work." class InternalError(OIDCException): diff --git a/src/djangooidc/oidc.py b/src/djangooidc/oidc.py index bff766bb4..95ed322f5 100644 --- a/src/djangooidc/oidc.py +++ b/src/djangooidc/oidc.py @@ -182,10 +182,20 @@ class Client(oic.Client): if authn_response["state"] != session.get("state", None): # this most likely means the user's Django session vanished - logger.error("Received state not the same as expected for %s" % state) if session.get("state", None) is None: - raise o_e.NoStateDefined() - raise o_e.AuthenticationFailed(locator=state) + logger.error( + f"The OP state {state} does not match the session state. " + f"The session state is None. " + f"authn_response['state'] = {authn_response['state']} " + f"session.get('state', None) = {session.get('state', None)}" + ) + else: + logger.error( + f"The OP state {state} does not match the session state. " + f"authn_response['state'] = {authn_response['state']} " + f"session.get('state', None) = {session.get('state', None)}" + ) + raise o_e.StateMismatch() if self.behaviour.get("response_type") == "code": # need an access token to get user info (and to log the user out later) diff --git a/src/djangooidc/tests/test_views.py b/src/djangooidc/tests/test_views.py index 0f734b80d..f10afcbaf 100644 --- a/src/djangooidc/tests/test_views.py +++ b/src/djangooidc/tests/test_views.py @@ -4,7 +4,7 @@ from django.http import HttpResponse from django.test import Client, TestCase, RequestFactory from django.urls import reverse -from djangooidc.exceptions import NoStateDefined, InternalError +from djangooidc.exceptions import StateMismatch, InternalError from ..views import login_callback from .common import less_console_noise @@ -129,21 +129,35 @@ class ViewsTest(TestCase): self.assertContains(response, "Hi") def test_login_callback_with_no_session_state(self, mock_client): - """If the local session is None (ie the server restarted while user was logged out), + """If the local session does not match the OP session, we do not throw an exception. Rather, we attempt to login again.""" with less_console_noise(): - # MOCK - # mock the acr_value to some string - # mock the callback function to raise the NoStateDefined Exception + # MOCK get_default_acr_value and the callback to raise StateMismatch + # error when called mock_client.get_default_acr_value.side_effect = self.create_acr - mock_client.callback.side_effect = NoStateDefined() - # TEST - # test the login callback + mock_client.callback.side_effect = StateMismatch() + # TEST receiving a response from login.gov response = self.client.get(reverse("openid_login_callback")) - # ASSERTIONS - # assert that the user is redirected to the start of the login process + # ASSERT self.assertEqual(response.status_code, 302) self.assertEqual(response.url, "/") + # Check that the redirect_attempted flag is set in the session + self.assertTrue(self.client.session.get("redirect_attempted", False)) + + def test_login_callback_with_no_session_state_attempt_again_only_once(self, mock_client): + """We only attempt to relogin once. After that, it's the error page for you.""" + with less_console_noise(): + # MOCK get_default_acr_value, redirect_attempted to True and the callback + # to raise StateMismatch error when called + mock_client.get_default_acr_value.side_effect = self.create_acr + mock_client.callback.side_effect = StateMismatch() + session = self.client.session + session["redirect_attempted"] = True + session.save() + # TEST receiving a response from login.gov + response = self.client.get(reverse("openid_login_callback")) + # ASSERT + self.assertEqual(response.status_code, 401) def test_login_callback_reads_next(self, mock_client): """If the next value is set in the session, test that login_callback returns diff --git a/src/djangooidc/views.py b/src/djangooidc/views.py index 8e112769b..ab81ccff1 100644 --- a/src/djangooidc/views.py +++ b/src/djangooidc/views.py @@ -101,16 +101,25 @@ def login_callback(request): if user: login(request, user) logger.info("Successfully logged in user %s" % user) - # Double login bug (1507)? + # Clear the flag if the exception is not caught + request.session.pop("redirect_attempted", None) return redirect(request.session.get("next", "/")) else: raise o_e.BannedUser() - except o_e.NoStateDefined as nsd_err: - # In the event that a user is in the middle of a login when the app is restarted, - # their session state will no longer be available, so redirect the user to the - # beginning of login process without raising an error to the user. - logger.warning(f"No State Defined: {nsd_err}") - return redirect(request.session.get("next", "/")) + except o_e.StateMismatch as nsd_err: + # Check if the redirect has already been attempted + if not request.session.get("redirect_attempted", False): + # Set the flag to indicate that the redirect has been attempted + request.session["redirect_attempted"] = True + + # In the event of a state mismatch between OP and session, redirect the user to the + # beginning of login process without raising an error to the user. Attempt once. + logger.warning(f"No State Defined: {nsd_err}") + return redirect(request.session.get("next", "/")) + else: + # Clear the flag if the exception is not caught + request.session.pop("redirect_attempted", None) + return error_page(request, nsd_err) except Exception as err: return error_page(request, err) diff --git a/src/registrar/admin.py b/src/registrar/admin.py index e1b9bd5a9..0d533defc 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -830,7 +830,7 @@ class DomainInformationAdmin(ListHeaderAdmin): # Columns list_display = [ "domain", - "organization_type", + "generic_org_type", "created_at", "submitter", ] @@ -841,7 +841,7 @@ class DomainInformationAdmin(ListHeaderAdmin): ] # Filters - list_filter = ["organization_type"] + list_filter = ["generic_org_type"] # Search search_fields = [ @@ -858,7 +858,7 @@ class DomainInformationAdmin(ListHeaderAdmin): "Type of organization", { "fields": [ - "organization_type", + "generic_org_type", "is_election_board", "federal_type", "federal_agency", @@ -1003,7 +1003,7 @@ class DomainRequestAdmin(ListHeaderAdmin): list_display = [ "requested_domain", "status", - "organization_type", + "generic_org_type", "federal_type", "federal_agency", "organization_name", @@ -1030,7 +1030,7 @@ class DomainRequestAdmin(ListHeaderAdmin): # Filters list_filter = ( "status", - "organization_type", + "generic_org_type", "federal_type", ElectionOfficeFilter, "rejection_reason", @@ -1068,7 +1068,7 @@ class DomainRequestAdmin(ListHeaderAdmin): "Type of organization", { "fields": [ - "organization_type", + "generic_org_type", "is_election_board", "federal_type", "federal_agency", @@ -1401,7 +1401,7 @@ class DomainAdmin(ListHeaderAdmin): # Columns list_display = [ "name", - "organization_type", + "generic_org_type", "federal_type", "federal_agency", "organization_name", @@ -1426,10 +1426,10 @@ class DomainAdmin(ListHeaderAdmin): # in autocomplete_fields for domain ordering = ["name"] - def organization_type(self, obj): - return obj.domain_info.get_organization_type_display() + def generic_org_type(self, obj): + return obj.domain_info.get_generic_org_type_display() - organization_type.admin_order_field = "domain_info__organization_type" # type: ignore + generic_org_type.admin_order_field = "domain_info__generic_org_type" # type: ignore def federal_agency(self, obj): return obj.domain_info.federal_agency if obj.domain_info else None @@ -1466,7 +1466,7 @@ class DomainAdmin(ListHeaderAdmin): state_territory.admin_order_field = "domain_info__state_territory" # type: ignore # Filters - list_filter = ["domain_info__organization_type", "domain_info__federal_type", ElectionOfficeFilter, "state"] + list_filter = ["domain_info__generic_org_type", "domain_info__federal_type", ElectionOfficeFilter, "state"] search_fields = ["name"] search_help_text = "Search by domain name." diff --git a/src/registrar/fixtures_domain_requests.py b/src/registrar/fixtures_domain_requests.py index a37e29d6b..02efae5a9 100644 --- a/src/registrar/fixtures_domain_requests.py +++ b/src/registrar/fixtures_domain_requests.py @@ -30,7 +30,7 @@ class DomainRequestFixture: # { # "status": "started", # "organization_name": "Example - Just started", - # "organization_type": "federal", + # "generic_org_type": "federal", # "federal_agency": None, # "federal_type": None, # "address_line1": None, @@ -98,7 +98,7 @@ class DomainRequestFixture: def _set_non_foreign_key_fields(cls, da: DomainRequest, app: dict): """Helper method used by `load`.""" da.status = app["status"] if "status" in app else "started" - da.organization_type = app["organization_type"] if "organization_type" in app else "federal" + da.generic_org_type = app["generic_org_type"] if "generic_org_type" in app else "federal" da.federal_agency = ( app["federal_agency"] if "federal_agency" in app diff --git a/src/registrar/forms/domain.py b/src/registrar/forms/domain.py index 22d76c768..0bfd9b667 100644 --- a/src/registrar/forms/domain.py +++ b/src/registrar/forms/domain.py @@ -262,8 +262,8 @@ class AuthorizingOfficialContactForm(ContactForm): return super().save() # Determine if the domain is federal or tribal - is_federal = self.domainInfo.organization_type == DomainRequest.OrganizationChoices.FEDERAL - is_tribal = self.domainInfo.organization_type == DomainRequest.OrganizationChoices.TRIBAL + is_federal = self.domainInfo.generic_org_type == DomainRequest.OrganizationChoices.FEDERAL + is_tribal = self.domainInfo.generic_org_type == DomainRequest.OrganizationChoices.TRIBAL # Get the Contact object from the db for the Authorizing Official db_ao = Contact.objects.get(id=self.instance.id) @@ -363,8 +363,8 @@ class DomainOrgNameAddressForm(forms.ModelForm): self.fields["state_territory"].widget.attrs.pop("maxlength", None) self.fields["zipcode"].widget.attrs.pop("maxlength", None) - self.is_federal = self.instance.organization_type == DomainRequest.OrganizationChoices.FEDERAL - self.is_tribal = self.instance.organization_type == DomainRequest.OrganizationChoices.TRIBAL + self.is_federal = self.instance.generic_org_type == DomainRequest.OrganizationChoices.FEDERAL + self.is_tribal = self.instance.generic_org_type == DomainRequest.OrganizationChoices.TRIBAL field_to_disable = None if self.is_federal: @@ -384,9 +384,9 @@ class DomainOrgNameAddressForm(forms.ModelForm): # If they get past this point, we forbid it this way. # This could be malicious, so lets reserve information for the backend only. if self.is_federal and not self._field_unchanged("federal_agency"): - raise ValueError("federal_agency cannot be modified when the organization_type is federal") + raise ValueError("federal_agency cannot be modified when the generic_org_type is federal") elif self.is_tribal and not self._field_unchanged("organization_name"): - raise ValueError("organization_name cannot be modified when the organization_type is tribal") + raise ValueError("organization_name cannot be modified when the generic_org_type is tribal") else: super().save() diff --git a/src/registrar/forms/domain_request_wizard.py b/src/registrar/forms/domain_request_wizard.py index ef47143ea..1efc028f6 100644 --- a/src/registrar/forms/domain_request_wizard.py +++ b/src/registrar/forms/domain_request_wizard.py @@ -169,7 +169,7 @@ class RegistrarFormSet(forms.BaseFormSet): class OrganizationTypeForm(RegistrarForm): - organization_type = forms.ChoiceField( + generic_org_type = forms.ChoiceField( # use the long names in the domain request form choices=DomainRequest.OrganizationChoicesVerbose.choices, widget=forms.RadioSelect, diff --git a/src/registrar/management/commands/transfer_transition_domains_to_domains.py b/src/registrar/management/commands/transfer_transition_domains_to_domains.py index 7f09d8de7..4ea74e335 100644 --- a/src/registrar/management/commands/transfer_transition_domains_to_domains.py +++ b/src/registrar/management/commands/transfer_transition_domains_to_domains.py @@ -332,7 +332,7 @@ class Command(BaseCommand): updated = False fields_to_update = [ - "organization_type", + "generic_org_type", "federal_type", "federal_agency", "organization_name", @@ -400,7 +400,7 @@ class Command(BaseCommand): if debug_on: logger.info(f"Contact created: {contact}") - org_type_current = transition_domain.organization_type + org_type_current = transition_domain.generic_org_type match org_type_current: case "Federal": org_type = ("federal", "Federal") @@ -431,7 +431,7 @@ class Command(BaseCommand): } if valid_org_type: - new_domain_info_data["organization_type"] = org_type[0] + new_domain_info_data["generic_org_type"] = org_type[0] elif debug_on: logger.debug(f"No org type found on {domain.name}") diff --git a/src/registrar/management/commands/utility/extra_transition_domain_helper.py b/src/registrar/management/commands/utility/extra_transition_domain_helper.py index 5c3573fb1..eb41c4be8 100644 --- a/src/registrar/management/commands/utility/extra_transition_domain_helper.py +++ b/src/registrar/management/commands/utility/extra_transition_domain_helper.py @@ -200,7 +200,7 @@ class LoadExtraTransitionDomain: updated_fields = [ "organization_name", - "organization_type", + "generic_org_type", "federal_type", "federal_agency", "first_name", @@ -412,7 +412,7 @@ class LoadExtraTransitionDomain: return transition_domain def parse_domain_type_data(self, domain_name, transition_domain: TransitionDomain) -> TransitionDomain: - """Grabs organization_type and federal_type from the parsed files + """Grabs generic_org_type and federal_type from the parsed files and associates it with a transition_domain object, then returns that object.""" if not isinstance(transition_domain, TransitionDomain): raise ValueError("Not a valid object, must be TransitionDomain") @@ -439,7 +439,7 @@ class LoadExtraTransitionDomain: raise ValueError("Found invalid data on DOMAIN_ADHOC") # Then, just grab the organization type. - new_organization_type = domain_type[0].strip() + new_generic_org_type = domain_type[0].strip() # Check if this domain_type is active or not. # If not, we don't want to add this. @@ -455,8 +455,8 @@ class LoadExtraTransitionDomain: # Are we updating data that already exists, # or are we adding new data in its place? - organization_type_exists = ( - transition_domain.organization_type is not None and transition_domain.organization_type.strip() != "" + generic_org_type_exists = ( + transition_domain.generic_org_type is not None and transition_domain.generic_org_type.strip() != "" ) federal_type_exists = ( transition_domain.federal_type is not None and transition_domain.federal_type.strip() != "" @@ -467,20 +467,20 @@ class LoadExtraTransitionDomain: is_federal = domain_type_length == 2 if is_federal: new_federal_type = domain_type[1].strip() - transition_domain.organization_type = new_organization_type + transition_domain.generic_org_type = new_generic_org_type transition_domain.federal_type = new_federal_type else: - transition_domain.organization_type = new_organization_type + transition_domain.generic_org_type = new_generic_org_type transition_domain.federal_type = None # Logs if we either added to this property, # or modified it. self._add_or_change_message( EnumFilenames.DOMAIN_ADHOC, - "organization_type", - transition_domain.organization_type, + "generic_org_type", + transition_domain.generic_org_type, domain_name, - organization_type_exists, + generic_org_type_exists, ) self._add_or_change_message( diff --git a/src/registrar/migrations/0077_alter_publiccontact_fax_alter_publiccontact_org_and_more.py b/src/registrar/migrations/0077_alter_publiccontact_fax_alter_publiccontact_org_and_more.py new file mode 100644 index 000000000..66c904391 --- /dev/null +++ b/src/registrar/migrations/0077_alter_publiccontact_fax_alter_publiccontact_org_and_more.py @@ -0,0 +1,35 @@ +# Generated by Django 4.2.10 on 2024-03-15 18:47 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("registrar", "0076_alter_domainrequest_current_websites_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="publiccontact", + name="fax", + field=models.CharField( + blank=True, help_text="Contact's fax number (null ok). Must be in ITU.E164.2005 format.", null=True + ), + ), + migrations.AlterField( + model_name="publiccontact", + name="org", + field=models.CharField(blank=True, help_text="Contact's organization (null ok)", null=True), + ), + migrations.AlterField( + model_name="publiccontact", + name="street2", + field=models.CharField(blank=True, help_text="Contact's street (null ok)", null=True), + ), + migrations.AlterField( + model_name="publiccontact", + name="street3", + field=models.CharField(blank=True, help_text="Contact's street (null ok)", null=True), + ), + ] diff --git a/src/registrar/migrations/0078_rename_organization_type_domaininformation_generic_org_type_and_more.py b/src/registrar/migrations/0078_rename_organization_type_domaininformation_generic_org_type_and_more.py new file mode 100644 index 000000000..fb9d65cce --- /dev/null +++ b/src/registrar/migrations/0078_rename_organization_type_domaininformation_generic_org_type_and_more.py @@ -0,0 +1,28 @@ +# Generated by Django 4.2.10 on 2024-03-20 21:14 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("registrar", "0077_alter_publiccontact_fax_alter_publiccontact_org_and_more"), + ] + + operations = [ + migrations.RenameField( + model_name="domaininformation", + old_name="organization_type", + new_name="generic_org_type", + ), + migrations.RenameField( + model_name="domainrequest", + old_name="organization_type", + new_name="generic_org_type", + ), + migrations.RenameField( + model_name="transitiondomain", + old_name="organization_type", + new_name="generic_org_type", + ), + ] diff --git a/src/registrar/models/domain_information.py b/src/registrar/models/domain_information.py index f8f4db9c6..b5755a3c9 100644 --- a/src/registrar/models/domain_information.py +++ b/src/registrar/models/domain_information.py @@ -49,7 +49,7 @@ class DomainInformation(TimeStampedModel): ) # ##### data fields from the initial form ##### - organization_type = models.CharField( + generic_org_type = models.CharField( max_length=255, choices=OrganizationChoices.choices, null=True, diff --git a/src/registrar/models/domain_request.py b/src/registrar/models/domain_request.py index e7378a880..7527529a1 100644 --- a/src/registrar/models/domain_request.py +++ b/src/registrar/models/domain_request.py @@ -397,7 +397,7 @@ class DomainRequest(TimeStampedModel): ) # ##### data fields from the initial form ##### - organization_type = models.CharField( + generic_org_type = models.CharField( max_length=255, # use the short names in Django admin choices=OrganizationChoices.choices, @@ -886,12 +886,12 @@ class DomainRequest(TimeStampedModel): def show_organization_federal(self) -> bool: """Show this step if the answer to the first question was "federal".""" - user_choice = self.organization_type + user_choice = self.generic_org_type return user_choice == DomainRequest.OrganizationChoices.FEDERAL def show_tribal_government(self) -> bool: """Show this step if the answer to the first question was "tribal".""" - user_choice = self.organization_type + user_choice = self.generic_org_type return user_choice == DomainRequest.OrganizationChoices.TRIBAL def show_organization_election(self) -> bool: @@ -900,7 +900,7 @@ class DomainRequest(TimeStampedModel): This shows for answers that aren't "Federal" or "Interstate". This also doesnt show if user selected "School District" as well (#524) """ - user_choice = self.organization_type + user_choice = self.generic_org_type excluded = [ DomainRequest.OrganizationChoices.FEDERAL, DomainRequest.OrganizationChoices.INTERSTATE, @@ -910,7 +910,7 @@ class DomainRequest(TimeStampedModel): def show_about_your_organization(self) -> bool: """Show this step if this is a special district or interstate.""" - user_choice = self.organization_type + user_choice = self.generic_org_type return user_choice in [ DomainRequest.OrganizationChoices.SPECIAL_DISTRICT, DomainRequest.OrganizationChoices.INTERSTATE, @@ -927,12 +927,12 @@ class DomainRequest(TimeStampedModel): def is_federal(self) -> Union[bool, None]: """Is this domain request for a federal agency? - organization_type can be both null and blank, + generic_org_type can be both null and blank, """ - if not self.organization_type: - # organization_type is either blank or None, can't answer + if not self.generic_org_type: + # generic_org_type is either blank or None, can't answer return None - if self.organization_type == DomainRequest.OrganizationChoices.FEDERAL: + if self.generic_org_type == DomainRequest.OrganizationChoices.FEDERAL: return True return False diff --git a/src/registrar/models/public_contact.py b/src/registrar/models/public_contact.py index cdd0d6a42..f9dea3f02 100644 --- a/src/registrar/models/public_contact.py +++ b/src/registrar/models/public_contact.py @@ -60,10 +60,10 @@ class PublicContact(TimeStampedModel): ) name = models.CharField(null=False, help_text="Contact's full name") - org = models.CharField(null=True, help_text="Contact's organization (null ok)") + org = models.CharField(null=True, blank=True, help_text="Contact's organization (null ok)") street1 = models.CharField(null=False, help_text="Contact's street") - street2 = models.CharField(null=True, help_text="Contact's street (null ok)") - street3 = models.CharField(null=True, help_text="Contact's street (null ok)") + street2 = models.CharField(null=True, blank=True, help_text="Contact's street (null ok)") + street3 = models.CharField(null=True, blank=True, help_text="Contact's street (null ok)") city = models.CharField(null=False, help_text="Contact's city") sp = models.CharField(null=False, help_text="Contact's state or province") pc = models.CharField(null=False, help_text="Contact's postal code") @@ -72,6 +72,7 @@ class PublicContact(TimeStampedModel): voice = models.CharField(null=False, help_text="Contact's phone number. Must be in ITU.E164.2005 format") fax = models.CharField( null=True, + blank=True, help_text="Contact's fax number (null ok). Must be in ITU.E164.2005 format.", ) pw = models.CharField(null=False, help_text="Contact's authorization code. 16 characters minimum.") diff --git a/src/registrar/models/transition_domain.py b/src/registrar/models/transition_domain.py index 0c9c2ae66..eafbeda00 100644 --- a/src/registrar/models/transition_domain.py +++ b/src/registrar/models/transition_domain.py @@ -49,7 +49,7 @@ class TransitionDomain(TimeStampedModel): verbose_name="Processed", help_text="Indicates whether this TransitionDomain was already processed", ) - organization_type = models.CharField( + generic_org_type = models.CharField( max_length=255, null=True, blank=True, @@ -147,7 +147,7 @@ class TransitionDomain(TimeStampedModel): f"username: {self.username}, \n" f"status: {self.status}, \n" f"email sent: {self.email_sent}, \n" - f"organization type: {self.organization_type}, \n" + f"organization type: {self.generic_org_type}, \n" f"organization_name: {self.organization_name}, \n" f"federal_type: {self.federal_type}, \n" f"federal_agency: {self.federal_agency}, \n" diff --git a/src/registrar/templates/domain_authorizing_official.html b/src/registrar/templates/domain_authorizing_official.html index 2e2faa0d3..aa9808c2e 100644 --- a/src/registrar/templates/domain_authorizing_official.html +++ b/src/registrar/templates/domain_authorizing_official.html @@ -12,7 +12,7 @@

Your authorizing official is a person within your organization who can authorize domain requests. This person must be in a role of significant, executive responsibility within the organization. Read more about who can serve as an authorizing official.

- {% if organization_type == "federal" or organization_type == "tribal" %} + {% if generic_org_type == "federal" or generic_org_type == "tribal" %}

The authorizing official for your organization can’t be updated here. To suggest an update, email help@get.gov. @@ -25,7 +25,7 @@

{% csrf_token %} - {% if organization_type == "federal" or organization_type == "tribal" %} + {% if generic_org_type == "federal" or generic_org_type == "tribal" %} {# If all fields are disabled, add SR content #}
{{ form.first_name.value }}
{{ form.last_name.value }}
@@ -41,7 +41,7 @@ {% input_with_errors form.email %} - {% if organization_type != "federal" and organization_type != "tribal" %} + {% if generic_org_type != "federal" and generic_org_type != "tribal" %} {% endif %}
diff --git a/src/registrar/templates/domain_org_name_address.html b/src/registrar/templates/domain_org_name_address.html index 180fdd2a6..1e6176aa0 100644 --- a/src/registrar/templates/domain_org_name_address.html +++ b/src/registrar/templates/domain_org_name_address.html @@ -11,12 +11,12 @@

The name of your organization will be publicly listed as the domain registrant.

- {% if domain.domain_info.organization_type == "federal" %} + {% if domain.domain_info.generic_org_type == "federal" %}

The federal agency for your organization can’t be updated here. To suggest an update, email help@get.gov.

- {% elif domain.domain_info.organization_type == "tribal" %} + {% elif domain.domain_info.generic_org_type == "tribal" %}

Your organization name can’t be updated here. To suggest an update, email help@get.gov. @@ -28,7 +28,7 @@

{% csrf_token %} - {% if domain.domain_info.organization_type == 'federal' %} + {% if domain.domain_info.generic_org_type == 'federal' %} {% input_with_errors form.federal_agency %} {% endif %} diff --git a/src/registrar/templates/domain_request_org_type.html b/src/registrar/templates/domain_request_org_type.html index eab61e0bc..0e01a5260 100644 --- a/src/registrar/templates/domain_request_org_type.html +++ b/src/registrar/templates/domain_request_org_type.html @@ -14,6 +14,6 @@ {% block form_fields %} {% with add_class="usa-radio__input--tile" add_legend_class="usa-sr-only" %} - {% input_with_errors forms.0.organization_type %} + {% input_with_errors forms.0.generic_org_type %} {% endwith %} {% endblock %} diff --git a/src/registrar/templates/domain_request_review.html b/src/registrar/templates/domain_request_review.html index 71aec8d0a..227fc0cea 100644 --- a/src/registrar/templates/domain_request_review.html +++ b/src/registrar/templates/domain_request_review.html @@ -24,8 +24,8 @@ {% if step == Step.ORGANIZATION_TYPE %} {% namespaced_url 'domain-request' step as domain_request_url %} - {% if domain_request.organization_type is not None %} - {% with title=form_titles|get_item:step value=domain_request.get_organization_type_display|default:"Incomplete" %} + {% if domain_request.generic_org_type is not None %} + {% with title=form_titles|get_item:step value=domain_request.get_generic_org_type_display|default:"Incomplete" %} {% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=domain_request_url %} {% endwith %} {% else %} diff --git a/src/registrar/templates/domain_request_status.html b/src/registrar/templates/domain_request_status.html index 55260db97..e6ca4cdb3 100644 --- a/src/registrar/templates/domain_request_status.html +++ b/src/registrar/templates/domain_request_status.html @@ -52,7 +52,7 @@

Summary of your domain request

{% with heading_level='h3' %} - {% with org_type=DomainRequest.get_organization_type_display %} + {% with org_type=DomainRequest.get_generic_org_type_display %} {% include "includes/summary_item.html" with title='Type of organization' value=org_type heading_level=heading_level %} {% endwith %} diff --git a/src/registrar/templates/emails/includes/domain_request_summary.txt b/src/registrar/templates/emails/includes/domain_request_summary.txt index 6c7b36523..10ec9ac2c 100644 --- a/src/registrar/templates/emails/includes/domain_request_summary.txt +++ b/src/registrar/templates/emails/includes/domain_request_summary.txt @@ -1,7 +1,7 @@ SUMMARY OF YOUR DOMAIN REQUEST Type of organization: -{{ domain_request.get_organization_type_display }} +{{ domain_request.get_generic_org_type_display }} {% if domain_request.show_organization_federal %} Federal government branch: {{ domain_request.get_federal_type_display }} diff --git a/src/registrar/templates/includes/ao_example.html b/src/registrar/templates/includes/ao_example.html index 85df174aa..cddf0def7 100644 --- a/src/registrar/templates/includes/ao_example.html +++ b/src/registrar/templates/includes/ao_example.html @@ -24,28 +24,28 @@ {% endif %} -{% elif organization_type == 'city' %} +{% elif generic_org_type == 'city' %}

Cities

Domain requests from cities must be authorized by someone in a role of significant, executive responsibility within the city (mayor, council president, city manager, township/village supervisor, select board chairperson, chief, senior technology officer, or equivalent).

-{% elif organization_type == 'county' %} +{% elif generic_org_type == 'county' %}

Counties

Domain requests from counties must be authorized by the commission chair or someone in a role of significant, executive responsibility within the county (county judge, county mayor, parish/borough president, senior technology officer, or equivalent). Other county-level offices (county clerk, sheriff, county auditor, comptroller) may qualify, as well, in some instances.

-{% elif organization_type == 'interstate' %} +{% elif generic_org_type == 'interstate' %}

Interstate organizations

Domain requests from interstate organizations must be authorized by someone in a role of significant, executive responsibility within the organization (president, director, chair, senior technology officer, or equivalent) or one of the state’s governors or CIOs.

-{% elif organization_type == 'school_district' %} +{% elif generic_org_type == 'school_district' %}

School districts

Domain requests from school district governments must be authorized by someone in a role of significant, executive responsibility within the district (board chair, superintendent, senior technology officer, or equivalent).

-{% elif organization_type == 'special_district' %} +{% elif generic_org_type == 'special_district' %}

Special districts

Domain requests from special districts must be authorized by someone in a role of significant, executive responsibility within the district (CEO, chair, executive director, senior technology officer, or equivalent).

-{% elif organization_type == 'state_or_territory' %} +{% elif generic_org_type == 'state_or_territory' %}

U.S. states and territories

States and territories: executive branch

@@ -54,7 +54,7 @@

States and territories: judicial and legislative branches

Domain requests from state legislatures and courts must be authorized by an agency’s CIO or someone in a role of significant, executive responsibility within the agency.

-{% elif organization_type == 'tribal' %} +{% elif generic_org_type == 'tribal' %}

Tribal governments

Domain requests from federally-recognized tribal governments must be authorized by the tribal leader the Bureau of Indian Affairs recognizes.

Domain requests from state-recognized tribal governments must be authorized by the tribal leader the individual state recognizes.

diff --git a/src/registrar/templates/includes/domain_example.html b/src/registrar/templates/includes/domain_example.html index 74ab18b3b..05df00e7b 100644 --- a/src/registrar/templates/includes/domain_example.html +++ b/src/registrar/templates/includes/domain_example.html @@ -26,7 +26,7 @@ {% endif %} -{% elif organization_type == 'interstate' %} +{% elif generic_org_type == 'interstate' %} -{% elif organization_type == 'state_or_territory' %} +{% elif generic_org_type == 'state_or_territory' %}

State .gov domains must include the two-letter state abbreviation or clearly spell out the state name.

Examples:

-{% elif organization_type == 'tribal' %} +{% elif generic_org_type == 'tribal' %}

Tribal domains may include the suffix -nsn, for native sovereign nation.

Examples:

-{% elif organization_type == 'county' %} +{% elif generic_org_type == 'county' %}

Most county .gov domains must include the two-letter state abbreviation or the full state name. County names that aren’t shared by any other city, county, parish, town, borough, village or equivalent in the U.S. (at the time a domain is granted) don’t have to refer to their state in their domain name. Counties can include “county” in their domain to distinguish it from other places with similar names.

We use the Census Bureau’s National Places Gazetteer Files to determine if county names are unique.

@@ -65,7 +65,7 @@
  • MiamiDade.gov
  • -{% elif organization_type == 'city' %} +{% elif generic_org_type == 'city' %}

    Most city domains must include the two-letter state abbreviation or clearly spell out the state name. Using phrases like “City of” or “Town of” is optional.

    Cities that meet one of the criteria below don’t have to refer to their state in their domain name.

    -{% elif organization_type == 'special_district' %} +{% elif generic_org_type == 'special_district' %}

    Domain names must represent your organization or institutional name, not solely the services you provide. It also needs to include your two-letter state abbreviation or clearly spell out the state name.

    Examples:

    -{% elif organization_type == 'school_district' %} +{% elif generic_org_type == 'school_district' %}

    Domain names must represent your organization or institutional name.

    Examples: