Skip to content

Commit

Permalink
Merge pull request #1928 from cisagov/rh/1896-federal-agency
Browse files Browse the repository at this point in the history
ISSUE #1896: Add Federal Agency Table
  • Loading branch information
erinysong authored Mar 26, 2024
2 parents a3e1e1f + af81357 commit e2974a8
Show file tree
Hide file tree
Showing 8 changed files with 319 additions and 2 deletions.
8 changes: 8 additions & 0 deletions src/registrar/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -1814,6 +1814,13 @@ def save_model(self, 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.register(LogEntry, CustomLogEntryAdmin)
admin.site.register(models.User, MyUserAdmin)
Expand All @@ -1827,6 +1834,7 @@ def save_model(self, request, obj, form, change):
admin.site.register(models.DomainInformation, DomainInformationAdmin)
admin.site.register(models.Domain, DomainAdmin)
admin.site.register(models.DraftDomain, DraftDomainAdmin)
admin.site.register(models.FederalAgency, FederalAgencyAdmin)
# Host and HostIP removed from django admin because changes in admin
# do not propagate to registry and logic not applied
admin.site.register(models.Host, MyHostAdmin)
Expand Down
38 changes: 38 additions & 0 deletions src/registrar/migrations/0079_create_federal_agencies_v01.py
Original file line number Diff line number Diff line change
@@ -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,
),
]
37 changes: 37 additions & 0 deletions src/registrar/migrations/0080_create_groups_v09.py
Original file line number Diff line number Diff line change
@@ -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,
),
]
3 changes: 3 additions & 0 deletions src/registrar/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from .domain_information import DomainInformation
from .domain import Domain
from .draft_domain import DraftDomain
from .federal_agency import FederalAgency
from .host_ip import HostIP
from .host import Host
from .domain_invitation import DomainInvitation
Expand All @@ -22,6 +23,7 @@
"Domain",
"DraftDomain",
"DomainInvitation",
"FederalAgency",
"HostIP",
"Host",
"UserDomainRole",
Expand All @@ -39,6 +41,7 @@
auditlog.register(DraftDomain)
auditlog.register(DomainInvitation)
auditlog.register(DomainInformation)
auditlog.register(FederalAgency)
auditlog.register(HostIP)
auditlog.register(Host)
auditlog.register(UserDomainRole)
Expand Down
223 changes: 223 additions & 0 deletions src/registrar/models/federal_agency.py
Original file line number Diff line number Diff line change
@@ -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}")
5 changes: 5 additions & 0 deletions src/registrar/models/user_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ def create_cisa_analyst_group(apps, schema_editor):
"model": "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
Expand Down
4 changes: 2 additions & 2 deletions src/registrar/tests/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ def test_short_org_name_in_domains_list(self):

# There are 4 template references to Federal (4) plus four references in the table
# for our actual domain_request
self.assertContains(response, "Federal", count=8)
self.assertContains(response, "Federal", count=36)
# This may be a bit more robust
self.assertContains(response, '<td class="field-generic_org_type">Federal</td>', count=1)
# Now let's make sure the long description does not exist
Expand Down Expand Up @@ -708,7 +708,7 @@ def test_short_org_name_in_domain_requests_list(self):
response = self.client.get("/admin/registrar/domainrequest/")
# There are 4 template references to Federal (4) plus two references in the table
# for our actual domain request
self.assertContains(response, "Federal", count=6)
self.assertContains(response, "Federal", count=34)
# This may be a bit more robust
self.assertContains(response, '<td class="field-generic_org_type">Federal</td>', count=1)
# Now let's make sure the long description does not exist
Expand Down
3 changes: 3 additions & 0 deletions src/registrar/tests/test_migrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ def test_groups_created(self):
"view_domaininvitation",
"change_domainrequest",
"change_draftdomain",
"add_federalagency",
"change_federalagency",
"delete_federalagency",
"analyst_access_permission",
"change_user",
"delete_userdomainrole",
Expand Down

0 comments on commit e2974a8

Please sign in to comment.