Skip to content

Commit

Permalink
Merge pull request #183 from kids-first/enable-expunge
Browse files Browse the repository at this point in the history
🔧 Enable expunge / delete-expunge operations
  • Loading branch information
znatty22 committed Jan 9, 2024
2 parents fb43c4b + f0cedee commit 42c0d55
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 28 deletions.
4 changes: 3 additions & 1 deletion bin/admin_backup.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@ def upsert_admin(username, password):
],
}
]
upsert_users(
users = upsert_users(
FHIR_APP_ADMIN, FHIR_APP_ADMIN_PW, USER_MGMNT_ENDPOINT, users
)

return users


def cli():
"""
Expand Down
109 changes: 109 additions & 0 deletions bin/unlock_account.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#!/usr/bin/env python

# Unlock user account

# This is used to unlock the main admin account. Often times during
# deployment, the main admin account gets locked. We don't know why
# but we can unlock it with the backup

import argparse
from pprint import pprint, pformat

import requests
from requests.auth import HTTPBasicAuth

from src.config import (
USER_MGMNT_ENDPOINT,
FHIR_APP_ADMIN,
FHIR_APP_ADMIN_PW
)

from src.bin.seed_users import upsert_users, get_user


def unlock_account(user, admin_username, admin_password):
"""
Unlock account
"""
pid = user["pid"]
user.update({
"accountLocked": False,
})
url = f"{USER_MGMNT_ENDPOINT}/Master/local_security/{pid}"

result = None
try:
headers = {
"Content-Type": "application/json",
}
resp = requests.put(
url,
headers=headers,
auth=HTTPBasicAuth(admin_username, admin_password),
json=user
)
resp.raise_for_status()
result = resp.json()
print(f"Updated user {user['username']} at {url}")
except (
requests.exceptions.HTTPError, requests.exceptions.JSONDecodeError
) as e:
print(f"Failed to update user {user['username']} at {url}")
print("Problem sending request to FHIR server")
print(resp.text)
if "ConstraintViolationException" in resp.text:
update_pid = True
else:
raise e
return result


def cli():
"""
CLI for running this script
"""
parser = argparse.ArgumentParser(
description='Unlock user account'
)
parser.add_argument(
"--username",
help="Username to unlock",
)
parser.add_argument(
"--admin_username",
default="admin_backup",
help="Admin username",
)
parser.add_argument(
"--admin_password",
default=FHIR_APP_ADMIN_PW,
help="Admin password",
)
args = parser.parse_args()

# Unlock the account with backup admin
print(
f"🔎 Searching for user: {args.username}"
)
result = get_user(
f"{USER_MGMNT_ENDPOINT}/Master/local_security",
args.username,
FHIR_APP_ADMIN,
FHIR_APP_ADMIN_PW,
)
if not result:
print(
f"❌ Could not unlock user '{args.username}' because"
" user does not exist yet"
)
else:
print(f"🔓 Attempting to unlock account {args.username}")
users = unlock_account(
result, args.admin_username, args.admin_password
)
pprint(users)
print(f"✅ Unlock {args.username} complete")


if __name__ == "__main__":
cli()
1 change: 1 addition & 0 deletions playbook/post_deploy_config
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pip install -r dev-requirements.txt
pip install -e .

echo "👮🏻‍♀️ Upsert backup admin user"
python bin/unlock_account.py --username=admin
python bin/admin_backup.py

# Run tests
Expand Down
8 changes: 4 additions & 4 deletions smilecdr/settings/server-postgres.properties
Original file line number Diff line number Diff line change
Expand Up @@ -301,23 +301,23 @@ module.persistence.config.cascading_delete.enabled=false
module.persistence.config.dao_config.allow_contains_searches=false
module.persistence.config.dao_config.allow_external_references.enabled=false
module.persistence.config.dao_config.allow_inline_match_url_references.enabled=true
module.persistence.config.dao_config.allow_multiple_delete.enabled=false
module.persistence.config.dao_config.allow_multiple_delete.enabled=true
module.persistence.config.dao_config.allow_storing_all_bundle_types=false
module.persistence.config.dao_config.auto_create_placeholder_reference_targets.enabled=false
module.persistence.config.dao_config.bundle_validation_thread_count=4
module.persistence.config.dao_config.client_id_mode=ALPHANUMERIC
module.persistence.config.dao_config.concurrent_bundle_validation=false
module.persistence.config.dao_config.delete_child_resource.count=60
module.persistence.config.dao_config.delete_enabled=true
module.persistence.config.dao_config.delete_expunge_enabled=false
module.persistence.config.dao_config.delete_expunge_enabled=true
module.persistence.config.dao_config.default_total_mode=ACCURATE
module.persistence.config.dao_config.enforce_reference_target_types=true
module.persistence.config.dao_config.enforce_referential_integrity_on_delete.enabled=true
module.persistence.config.dao_config.enforce_referential_integrity_on_write.enabled=true
module.persistence.config.dao_config.expansion.maximum_size=1000
module.persistence.config.dao_config.expire_search_results_after_minutes=60
module.persistence.config.dao_config.expunge_batch_size=800
module.persistence.config.dao_config.expunge_operation_enabled=false
module.persistence.config.dao_config.expunge_batch_size=1000
module.persistence.config.dao_config.expunge_operation_enabled=true
module.persistence.config.dao_config.expunge_thread_count=2
module.persistence.config.dao_config.history_rewrite.enabled=false
module.persistence.config.dao_config.index_contained_resources=DISABLED
Expand Down
53 changes: 32 additions & 21 deletions src/bin/seed_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,37 @@
)


def get_user(url, username, client_id, client_secret):
"""
Get user by username
"""
headers = {
"Content-Type": "application/json",
}
# Get user by username
result = None
try:
resp = requests.get(
f"{url}?searchTerm={username}",
headers=headers,
auth=HTTPBasicAuth(client_id, client_secret),
)
resp.raise_for_status()
result = resp.json().get("users", [])
if len(result) > 0:
result = result[0]
except (
requests.exceptions.HTTPError, requests.exceptions.JSONDecodeError
) as e:
print("Problem sending request to FHIR server")
print(f"Response:\n{resp.text}")
if resp.status_code == 404:
print(f"Could not find user {username}")
else:
raise e
return result


def add_authorization(user):
# Extract consent authorizations and store in user.notes as JSON encoded str
consent = user.get("auth_config", {})
Expand Down Expand Up @@ -77,27 +108,7 @@ def upsert_users(client_id, client_secret, endpoint, users):
module_endpoint = f"{endpoint}/{node_id}/{module_id}"

# Get user by username
result = None
try:
resp = requests.get(
f"{module_endpoint}?searchTerm={username}",
headers=headers,
auth=HTTPBasicAuth(client_id, client_secret),
)
resp.raise_for_status()
result = resp.json().get("users", [])
if len(result) > 0:
result = result[0]
except (
requests.exceptions.HTTPError, requests.exceptions.JSONDecodeError
) as e:
print(f"Failed to find user {user['username']}")
print("Problem sending request to FHIR server")
print(f"Response:\n{resp.text}")
if resp.status_code == 404:
pass
else:
raise e
result = get_user(module_endpoint, username, client_id, client_secret)

# Update user
if result:
Expand Down
2 changes: 0 additions & 2 deletions tests/python/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ def _upsert_smilecdr_users(users):
"""
Upsert list of user objects into smilecdr
"""
for user in users:
user["accountLocked"] = False
upserted.extend(
upsert_users(
FHIR_APP_ADMIN, FHIR_APP_ADMIN_PW, USER_MGMNT_ENDPOINT, users
Expand Down

0 comments on commit 42c0d55

Please sign in to comment.