Skip to content

Commit

Permalink
Merge pull request #765 from cisagov/AL-create-pg-scan-user
Browse files Browse the repository at this point in the history
Automate creating a postgres user for DB scanning
  • Loading branch information
schmelz21 authored Jan 21, 2025
2 parents 10ce721 + d0b03c4 commit 54f50b0
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 1 deletion.
12 changes: 12 additions & 0 deletions backend/env.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ dev:
REGION: us-east-1

staging-cd:
IS_DMZ: 1
REGION: us-east-1
ENDPOINT_TYPE: REGIONAL
COGNITO_URL: https://cognito-idp.us-east-1.amazonaws.com
Expand All @@ -24,6 +25,8 @@ staging-cd:
MDL_USERNAME: ${ssm:/crossfeed/staging/MDL_USERNAME}
MDL_PASSWORD: ${ssm:/crossfeed/staging/MDL_PASSWORD}
MDL_NAME: ${ssm:/crossfeed/staging/MDL_NAME}
POSTGRES_SCAN_USER: ${ssm:/crossfeed/staging/POSTGRES_SCAN_USER}
POSTGRES_SCAN_PASSWORD: ${ssm:/crossfeed/staging/POSTGRES_SCAN_PASSWORD}
MI_ACCOUNT_NAME: ${ssm:/readysetcyber/staging/MI_ACCOUNT_NAME}
MI_PASSWORD: ${ssm:/readysetcyber/staging/MI_ACCOUNT_PASSWORD}
PE_DB_NAME: ${ssm:/crossfeed/staging/PE_DB_NAME}
Expand Down Expand Up @@ -78,6 +81,7 @@ staging-cd:
REACT_APP_COGNITO_CALLBACK_URL: https://staging-cd.crossfeed.cyber.dhs.gov/okta-callback

integration:
IS_DMZ: 1
REGION: us-east-1
ENDPOINT_TYPE: REGIONAL
COGNITO_URL: https://cognito-idp.us-east-1.amazonaws.com
Expand All @@ -95,6 +99,8 @@ integration:
MDL_USERNAME: ${ssm:/crossfeed/integration/MDL_USERNAME}
MDL_PASSWORD: ${ssm:/crossfeed/integration/MDL_PASSWORD}
MDL_NAME: ${ssm:/crossfeed/integration/MDL_NAME}
POSTGRES_SCAN_USER: ${ssm:/crossfeed/integration/POSTGRES_SCAN_USER}
POSTGRES_SCAN_PASSWORD: ${ssm:/crossfeed/integration/POSTGRES_SCAN_PASSWORD}
MI_ACCOUNT_NAME: ${ssm:/readysetcyber/integration/MI_ACCOUNT_NAME}
MI_PASSWORD: ${ssm:/readysetcyber/integration/MI_ACCOUNT_PASSWORD}
JWT_SECRET: ${ssm:/crossfeed/integration/APP_JWT_SECRET}
Expand Down Expand Up @@ -142,6 +148,7 @@ integration:
ELASTICACHE_ENDPOINT: ${ssm:/crossfeed/integration/ELASTICACHE_ENDPOINT}

staging:
IS_DMZ: 0
REGION: us-gov-east-1
ENDPOINT_TYPE: PRIVATE
COGNITO_URL: https://cognito-idp.us-gov-west-1.amazonaws.com
Expand All @@ -157,6 +164,8 @@ staging:
DB_NAME: ${ssm:/crossfeed/staging/DATABASE_NAME}
DB_USERNAME: ${ssm:/crossfeed/staging/DATABASE_USER}
DB_PASSWORD: ${ssm:/crossfeed/staging/DATABASE_PASSWORD}
POSTGRES_SCAN_USER: ${ssm:/crossfeed/staging/POSTGRES_SCAN_USER}
POSTGRES_SCAN_PASSWORD: ${ssm:/crossfeed/staging/POSTGRES_SCAN_PASSWORD}
JWT_SECRET: ${ssm:/crossfeed/staging/APP_JWT_SECRET}
JWT_ALGORITHM: ${ssm:/crossfeed/staging/JWT_ALGORITHM}
JWT_TIMEOUT_HOURS: ${ssm:/crossfeed/staging/JWT_TIMEOUT_HOURS}
Expand Down Expand Up @@ -204,6 +213,7 @@ staging:
ELASTICACHE_ENDPOINT: ${ssm:/crossfeed/staging/ELASTICACHE_ENDPOINT}

prod:
IS_DMZ: 0
REGION: us-gov-east-1
ENDPOINT_TYPE: PRIVATE
COGNITO_URL: https://cognito-idp.us-gov-west-1.amazonaws.com
Expand All @@ -223,6 +233,8 @@ prod:
MDL_PASSWORD: ${ssm:/crossfeed/prod/MDL_PASSWORD}
DJANGO_SECRET: ${ssm:/crossfeed/prod/DJANGO_SECRECT}
MDL_NAME: ${ssm:/crossfeed/prod/MDL_NAME}
POSTGRES_SCAN_USER: ${ssm:/crossfeed/prod/POSTGRES_SCAN_USER}
POSTGRES_SCAN_PASSWORD: ${ssm:/crossfeed/prod/POSTGRES_SCAN_PASSWORD}
JWT_SECRET: ${ssm:/crossfeed/prod/APP_JWT_SECRET}
JWT_ALGORITHM: ${ssm:/crossfeed/prod/JWT_ALGORITHM}
JWT_TIMEOUT_HOURS: ${ssm:/crossfeed/prod/JWT_TIMEOUT_HOURS}
Expand Down
7 changes: 6 additions & 1 deletion backend/src/xfd_django/xfd_api/management/commands/syncdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from django.core.management.base import BaseCommand
from xfd_api.tasks.searchSync import handler as sync_es_domains
from xfd_api.tasks.syncdb_helpers import (
create_scan_user,
drop_all_tables,
manage_elasticsearch_indices,
populate_sample_data,
Expand Down Expand Up @@ -48,7 +49,11 @@ def handle(self, *args, **options):
# Step 2: Elasticsearch Index Management
manage_elasticsearch_indices(dangerouslyforce)

# Step 3: Populate Sample Data
# Step 3: Create the scanning user if doesn't exist
self.stdout.write("Creating and configuring the scanning user...")
create_scan_user()

# Step 4: Populate Sample Data
if populate:
self.stdout.write("Populating the database with sample data...")
populate_sample_data()
Expand Down
49 changes: 49 additions & 0 deletions backend/src/xfd_django/xfd_api/tasks/syncdb_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,3 +483,52 @@ def sync_es_organizations():
except Exception as e:
print("Error syncing organizations: {}".format(e))
raise e


def create_scan_user():
"""Create and configure the scanning user if it does not already exist."""
# Only create if not in the DMZ
is_dmz = os.getenv("IS_DMZ", "0") == "1"

if is_dmz:
print("IS_DMZ is set to 1. Skipping creation of the scanning user.")
return

user = os.getenv("POSTGRES_SCAN_USER")
password = os.getenv("POSTGRES_SCAN_PASSWORD")
if not user or not password:
print("POSTGRES_SCAN_USER or POSTGRES_SCAN_PASSWORD is not set.")
return

db_name = settings.DATABASES["default"]["NAME"]

with connection.cursor() as cursor:
try:
# Check if the user already exists
cursor.execute("SELECT 1 FROM pg_roles WHERE rolname = %s;", [user])
user_exists = cursor.fetchone() is not None

if not user_exists:
# Create the user
cursor.execute(
"CREATE ROLE {} LOGIN PASSWORD %s;".format(user), [password]
)
print("User '{}' created successfully.".format(user))
else:
print("User '{}' already exists. Skipping creation.".format(user))

# Grant privileges (idempotent as well)
cursor.execute("GRANT CONNECT ON DATABASE {} TO {};".format(db_name, user))
cursor.execute("GRANT USAGE ON SCHEMA public TO {};".format(user))
cursor.execute(
"GRANT SELECT ON ALL TABLES IN SCHEMA public TO {};".format(user)
)
cursor.execute(
"ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO {};".format(
user
)
)

print("User '{}' configured successfully.".format(user))
except Exception as e:
print("Error creating or configuring scan user: {}".format(e))
4 changes: 4 additions & 0 deletions dev.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,7 @@ ELASTICACHE_ENDPOINT=redis
WHOIS_XML_KEY=change_me
QUALYS_USERNAME=change_me
QUALYS_PASSWORD=change_me

IS_DMZ=1
POSTGRES_SCAN_USER=
POSTGRES_SCAN_PASSWORD=

0 comments on commit 54f50b0

Please sign in to comment.