Skip to content

Merge setup script changes from v7.12.0.7 into main - #8388

Open
melton-jason wants to merge 4 commits into
mainfrom
setup_script_hotfix
Open

Merge setup script changes from v7.12.0.7 into main#8388
melton-jason wants to merge 4 commits into
mainfrom
setup_script_hotfix

Conversation

@melton-jason

@melton-jason melton-jason commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

This PR fixes an Issue with the Setup Script where:

  1. The APP or MIGRATOR user was the same as the MASTER_USER
  2. The MASTER_USER host as seen from the MariaDB server is more broad than the IP address of the client

Specifically, the setup script would always try and use the IP address of the client as seen from the server when dealing with authentication connection.
For example, if there was a master@% user on the database and the IP address of the client from the perspective of the database was an IP address like 192.168.0.2, then Specify would check for and create a master@'192.168.0.2' MIGRATOR/APP user if the name portion of the connection was the same as the MASTER user.
This led to a problem where:

  1. Specify would (correctly) use the more broad connection to connect
    a. For example, consider the above case where the user is defined as master@'%'
  2. Specify would use the client's IP to check if the user existed in the database
    a. In the example case, the query would indicate the user does not exist as there's not a user for master@'192.168.0.2'
  3. Seeing that the user doesn't exist, Specify would use create the more specific user
    a. e.g., master@'192.168.0.2'
  4. For all future queries, the database will prioritize the new more-specific connection
    a. This includes the queries that give the new user permissions, which the new user will always not be able to do

This PR does two things:

  1. By default, inherits the host of the MASTER_USER when creating/connecting with the MIGRATOR or APP user
    a. This results in Specify only working with the most specific host name combination that already exists on the master user
    b. e.g., if the master user connection is defined as master@%, the migrator and app user will inherit the host of %
    c. If there are two connections for master: master@%  and master@ip , then Specify will use ip when the connection is authenticated with that connection (i.e., when connecting to the DB from that IP)
    d. This should work out-of-the-box and be sufficient for nearly all connections. This directly resolves the instigating Issue where Specify was creating a user with a more-specific IP

  2. Allows the MIGRATOR and APP user hosts from the MariaDB side to be manually overwritten through the MIGRATOR_USER_HOST and APP_USER_HOST environment variables
    a. The use case for these is for more fine-grained hosts for the created users. I would say these are for more advanced setups and most people will not need these options
    b. These variables do not have a default value and only have meaning when explicitly set (they will "default" to inheriting the host of the master user)
    c. If the user itself would be inherited (e.g., in the case where the migrator user is the same as the master user, or the app user is the same as the master user or migrator user) then these variables are ignored/inherited in order of precedence
    d. This has some pros/cons. It leads to a little less flexibility from a user perspective, but does prevent the leading issue from happening. If someone is familiar with database administration, then it is better to not have this feature: otherwise I think it's safest to have a safety guard at the cost of flexibility
    e. The commit for this is 9ebe0c9

Checklist

  • Self-review the PR after opening it to make sure the changes look good and
    self-explanatory (or properly documented)
  • Add relevant issue to release milestone
  • Add pr to documentation list
  • Add automated tests
  • Add a reverse migration if a migration is present in the PR
  • Add migration function to
    def fix_schema_config(stdout: WriteToStdOut | None = None):

Testing instructions

These testing instructions will only be performable with a local Specify instance where you have access to the database

  • Ensure there is one MariaDB user with the name (excluding host) indicated by the MASTER_NAME environment variable and the user's host is something overly broad, like %

You can run the following SQL in the MariaDB database to view all users and their respective hosts:

SELECT User, Host FROM mysql.user;

You can use CREATE USER to create new MariaDB users.
e.g.:

CREATE USER 'master'@'%' identified by 'somepassword';
-- specifying a more specific host
CREATE USER 'master'@'localhost' identified by 'somepassword';
-- note that any number of users with the same name but different hosts can exist at the same time, and MariaDB will prefer the most specific/accurate user when authenticating

You can use DROP USER to delete MariaDB users:

DROP USER 'master'@'%';
DROP USER 'master'@'localhost';
  • Ensure the MASTER_NAME user from the previous user has permissions to completely create, delete, and modify databases, as well as modify the permissions of other users
    • You can use ALL PRIVILEGES ON *.* and make sure they have GRANT OPTION

View GRANT for a refresher on how to give users different permissions:

-- Gives all permissions on all databases, and enables this user
-- to give or take these permissions from other users
GRANT ALL PRIVILEGES ON *.* to 'master'@'%' WITH GRANT OPTION;

-- Gives all permissions to the database my_db, and this user can
-- not affect other users permissions
GRANT ALL PRIVILEGES ON my_db.* to 'master'@'%';
  • Get the values of the IP of the Specify 7 container as seen by the database manager, and the user + host name for the authenticating connection (these will be used for later testing instructions)
    • The host for the former should be something like localhost or a private IP like (172.18.x.x), while the latter should be the connection set up and/or verified in the previous step

You can run the following command from the "root" directory of Specify 7 to get the IP address of the Specify7 container as seen by MariaDB (USER()), as well as the full name of the user used to authenticate the connection (CURRENT_USER()).

docker compose exec -it specify7 bash -c 'mariadb -u "$MASTER_NAME" --password="$MASTER_PASSWORD" -h $DATABASE_HOST -e "SELECT USER(), CURRENT_USER();"'

  • Ensure the MIGRATOR_NAME and APP_USER_NAME environment variables are different from each other and the MASTER_NAME environment variable
  • Ensure that there are no pre-existing users in the database which have the names of the MIGRATOR_NAME and APP_USER_NAME (with any host)
  • Start Specify7 and ensure the database setup script completes successfully (or at least gets to checking for and/or running migrations)
  • Ensure that the created users have a Host which matches that of the MASTER_NAME user

  • Set the MIGRATOR_NAME and MIGRATOR_PASSWORD environment variables to the same as the MASTER_NAME and MASTER_PASSWORD environment variables
  • Ensure that there are no pre-existing users in the database which have the names of the MASTER_NAME and do not have a generic host from the first step (%)
  • Start Specify7 and ensure the database setup script completes successfully
  • Ensure that a new user was not created in MariaDB for the MIGRATOR_NAME
  • With the MIGRATOR variables still matching the MASTER variables, set the MIGRATOR_USER_HOST environment variable to a valid, but more specific value
    • This can be the host returned by the USER() function executed earlier in these testing instructions
  • Start Specify7 and ensure the database setup script completes successfully
  • Ensure that a new user was not created in MariaDB for the MIGRATOR_NAME

  • Set the APP_USER_NAME and APP_USER_PASSWORD to the same as the MASTER_NAME and MASTER_PASSWORD environment variables
  • Ensure that there are no pre-existing users in the database which have the names of the MASTER_NAME and do not have a generic host from the first step (%)
  • Start Specify7 and ensure the database setup script completes successfully
  • Ensure that a new user was not created in MariaDB for the APP_USER_NAME
  • With the APP_USER variables still matching the MASTER variables, set the APP_USER_HOST environment variable to any value that is not the generic host from the first step
  • Start Specify7 and ensure the database setup script completes successfully
  • Ensure that a new user was not created in MariaDB for the APP_USER_NAME

  • Set the APP_USER_NAME and APP_USER_PASSWORD to the same as the MIGRATOR_NAME and MIGRATOR_PASSWORD environment variables
  • Ensure that there are no pre-existing users in the database which have the names of the MIGRATOR_NAME and do not have a generic host from the first step (%)
  • Start Specify7 and ensure the database setup script completes successfully
  • Ensure that a new user was not created in MariaDB for the APP_USER_NAME
  • With the APP_USER variables still matching the MIGRATOR variables, set the APP_USER_HOST environment variable to something different from the MIGRATOR_USER_HOST
  • Start Specify7 and ensure the database setup script completes successfully
  • Ensure that a new user was not created in MariaDB for the APP_USER_NAME

  • Set the MIGRATOR_NAME to be different from the MASTER_NAME
  • Set the MIGRATOR_USER_HOST environment variable to a valid, but more specific value than the host of the MASTER user
    • This can be the host returned by the USER() function executed earlier in these testing instructions
  • Start Specify7 and ensure the database setup script completes successfully
  • Ensure that a new user was created with the MIGRATOR_NAME and MIGRATOR_USER_HOST

  • Set the APP_USER_NAME to be different from the MASTER_NAME and MIGRATOR_NAME
  • Set the APP_USER_HOST environment variable to a valid, but more specific value than the host of the MASTER user
    • This can be the host returned by the USER() function executed earlier in these testing instructions
  • Start Specify7 and ensure the database setup script completes successfully
  • Ensure that a new user was created with the APP_USER_NAME and APP_USER_HOST

Summary by CodeRabbit

  • Bug Fixes

    • Improved MariaDB account host detection during setup.
    • Corrected permissions, verification, and diagnostics for migrator and application accounts.
    • Removed an outdated warning that could appear during host detection.
    • Improved setup reliability when configuring database access across different connection environments.
  • Maintenance

    • Applied consistency and readability improvements to attachment bulk import components without changing functionality.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 09213c05-ea49-40b4-a6dc-33a7f7f3304a

📥 Commits

Reviewing files that changed from the base of the PR and between edd7b09 and ef57132.

📒 Files selected for processing (6)
  • specifyweb/frontend/js_src/lib/components/AttachmentsBulkImport/Import.tsx
  • specifyweb/frontend/js_src/lib/components/AttachmentsBulkImport/MatchingModeDialog.tsx
  • specifyweb/frontend/js_src/lib/components/AttachmentsBulkImport/ViewAttachmentFiles.tsx
  • specifyweb/frontend/js_src/lib/components/AttachmentsBulkImport/__tests__/utils.test.ts
  • specifyweb/frontend/js_src/lib/components/AttachmentsBulkImport/useEagerDataset.ts
  • specifyweb/frontend/js_src/lib/components/AttachmentsBulkImport/utils.ts

📝 Walkthrough

Walkthrough

The setup script derives separate MariaDB hosts for migrator and app accounts. Attachment bulk-import files receive formatting-only updates with no behavior or API changes.

Changes

MariaDB account host targeting

Layer / File(s) Summary
Account host resolution
sp7_db_setup_check.sh
CURRENT_USER() derives separate hosts for migrator and app accounts. Shared credentials can reuse hosts.
Migrator account operations
sp7_db_setup_check.sh
Migrator checks, creation, grants, verification, and diagnostics use MIGRATOR_USER_HOST.
App account operations
sp7_db_setup_check.sh
App account checks, creation, grants, verification, and diagnostics use APP_USER_HOST.

Attachment bulk-import formatting

Layer / File(s) Summary
Attachment component formatting
specifyweb/frontend/js_src/lib/components/AttachmentsBulkImport/{Import.tsx,MatchingModeDialog.tsx,ViewAttachmentFiles.tsx}
Existing conditions, imports, callbacks, assignments, and expressions are reformatted without behavior changes.
Attachment utility and test formatting
specifyweb/frontend/js_src/lib/components/AttachmentsBulkImport/{useEagerDataset.ts,utils.ts,__tests__/utils.test.ts}
Existing fallback logic, status conditions, assertions, and test data are reformatted without behavior changes.

Possibly related PRs

Suggested reviewers: g1rly-c0d3r

🚥 Pre-merge checks | ✅ 4 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Automatic Tests ⚠️ Warning The setup-script feature commits changed only sp7_db_setup_check.sh; the changed Jest file is formatting-only, and the PR checklist leaves “Add automated tests” unchecked. Add automated coverage for inherited hosts, explicit host overrides, and same-user precedence, using mocked MariaDB commands or a MariaDB integration test.
Testing Instructions ⚠️ Warning The sequential steps set MIGRATOR=MASTER before APP=MIGRATOR, so all three accounts match and the script takes SAME_MASTER_AND_APP before SAME_MIGRATOR_AND_APP. Reset MIGRATOR_NAME/password to values distinct from MASTER before the APP=MIGRATOR scenario, then verify that branch ignores APP_USER_HOST and creates no new account.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: merging the v7.12.0.7 setup script changes into main.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch setup_script_hotfix

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jul 31, 2026

Copy link
Copy Markdown

Warning

One or more dependencies are approaching or past End-of-Life.
Please plan upgrades accordingly.

STATUS=WARNING
NODE_VERSION=20
NODE_CYCLE=20
EOL_DATE=2026-04-30
DAYS_REMAINING=-94

--- Node.js ---
Version: 20
EOL: 2026-04-30
Status: WARNING

STATUS=OK
PYTHON_VERSION=3.12
PYTHON_CYCLE=3.12
EOL_DATE=2028-10-31
DAYS_REMAINING=821

--- Python ---
Version: 3.12
EOL: 2028-10-31
Status: OK

STATUS=WARNING
DJANGO_VERSION=4.2
DJANGO_CYCLE=4.2
EOL_DATE=2026-04-07
DAYS_REMAINING=-117

--- Django ---
Version: 4.2
EOL: 2026-04-07
Status: WARNING


@melton-jason
melton-jason requested a review from a team July 31, 2026 16:35

@g1rly-c0d3r g1rly-c0d3r left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Testing instructions


  • Ensure the MIGRATOR_NAME and APP_USER_NAME environment variables are different from each other and the MASTER_NAME environment variable
  • Ensure that there are no pre-existing users in the database which have the names of the MIGRATOR_NAME and APP_USER_NAME (with any host)
  • Start Specify7 and ensure the database setup script completes successfully (or at least gets to checking for and/or running migrations)
  • Ensure that the created users have a Host which matches that of the MASTER_NAME user

  • Set the MIGRATOR_NAME and MIGRATOR_PASSWORD environment variables to the same as the MASTER_NAME and MASTER_PASSWORD environment variables
  • Ensure that there are no pre-existing users in the database which have the names of the MASTER_NAME and do not have a generic host from the first step (%)
  • Start Specify7 and ensure the database setup script completes successfully
  • Ensure that a new user was not created in MariaDB for the MIGRATOR_NAME
  • With the MIGRATOR variables still matching the MASTER variables, set the MIGRATOR_USER_HOST environment variable to a valid, but more specific value
    • This can be the host returned by the USER() function executed earlier in these testing instructions
  • Start Specify7 and ensure the database setup script completes successfully
  • Ensure that a new user was not created in MariaDB for the MIGRATOR_NAME

  • Set the APP_USER_NAME and APP_USER_PASSWORD to the same as the MASTER_NAME and MASTER_PASSWORD environment variables
  • Ensure that there are no pre-existing users in the database which have the names of the MASTER_NAME and do not have a generic host from the first step (%)
  • Start Specify7 and ensure the database setup script completes successfully
  • Ensure that a new user was not created in MariaDB for the APP_USER_NAME
  • With the APP_USER variables still matching the MASTER variables, set the APP_USER_HOST environment variable to any value that is not the generic host from the first step
  • Start Specify7 and ensure the database setup script completes successfully
  • Ensure that a new user was not created in MariaDB for the APP_USER_NAME

  • Set the APP_USER_NAME and APP_USER_PASSWORD to the same as the MIGRATOR_NAME and MIGRATOR_PASSWORD environment variables
  • Ensure that there are no pre-existing users in the database which have the names of the MIGRATOR_NAME and do not have a generic host from the first step (%)
  • Start Specify7 and ensure the database setup script completes successfully
  • Ensure that a new user was not created in MariaDB for the APP_USER_NAME
  • With the APP_USER variables still matching the MIGRATOR variables, set the APP_USER_HOST environment variable to something different from the MIGRATOR_USER_HOST
  • Start Specify7 and ensure the database setup script completes successfully
  • Ensure that a new user was not created in MariaDB for the APP_USER_NAME

  • Set the MIGRATOR_NAME to be different from the MASTER_NAME
  • Set the MIGRATOR_USER_HOST environment variable to a valid, but more specific value than the host of the MASTER user
    • This can be the host returned by the USER() function executed earlier in these testing instructions
  • Start Specify7 and ensure the database setup script completes successfully
  • Ensure that a new user was created with the MIGRATOR_NAME and MIGRATOR_USER_HOST

  • Set the APP_USER_NAME to be different from the MASTER_NAME and MIGRATOR_NAME
  • Set the APP_USER_HOST environment variable to a valid, but more specific value than the host of the MASTER user
    • This can be the host returned by the USER() function executed earlier in these testing instructions
  • Start Specify7 and ensure the database setup script completes successfully
  • Ensure that a new user was created with the APP_USER_NAME and APP_USER_HOST

Looks good, all users were created correctly when I specified no host, and when I did, they were not duplicated. When I initially specified a host, they were created with that name.

I do think that it could be confusing that the MIGRATOR_USER_HOST has a different naming scheme than both MIGRATOR_NAME and MIGRATOR_PASSWORD, but @melton-jason explained that this was more accurate. I think the best solution is to potentially re-name MIGRATOR_NAME and MIGRATOR_PASSWORD, but I understand that that would cause any self-hosted user to have to edit these variables, potentially causing confusion.

Base automatically changed from v7_12_0_7_main to main August 2, 2026 02:04

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@sp7_db_setup_check.sh`:
- Around line 175-186: After resolving MIGRATOR_USER_HOST and APP_USER_HOST,
create separate SQL-escaped host variables with sql_string_literal(), preserving
the raw variables for diagnostics. Update every MariaDB SELECT, CREATE USER,
GRANT, and SHOW GRANTS statement, including the referenced later statement
blocks, to interpolate only the escaped variables.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2e719fa1-b1a9-4152-b4e3-11d1013daa05

📥 Commits

Reviewing files that changed from the base of the PR and between b5a897d and edd7b09.

📒 Files selected for processing (1)
  • sp7_db_setup_check.sh

Comment thread sp7_db_setup_check.sh
Comment on lines +175 to +186
if [[ "$SAME_MASTER_AND_MIGRATOR" == true ]]; then
MIGRATOR_USER_HOST="${CLIENT_HOST:-}"
else
MIGRATOR_USER_HOST="${MIGRATOR_USER_HOST:-${CLIENT_HOST:-}}"
fi

if [[ "$SAME_MASTER_AND_APP" == true ]]; then
APP_USER_HOST="${CLIENT_HOST:-}"
elif [[ "$SAME_MIGRATOR_AND_APP" == true ]]; then
APP_USER_HOST="${MIGRATOR_USER_HOST:-}"
else
echo "Warning: Could not detect client host via USER(); will only create users for explicit *_HOST values."
APP_USER_HOST="${APP_USER_HOST:-${CLIENT_HOST:-}}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🔴 Critical | ⚡ Quick win

Escape account hosts before use in SQL.

MIGRATOR_USER_HOST and APP_USER_HOST can now come from environment variables. The script interpolates them into SQL literals without sql_string_literal(). An override containing a single quote can inject SQL that runs with MASTER_USER_NAME privileges.

Keep the raw values for diagnostics. Create escaped SQL-specific variables after host resolution. Use those variables in every SELECT, CREATE USER, GRANT, and SHOW GRANTS statement.

Proposed fix
 if [[ "$SAME_MASTER_AND_APP" == true ]]; then
   APP_USER_HOST="${CLIENT_HOST:-}"
 elif [[ "$SAME_MIGRATOR_AND_APP" == true ]]; then
   APP_USER_HOST="${MIGRATOR_USER_HOST:-}"
 else
   APP_USER_HOST="${APP_USER_HOST:-${CLIENT_HOST:-}}"
 fi
+
+SQL_MIGRATOR_USER_HOST="$(sql_string_literal "$MIGRATOR_USER_HOST")"
+SQL_APP_USER_HOST="$(sql_string_literal "$APP_USER_HOST")"
 
- "SELECT COUNT(*) FROM mysql.user WHERE user = '$SQL_MIGRATOR_NAME' AND host = '$MIGRATOR_USER_HOST';")
+ "SELECT COUNT(*) FROM mysql.user WHERE user = '$SQL_MIGRATOR_NAME' AND host = '$SQL_MIGRATOR_USER_HOST';")

Apply the same replacement to the other MariaDB statements.

Also applies to: 214-220, 236-249, 277-287, 317-327

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sp7_db_setup_check.sh` around lines 175 - 186, After resolving
MIGRATOR_USER_HOST and APP_USER_HOST, create separate SQL-escaped host variables
with sql_string_literal(), preserving the raw variables for diagnostics. Update
every MariaDB SELECT, CREATE USER, GRANT, and SHOW GRANTS statement, including
the referenced later statement blocks, to interpolate only the escaped
variables.

@github-project-automation github-project-automation Bot moved this from 📋Back Log to Dev Attention Needed in General Tester Board Aug 2, 2026
Triggered by edd7b09 on branch refs/heads/setup_script_hotfix
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Dev Attention Needed

Development

Successfully merging this pull request may close these issues.

3 participants