Skip to content

Commit 485b843

Browse files
committed
Fix SSL CA setup timing and QByteArray decode on macOS
- Decode QByteArray returned by trustedCaCertsPemText() to str before writing - Always replace the QGIS CA section in cert.pem instead of append-only, so stale certs from previous sessions are refreshed - Call setup_qgis_ssl_for_mergin_client() in initGui() where the auth manager is guaranteed to be ready, and also before each MerginClient creation in validate_mergin_url() and mergin_server_deprecated_version()
1 parent 05de699 commit 485b843

2 files changed

Lines changed: 20 additions & 19 deletions

File tree

Mergin/plugin.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@
6666
os.environ["MERGIN_CLIENT_LOG"] = MERGIN_CLIENT_LOG
6767

6868
try:
69+
# Best-effort early init; auth manager may not be ready yet so this may be a no-op.
70+
# The real call happens in initGui() and before each MerginClient creation.
6971
setup_qgis_ssl_for_mergin_client()
7072
except Exception:
7173
pass
@@ -119,6 +121,11 @@ def initGui(self):
119121

120122
self.initProcessing()
121123

124+
try:
125+
setup_qgis_ssl_for_mergin_client()
126+
except Exception:
127+
pass
128+
122129
if self.iface is not None:
123130
self.add_action(
124131
mm_symbol_path(),

Mergin/utils_auth.py

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ def validate_mergin_url(url):
444444
:param url: String Mergin Maps URL to ping.
445445
:return: String error message as result of validation. If None, URL is valid.
446446
"""
447+
setup_qgis_ssl_for_mergin_client()
447448
try:
448449
MerginClient(url, proxy_config=get_qgis_proxy_config(url))
449450

@@ -529,6 +530,7 @@ def set_qgsexpressionscontext(url: str, mc: typing.Optional[MerginClient] = None
529530

530531

531532
def mergin_server_deprecated_version(url: str) -> bool:
533+
setup_qgis_ssl_for_mergin_client()
532534
mc = MerginClient(
533535
url=url,
534536
auth_token=None,
@@ -567,24 +569,13 @@ def setup_qgis_ssl_for_mergin_client() -> None:
567569
2. On macOS, appends the QGIS CAs to MerginClient's bundled cert.pem
568570
so that the macOS fallback code path also trusts them.
569571
"""
570-
auth_manager = QgsApplication.authManager()
571-
ca_certs = auth_manager.trustedCaCertsCache()
572-
573-
if not ca_certs:
574-
return
572+
qgis_ca_pem = QgsApplication.authManager().trustedCaCertsPemText()
573+
if hasattr(qgis_ca_pem, "data"):
574+
qgis_ca_pem = qgis_ca_pem.data().decode("utf-8")
575575

576-
# Convert QSslCertificate objects to PEM text
577-
pem_blocks = []
578-
for cert in ca_certs:
579-
pem_data = bytes(cert.toPem()).decode("ascii")
580-
if pem_data:
581-
pem_blocks.append(pem_data)
582-
583-
if not pem_blocks:
576+
if not qgis_ca_pem:
584577
return
585578

586-
qgis_ca_pem = "\n".join(pem_blocks)
587-
588579
# 1. Write to a PEM file and set SSL_CERT_FILE
589580
settings_dir = QgsApplication.qgisSettingsDirPath()
590581
ca_file_path = os.path.join(settings_dir, "mergin-trusted-cas.pem")
@@ -601,10 +592,13 @@ def setup_qgis_ssl_for_mergin_client() -> None:
601592
marker = "# --- QGIS trusted CAs ---"
602593
with open(bundled_cert, "r") as f:
603594
existing = f.read()
604-
if marker not in existing:
605-
with open(bundled_cert, "a") as f:
606-
f.write(f"\n{marker}\n")
607-
f.write(qgis_ca_pem)
595+
# Always replace the QGIS section so stale CAs get refreshed
596+
if marker in existing:
597+
base_content = existing[: existing.index(marker)].rstrip()
598+
else:
599+
base_content = existing.rstrip()
600+
with open(bundled_cert, "w") as f:
601+
f.write(base_content + f"\n\n{marker}\n" + qgis_ca_pem)
608602

609603

610604
def qgis_support_sso() -> bool:

0 commit comments

Comments
 (0)