Sanitize Helpdesk mail settings for all projects
This commit is contained in:
@@ -242,7 +242,8 @@ The worker processing policy is documented in:
|
||||
### 7. Test Helpdesk Mail Reset
|
||||
|
||||
After importing a production database into the LAN test instance, reset all
|
||||
Helpdesk-enabled projects to use the local Mailpit test mailbox with:
|
||||
active projects to use the local Mailpit test mailbox for Helpdesk settings
|
||||
with:
|
||||
|
||||
- [reset_helpdesk_mail_settings.py](/home/iadnah/redmine/reset_helpdesk_mail_settings.py:1)
|
||||
|
||||
|
||||
@@ -32,6 +32,27 @@ environment. Before risky edits, archive the current plugin directories in
|
||||
- Run `validate_helpdesk_outbox_worker.py` after outbox or worker changes,
|
||||
then choose the external index target.
|
||||
|
||||
## 2026-04-25 - Test Helpdesk Credential Sanitization
|
||||
|
||||
- Touched areas:
|
||||
- Test instance post-import tooling
|
||||
- Post-import validation
|
||||
- Purpose:
|
||||
- Ensure production database imports cannot leave real Helpdesk POP3/SMTP
|
||||
credentials on projects where Helpdesk is disabled but settings rows still
|
||||
exist.
|
||||
- Behavior changed:
|
||||
- `reset_helpdesk_mail_settings.py` now rewrites Helpdesk mail settings for
|
||||
every active project, not only projects with `contacts_helpdesk` enabled.
|
||||
- `validate_test_instance.py` checks every active project for Mailpit
|
||||
Helpdesk settings.
|
||||
- LAN test result:
|
||||
- `./reset_helpdesk_mail_settings.py --dry-run` matched 52 active projects.
|
||||
- `./reset_helpdesk_mail_settings.py` updated 1,092 setting rows across 52
|
||||
active projects.
|
||||
- `./validate_test_instance.py` passed and reported 52 active projects with
|
||||
matching Mailpit Helpdesk settings.
|
||||
|
||||
## 2026-04-25 - Outbox Worker Processing Policy
|
||||
|
||||
- Touched areas:
|
||||
|
||||
@@ -69,8 +69,10 @@ Apply:
|
||||
./reset_helpdesk_mail_settings.py
|
||||
```
|
||||
|
||||
This rewrites all active `contacts_helpdesk` projects to use Mailpit for POP3
|
||||
and SMTP. Passwords are written but not printed.
|
||||
This rewrites all active projects to use Mailpit for Helpdesk POP3 and SMTP,
|
||||
even if the Helpdesk module is currently disabled for a project. That prevents
|
||||
imported real mail credentials from being used accidentally in the test
|
||||
instance. Passwords are written but not printed.
|
||||
|
||||
## 4. Restart Passenger
|
||||
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
"""Reset RedmineUP Helpdesk mail settings on the LAN test Redmine instance.
|
||||
|
||||
This is intended to be run after importing a production database into the test
|
||||
instance. It finds projects with the Helpdesk module enabled and rewrites only
|
||||
the incoming/outgoing mail settings so test mail flows through Mailpit.
|
||||
instance. It rewrites every active project's incoming/outgoing Helpdesk mail
|
||||
settings so test mail flows through Mailpit and imported real credentials cannot
|
||||
be used accidentally.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -113,7 +114,7 @@ class RemoteRedmine:
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Reset Helpdesk mail settings for projects with the contacts_helpdesk module enabled."
|
||||
description="Reset Helpdesk mail settings for all active projects."
|
||||
)
|
||||
parser.add_argument("--ssh-host", default=os.getenv("REDMINE_SSH_HOST", DEFAULT_SSH_HOST))
|
||||
parser.add_argument("--ssh-key", type=Path, default=Path(os.getenv("REDMINE_SSH_KEY", str(DEFAULT_SSH_KEY))))
|
||||
@@ -141,12 +142,12 @@ def main() -> int:
|
||||
remote = RemoteRedmine(args.ssh_host, args.ssh_key, args.remote_redmine)
|
||||
|
||||
try:
|
||||
projects = find_helpdesk_projects(remote, args.project)
|
||||
projects = find_active_projects(remote, args.project)
|
||||
if not projects:
|
||||
print("No active projects with contacts_helpdesk enabled matched the requested filters.")
|
||||
print("No active projects matched the requested filters.")
|
||||
return 0
|
||||
|
||||
print(f"Matched {len(projects)} Helpdesk-enabled project(s):")
|
||||
print(f"Matched {len(projects)} active project(s):")
|
||||
for project in projects:
|
||||
print(f" - #{project['id']} {project['identifier']} ({project['name']})")
|
||||
|
||||
@@ -165,7 +166,7 @@ def main() -> int:
|
||||
return 1
|
||||
|
||||
|
||||
def find_helpdesk_projects(remote: RemoteRedmine, filters: list[str]) -> list[dict[str, Any]]:
|
||||
def find_active_projects(remote: RemoteRedmine, filters: list[str]) -> list[dict[str, Any]]:
|
||||
where = ["p.status = 1"]
|
||||
if filters:
|
||||
clauses = []
|
||||
@@ -183,9 +184,6 @@ SELECT HEX(CAST(JSON_OBJECT(
|
||||
'name', p.name
|
||||
) AS CHAR)) AS document
|
||||
FROM projects p
|
||||
JOIN enabled_modules em
|
||||
ON em.project_id = p.id
|
||||
AND em.name = 'contacts_helpdesk'
|
||||
WHERE {' AND '.join(where)}
|
||||
ORDER BY p.identifier;
|
||||
"""
|
||||
|
||||
@@ -231,7 +231,7 @@ ORDER BY identifier;
|
||||
if failures:
|
||||
results.append(CheckResult("FAIL", "Helpdesk Mailpit settings", "; ".join(failures[:8])))
|
||||
else:
|
||||
results.append(CheckResult("OK", "Helpdesk Mailpit settings", f"{len(settings_rows)} project(s) match"))
|
||||
results.append(CheckResult("OK", "Helpdesk Mailpit settings", f"{len(settings_rows)} active project(s) match"))
|
||||
except Exception as exc:
|
||||
results.append(CheckResult("FAIL", "Database checks", f"{exc.__class__.__name__}: {exc}"))
|
||||
return results
|
||||
@@ -257,7 +257,6 @@ SELECT HEX(CAST(JSON_OBJECT(
|
||||
'smtp_tls', MAX(CASE WHEN cs.name = 'helpdesk_smtp_tls' THEN cs.value END)
|
||||
) AS CHAR)) AS document
|
||||
FROM projects p
|
||||
JOIN enabled_modules em ON em.project_id = p.id AND em.name = 'contacts_helpdesk'
|
||||
LEFT JOIN contacts_settings cs ON cs.project_id = p.id
|
||||
WHERE p.status = 1
|
||||
GROUP BY p.id, p.identifier
|
||||
|
||||
Reference in New Issue
Block a user