Merge pull request #1928 from cisagov/rh/1896-federal-agency

ISSUE #1896: Add Federal Agency Table
This commit is contained in:
Erin Song 2024-03-26 11:32:36 -07:00 committed by GitHub
commit e2974a8b8c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 319 additions and 2 deletions

View file

@ -1814,6 +1814,13 @@ class VerifiedByStaffAdmin(ListHeaderAdmin):
super().save_model(request, obj, form, change) super().save_model(request, obj, form, change)
class FederalAgencyAdmin(ListHeaderAdmin):
list_display = ["agency"]
search_fields = ["agency"]
search_help_text = "Search by agency name."
ordering = ["agency"]
admin.site.unregister(LogEntry) # Unregister the default registration admin.site.unregister(LogEntry) # Unregister the default registration
admin.site.register(LogEntry, CustomLogEntryAdmin) admin.site.register(LogEntry, CustomLogEntryAdmin)
admin.site.register(models.User, MyUserAdmin) admin.site.register(models.User, MyUserAdmin)
@ -1827,6 +1834,7 @@ admin.site.register(models.DomainInvitation, DomainInvitationAdmin)
admin.site.register(models.DomainInformation, DomainInformationAdmin) admin.site.register(models.DomainInformation, DomainInformationAdmin)
admin.site.register(models.Domain, DomainAdmin) admin.site.register(models.Domain, DomainAdmin)
admin.site.register(models.DraftDomain, DraftDomainAdmin) admin.site.register(models.DraftDomain, DraftDomainAdmin)
admin.site.register(models.FederalAgency, FederalAgencyAdmin)
# Host and HostIP removed from django admin because changes in admin # Host and HostIP removed from django admin because changes in admin
# do not propagate to registry and logic not applied # do not propagate to registry and logic not applied
admin.site.register(models.Host, MyHostAdmin) admin.site.register(models.Host, MyHostAdmin)

View file

@ -0,0 +1,38 @@
# Generated by Django 4.2.10 on 2024-03-22 22:18
from django.db import migrations, models
from registrar.models import FederalAgency
from typing import Any
# For linting: RunPython expects a function reference.
def create_federal_agencies(apps, schema_editor) -> Any:
FederalAgency.create_federal_agencies(apps, schema_editor)
class Migration(migrations.Migration):
dependencies = [
("registrar", "0078_rename_organization_type_domaininformation_generic_org_type_and_more"),
]
operations = [
migrations.CreateModel(
name="FederalAgency",
fields=[
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
("agency", models.CharField(blank=True, help_text="Federal agency", null=True)),
],
options={
"verbose_name": "Federal agency",
"verbose_name_plural": "Federal agencies",
},
),
migrations.RunPython(
create_federal_agencies,
reverse_code=migrations.RunPython.noop,
atomic=True,
),
]

View file

@ -0,0 +1,37 @@
# This migration creates the create_full_access_group and create_cisa_analyst_group groups
# It is dependent on 0079 (which populates federal agencies)
# If permissions on the groups need changing, edit CISA_ANALYST_GROUP_PERMISSIONS
# in the user_group model then:
# [NOT RECOMMENDED]
# step 1: docker-compose exec app ./manage.py migrate --fake registrar 0035_contenttypes_permissions
# step 2: docker-compose exec app ./manage.py migrate registrar 0036_create_groups
# step 3: fake run the latest migration in the migrations list
# [RECOMMENDED]
# Alternatively:
# step 1: duplicate the migration that loads data
# step 2: docker-compose exec app ./manage.py migrate
from django.db import migrations
from registrar.models import UserGroup
from typing import Any
# For linting: RunPython expects a function reference,
# so let's give it one
def create_groups(apps, schema_editor) -> Any:
UserGroup.create_cisa_analyst_group(apps, schema_editor)
UserGroup.create_full_access_group(apps, schema_editor)
class Migration(migrations.Migration):
dependencies = [
("registrar", "0079_create_federal_agencies_v01"),
]
operations = [
migrations.RunPython(
create_groups,
reverse_code=migrations.RunPython.noop,
atomic=True,
),
]

View file

@ -4,6 +4,7 @@ from .domain_request import DomainRequest
from .domain_information import DomainInformation from .domain_information import DomainInformation
from .domain import Domain from .domain import Domain
from .draft_domain import DraftDomain from .draft_domain import DraftDomain
from .federal_agency import FederalAgency
from .host_ip import HostIP from .host_ip import HostIP
from .host import Host from .host import Host
from .domain_invitation import DomainInvitation from .domain_invitation import DomainInvitation
@ -22,6 +23,7 @@ __all__ = [
"Domain", "Domain",
"DraftDomain", "DraftDomain",
"DomainInvitation", "DomainInvitation",
"FederalAgency",
"HostIP", "HostIP",
"Host", "Host",
"UserDomainRole", "UserDomainRole",
@ -39,6 +41,7 @@ auditlog.register(Domain)
auditlog.register(DraftDomain) auditlog.register(DraftDomain)
auditlog.register(DomainInvitation) auditlog.register(DomainInvitation)
auditlog.register(DomainInformation) auditlog.register(DomainInformation)
auditlog.register(FederalAgency)
auditlog.register(HostIP) auditlog.register(HostIP)
auditlog.register(Host) auditlog.register(Host)
auditlog.register(UserDomainRole) auditlog.register(UserDomainRole)

View file

@ -0,0 +1,223 @@
from .utility.time_stamped_model import TimeStampedModel
from django.db import models
import logging
logger = logging.getLogger(__name__)
class FederalAgency(TimeStampedModel):
class Meta:
verbose_name = "Federal agency"
verbose_name_plural = "Federal agencies"
agency = models.CharField(
null=True,
blank=True,
help_text="Federal agency",
)
def __str__(self) -> str:
return f"{self.agency}"
def create_federal_agencies(apps, schema_editor):
"""This method gets run from a data migration to prepopulate data
regarding federal agencies."""
# Hard to pass self to these methods as the calls from migrations
# are only expecting apps and schema_editor, so we'll just define
# apps, schema_editor in the local scope instead
AGENCIES = [
"Administrative Conference of the United States",
"Advisory Council on Historic Preservation",
"American Battle Monuments Commission",
"AMTRAK",
"Appalachian Regional Commission",
("Appraisal Subcommittee of the Federal Financial " "Institutions Examination Council"),
"Architect of the Capitol",
"Armed Forces Retirement Home",
"Barry Goldwater Scholarship and Excellence in Education Foundation",
"Central Intelligence Agency",
"Christopher Columbus Fellowship Foundation",
"Civil Rights Cold Case Records Review Board",
"Commission for the Preservation of America's Heritage Abroad",
"Commission of Fine Arts",
"Committee for Purchase From People Who Are Blind or Severely Disabled",
"Commodity Futures Trading Commission",
"Congressional Budget Office",
"Consumer Financial Protection Bureau",
"Consumer Product Safety Commission",
"Corporation for National and Community Service",
"Council of Inspectors General on Integrity and Efficiency",
"Court Services and Offender Supervision",
"Cyberspace Solarium Commission",
"DC Court Services and Offender Supervision Agency",
"DC Pre-trial Services",
"Defense Nuclear Facilities Safety Board",
"Delta Regional Authority",
"Denali Commission",
"Department of Agriculture",
"Department of Commerce",
"Department of Defense",
"Department of Education",
"Department of Energy",
"Department of Health and Human Services",
"Department of Homeland Security",
"Department of Housing and Urban Development",
"Department of Justice",
"Department of Labor",
"Department of State",
"Department of the Interior",
"Department of the Treasury",
"Department of Transportation",
"Department of Veterans Affairs",
"Director of National Intelligence",
"Dwight D. Eisenhower Memorial Commission",
"Election Assistance Commission",
"Environmental Protection Agency",
"Equal Employment Opportunity Commission",
"Executive Office of the President",
"Export-Import Bank of the United States",
"Farm Credit Administration",
"Farm Credit System Insurance Corporation",
"Federal Communications Commission",
"Federal Deposit Insurance Corporation",
"Federal Election Commission",
"Federal Energy Regulatory Commission",
"Federal Financial Institutions Examination Council",
"Federal Housing Finance Agency",
"Federal Judiciary",
"Federal Labor Relations Authority",
"Federal Maritime Commission",
"Federal Mediation and Conciliation Service",
"Federal Mine Safety and Health Review Commission",
"Federal Permitting Improvement Steering Council",
"Federal Reserve Board of Governors",
"Federal Trade Commission",
"General Services Administration",
"gov Administration",
"Government Accountability Office",
"Government Publishing Office",
"Gulf Coast Ecosystem Restoration Council",
"Harry S. Truman Scholarship Foundation",
"Institute of Museum and Library Services",
"Institute of Peace",
"Inter-American Foundation",
"International Boundary and Water Commission: United States and Mexico",
"International Boundary Commission: United States and Canada",
"International Joint Commission: United States and Canada",
"James Madison Memorial Fellowship Foundation",
"Japan-U.S. Friendship Commission",
"John F. Kennedy Center for the Performing Arts",
"Legal Services Corporation",
"Legislative Branch",
"Library of Congress",
"Marine Mammal Commission",
"Medicaid and CHIP Payment and Access Commission",
"Medicare Payment Advisory Commission",
"Merit Systems Protection Board",
"Millennium Challenge Corporation",
"Morris K. Udall and Stewart L. Udall Foundation",
"National Aeronautics and Space Administration",
"National Archives and Records Administration",
"National Capital Planning Commission",
"National Council on Disability",
"National Credit Union Administration",
"National Endowment for the Arts",
"National Endowment for the Humanities",
"National Foundation on the Arts and the Humanities",
"National Gallery of Art",
"National Indian Gaming Commission",
"National Labor Relations Board",
"National Mediation Board",
"National Science Foundation",
"National Security Commission on Artificial Intelligence",
"National Transportation Safety Board",
"Networking Information Technology Research and Development",
"Non-Federal Agency",
"Northern Border Regional Commission",
"Nuclear Regulatory Commission",
"Nuclear Safety Oversight Committee",
"Occupational Safety and Health Review Commission",
"Office of Compliance",
"Office of Congressional Workplace Rights",
"Office of Government Ethics",
"Office of Navajo and Hopi Indian Relocation",
"Office of Personnel Management",
"Open World Leadership Center",
"Overseas Private Investment Corporation",
"Peace Corps",
"Pension Benefit Guaranty Corporation",
"Postal Regulatory Commission",
"Presidio Trust",
"Privacy and Civil Liberties Oversight Board",
"Public Buildings Reform Board",
"Public Defender Service for the District of Columbia",
"Railroad Retirement Board",
"Securities and Exchange Commission",
"Selective Service System",
"Small Business Administration",
"Smithsonian Institution",
"Social Security Administration",
"Social Security Advisory Board",
"Southeast Crescent Regional Commission",
"Southwest Border Regional Commission",
"State Justice Institute",
"Stennis Center for Public Service",
"Surface Transportation Board",
"Tennessee Valley Authority",
"The Executive Office of the President",
"The Intelligence Community",
"The Legislative Branch",
"The Supreme Court",
"The United States World War One Centennial Commission",
"U.S. Access Board",
"U.S. Agency for Global Media",
"U.S. Agency for International Development",
"U.S. Capitol Police",
"U.S. Chemical Safety Board",
"U.S. China Economic and Security Review Commission",
"U.S. Commission for the Preservation of Americas Heritage Abroad",
"U.S. Commission of Fine Arts",
"U.S. Commission on Civil Rights",
"U.S. Commission on International Religious Freedom",
"U.S. Courts",
"U.S. Department of Agriculture",
"U.S. Interagency Council on Homelessness",
"U.S. International Trade Commission",
"U.S. Nuclear Waste Technical Review Board",
"U.S. Office of Special Counsel",
"U.S. Postal Service",
"U.S. Semiquincentennial Commission",
"U.S. Trade and Development Agency",
"U.S.-China Economic and Security Review Commission",
"Udall Foundation",
"United States AbilityOne",
"United States Access Board",
"United States African Development Foundation",
"United States Agency for Global Media",
"United States Arctic Research Commission",
"United States Global Change Research Program",
"United States Holocaust Memorial Museum",
"United States Institute of Peace",
"United States Interagency Council on Homelessness",
"United States International Development Finance Corporation",
"United States International Trade Commission",
"United States Postal Service",
"United States Senate",
"United States Trade and Development Agency",
"Utah Reclamation Mitigation and Conservation Commission",
"Vietnam Education Foundation",
"Western Hemisphere Drug Policy Commission",
"Woodrow Wilson International Center for Scholars",
"World War I Centennial Commission",
]
FederalAgency = apps.get_model("registrar", "FederalAgency")
logger.info("Creating federal agency table.")
try:
agencies = [FederalAgency(agency=agency) for agency in AGENCIES]
FederalAgency.objects.bulk_create(agencies)
except Exception as e:
logger.error(f"Error creating federal agencies: {e}")

View file

@ -71,6 +71,11 @@ class UserGroup(Group):
"model": "verifiedbystaff", "model": "verifiedbystaff",
"permissions": ["add_verifiedbystaff", "change_verifiedbystaff", "delete_verifiedbystaff"], "permissions": ["add_verifiedbystaff", "change_verifiedbystaff", "delete_verifiedbystaff"],
}, },
{
"app_label": "registrar",
"model": "federalagency",
"permissions": ["add_federalagency", "change_federalagency", "delete_federalagency"],
},
] ]
# Avoid error: You can't execute queries until the end # Avoid error: You can't execute queries until the end

View file

@ -284,7 +284,7 @@ class TestDomainAdmin(MockEppLib, WebTest):
# There are 4 template references to Federal (4) plus four references in the table # There are 4 template references to Federal (4) plus four references in the table
# for our actual domain_request # for our actual domain_request
self.assertContains(response, "Federal", count=8) self.assertContains(response, "Federal", count=36)
# This may be a bit more robust # This may be a bit more robust
self.assertContains(response, '<td class="field-generic_org_type">Federal</td>', count=1) self.assertContains(response, '<td class="field-generic_org_type">Federal</td>', count=1)
# Now let's make sure the long description does not exist # Now let's make sure the long description does not exist
@ -708,7 +708,7 @@ class TestDomainRequestAdmin(MockEppLib):
response = self.client.get("/admin/registrar/domainrequest/") response = self.client.get("/admin/registrar/domainrequest/")
# There are 4 template references to Federal (4) plus two references in the table # There are 4 template references to Federal (4) plus two references in the table
# for our actual domain request # for our actual domain request
self.assertContains(response, "Federal", count=6) self.assertContains(response, "Federal", count=34)
# This may be a bit more robust # This may be a bit more robust
self.assertContains(response, '<td class="field-generic_org_type">Federal</td>', count=1) self.assertContains(response, '<td class="field-generic_org_type">Federal</td>', count=1)
# Now let's make sure the long description does not exist # Now let's make sure the long description does not exist

View file

@ -39,6 +39,9 @@ class TestGroups(TestCase):
"view_domaininvitation", "view_domaininvitation",
"change_domainrequest", "change_domainrequest",
"change_draftdomain", "change_draftdomain",
"add_federalagency",
"change_federalagency",
"delete_federalagency",
"analyst_access_permission", "analyst_access_permission",
"change_user", "change_user",
"delete_userdomainrole", "delete_userdomainrole",