-
-
Notifications
You must be signed in to change notification settings - Fork 51
fix: multiple bug fixes across chatmaild and cmdeploy #836
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
FileEntry namedtuple has (path, mtime, size), not relpath. Crashes with AttributeError when --mdir flag is used.
Bare return yielded None, causing TypeError on tuple unpacking in perform_initial_checks on fresh servers without DKIM keys.
Exception in _build_webpages was silently caught, returning None. rsync then received "None/" as source path, silently breaking deploy.
check_call always returns 0 or raises, making retcode!=0 branches unreachable. Also remote_data was undefined with --skip-dns-check.
doveadm output ends with empty line, parts=[] causes parts[2] crash.
Per Python docs, secrets module should be used for security-sensitive data. random.choices uses Mersenne Twister PRNG which is predictable. secrets.choice was already used for password generation in the same file.
TLS 1.0/1.1 deprecated by RFC 8996. Nginx default is TLSv1.2 TLSv1.3. Aligns with postfix (>=TLSv1.2) and dovecot (TLSv1.3) in the same stack.
- Reject localparts with chars outside [a-z0-9._-] to prevent filesystem issues from crafted usernames via IMAP/SMTP auth - Use filelock to serialize concurrent account creation for same address, preventing TOCTOU race where two threads both create an account and last writer wins
Hung TURN daemon would block dict proxy handler thread indefinitely. Per Python docs, settimeout() raises TimeoutError on expiry.
ConnectionRefusedError/FileNotFoundError/TimeoutError from turn_credentials() would kill the dict proxy connection. Return N (not found) response instead and log the error.
- test_doveauth: invalid localpart chars rejected, concurrent same-account creation - test_expire: --mdir filtering uses msg.path correctly - test_metadata: TURN exception returns N\n, success returns credentials - test_turnserver: socket timeout, connection refused, happy path - test_dns: get_dkim_entry returns (None, None) on CalledProcessError - test_rshell: dovecot_recalc_quota handles empty/malformed output
|
Thanks for this giant PR! I will create a separate branch so the CI can deploy it to our test servers. Usually we like to have one PR per change, so we can decide about them individually^^ let's see, if all of it is uncontroversial, it's probably fine, and at least the commits are properly separated :) I will take a look at your commits later today (or latest, on Tuesday). |
missytake
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, it's really an impressive list of fixes! And thank you especially for adding tests, nice.
| assert result == (None, None) | ||
| assert result[0] is None and result[1] is None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of interest: Is there a scenario in which the first statement passes and the second doesn't?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess I overlooked it... Of course, you're right — it's redundant. None is a singleton so == None and is None are equivalent. Removed in the next push.
None is a singleton; == already covers is None check.
- Handle filelock.Timeout gracefully in lookup_passdb: return N (not found) instead of killing the entire dict connection - Remove unused call_count variables from test_rshell.py
|
Two follow-up fixes based on self-review:
|
Summary
Bug fixes (round 1)
AttributeError—FileEntryhaspath, notrelpath. Crashes when--mdirflag is usedTypeError—get_dkim_entryreturns bareNoneinstead of(None, None)tuple onCalledProcessError, crashingcmdeploy dnson fresh serversbuild_webpagesreturnsNoneon exception, causingrsync("None/", ...)NameErrorinrun_cmd—check_callalways returns 0 or raises, makingretcode != 0branches unreachable;remote_dataundefined with--skip-dns-checkIndexErrorindovecot_recalc_quota— empty line at end ofdoveadmoutput producesparts=[]Security fixes (round 2)
secrets.choiceinstead ofrandom.choicesfor username generation — per Python docs,secretsshould be used for security-sensitive data[a-z0-9._-]— prevents filesystem issues from crafted usernames via IMAP/SMTP authfilelockto serialize concurrent creation for same addressturn_credentials()exceptions — returnN(not found) instead of crashing the dict proxy connectionFormatting
Test plan
pytest chatmaild/src/— 50 passedpytest cmdeploy/src/cmdeploy/tests/ --ignore=online— 16 passedruff check+ruff format --checkon all changed Python files — clean