Skip to content

Commit 21fd17a

Browse files
refactor: Refactored _write_zuliprc to create zulip_key.
1 parent 23a773c commit 21fd17a

File tree

2 files changed

+35
-10
lines changed

2 files changed

+35
-10
lines changed

zulipterminal/cli/run.py

+34-9
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import argparse
66
import configparser
7+
import contextlib
78
import logging
89
import os
910
import stat
@@ -311,36 +312,60 @@ def fetch_zuliprc(zuliprc_path: str) -> None:
311312
print(in_color("red", "\nIncorrect Email(or Username) or Password!\n"))
312313
login_data = get_api_key(realm_url)
313314

315+
zulip_key_path = os.path.join(
316+
os.path.dirname(os.path.abspath(zuliprc_path)), "zulip_key"
317+
)
318+
314319
preferred_realm_url, login_id, api_key = login_data
315320
save_zuliprc_failure = _write_zuliprc(
316-
zuliprc_path,
317-
login_id=login_id,
321+
to_path=zuliprc_path,
322+
key_path=zulip_key_path,
318323
api_key=api_key,
324+
login_id=login_id,
319325
server_url=preferred_realm_url,
320326
)
321327
if not save_zuliprc_failure:
322-
print(f"Generated API key saved at {zuliprc_path}")
328+
print(f"Generated config file saved at {zuliprc_path}")
323329
else:
324330
exit_with_error(save_zuliprc_failure)
325331

326332

327333
def _write_zuliprc(
328-
to_path: str, *, login_id: str, api_key: str, server_url: str
334+
to_path: str, *, key_path: str, login_id: str, api_key: str, server_url: str
329335
) -> str:
330336
"""
331-
Writes a zuliprc file, returning a non-empty error string on failure
332-
Only creates new private files; errors if file already exists
337+
Writes both zuliprc and zulip_key files securely.
338+
Ensures atomicity: if one file fails to write, cleans up the other.
339+
Returns an empty string on success, or a descriptive error message on failure.
333340
"""
341+
zuliprc_created = False
342+
334343
try:
344+
# Write zuliprc
335345
with open(
336346
os.open(to_path, os.O_CREAT | os.O_WRONLY | os.O_EXCL, 0o600), "w"
337347
) as f:
338-
f.write(f"[api]\nemail={login_id}\nkey={api_key}\nsite={server_url}")
348+
f.write(
349+
f"[api]\nemail={login_id}\npasscmd=cat zulip_key\nsite={server_url}"
350+
)
351+
zuliprc_created = True
352+
# Write zulip_key
353+
with open(
354+
os.open(key_path, os.O_CREAT | os.O_WRONLY | os.O_EXCL, 0o600), "w"
355+
) as f:
356+
f.write(api_key)
357+
339358
return ""
359+
340360
except FileExistsError:
341-
return f"zuliprc already exists at {to_path}"
361+
filename = to_path if not zuliprc_created else key_path
362+
return f"FileExistsError: {filename} already exists"
342363
except OSError as ex:
343-
return f"{ex.__class__.__name__}: zuliprc could not be created at {to_path}"
364+
if zuliprc_created:
365+
with contextlib.suppress(Exception):
366+
os.remove(to_path)
367+
filename = key_path if zuliprc_created else to_path
368+
return f"{ex.__class__.__name__}: could not create {filename} ({ex})"
344369

345370

346371
def parse_zuliprc(zuliprc_str: str) -> Dict[str, SettingData]:

zulipterminal/core.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -745,4 +745,4 @@ def main(self) -> None:
745745

746746
finally:
747747
self.restore_stdout()
748-
self.loop.screen.tty_signal_keys(*old_signal_list)
748+
self.loop.screen.tty_signal_keys(*old_signal_list)

0 commit comments

Comments
 (0)