notifications: only render body with mentions if there is a body
Notifications for registering a user would pass body=None. It is unfortunate to pass None all the way to render_w_mentions - it seems fair enough that this function expects a str.
There are some odd characters (like \r and \n) that the Kallithea UI doesn't allow in filenames in repos. Kallithea (through the routes module) will fail to generate URLs when browsing Files. That is a known limitation with minimal real-world impact, non-trivial to work around or fix.
There are very few relevant use cases for tracking files with odd filenames. \t is valid but is hard to render in a meaningful way in the UI. And ASCII characters like \ and " are not usable on Windows and should just be avoided.
Kallithea would parse Git diffs with odd characers incorrectly or fail, even before hitting the known limitation. With this change, Kallithea will parse diffs with odd filenames correctly (and then hit the limitation).
Git will quote odd filenames and escape the odd characters when emitting diffs. (Mercurial does by design not allow \r and \n , and Mercurial will thus never have to quote file names in diffs.)
Quotes are already handled (and ignored). With this change, Kallithea will handle \ unescaping of \\ and \", the usual letters like \r and \n and \t, and octal numbers like \033 (for ESC) .
Filenames with \ and " will work perfectly (when not on Windows).
Filenames with \t and ESC will work fine, but without helpful display in the UI.
Filenames with \r and \n will still make the UI fail when trying to generate URLs.
Thanks to stypr of Flatt Security for raising this.
diff: improved handling of Git diffs with " quoting
Kallithea would intentionally and explicitly fail with an ugly exception when trying to parse Git diffs with quoted filenames.
Improve this by parsing quotes ... and ignore them, as long as they are matching. The content inside the quotes might be \-escaped ... but that could potentially also be the case without quoting. We will fix that later.
Adding some test cases that before would have failed to parse and raised an exception.
Thanks to stypr of Flatt Security for raising this.
front-end: use 'bin' path for node commands instead of '.bin'
license-checker is using relative paths for importing other modules - that worked fine when .bin/license-checker was a symlink, but not on filesystems without symlinks support:
git: make sure _check_url only accept the protocols accepted by is_valid_repo_uri
Avoid unnecessary flexibility, ambiguity, and complexity.
The file protocol was never used. But when cloning existing managed repos, is_valid_repo_url would be skipped and _check_url would be called with absolute paths.
repo_groups: fix select of parent group when adding repo group
h.select was passed a list of repo groups where group_id was integer, but parent_group in the request was a string - thus no match.
Do as in repos controller create_repository (and in error handling): leave it to htmlfill to patch up the generated HTML using defaults ... but make sure we always have a default.
repos: extra HTML escaping of repo and repo group names shown in DataTables
These names will already have been "slugged" and can thus not contain anything that can be used for any attack. But let's be explicitly safe and escape them anyway.
raw_name without escaping would cause XSS *if* it was possible to create unsafe repo names.
just_name must be escaped in order to make search work correctly - for example if searching for '<' ... *if* it was possible for names to contain that.
model: remove unused 'subject' parameter of NotificationModel.create()
The subject of emails is determined with EmailNotificationModel._subj_map, based on the notification type. The 'subject' parameter passed to NotificationModel.create is completely unused.
Remove this parameter and update its callers, removing code that is now no longer used.
model/comment: extract notification-related code into a separate method
Preparation for grouping with _get_notification_data next, and keeping clear separation between creating the comment itself, and creating the notification.
Problem introduced in 9a0c41175e66: When iterating the headers dict and setting "msg[key] = value", it wasn't replacing the header but performing add_header so we sometimes ended up with two From headers.
It is also a general problem that while the headers dict only can contain each key once, it can contain entries that only differ in casing and thus will fold to the same message header, making it possible to end up adding duplicate headers.
"msg.replace_header(key, value)" is not a simple solution to the problem: it will raise KeyError if no such previous key exists.
Now, make the problem more clear by explicitly using add_header.
Avoid the duplication problem by deleting the key (no matter which casing) before invoking add_header. Delete promises that "No exception is raised if the named field isn’t present in the headers".
front-end: use 'bin' path for node commands instead of '.bin'
license-checker is using relative paths for importing other modueles - that worked fine when .bin/license-checker was a symlink, but not on filesystems without symlinks support:
hooks: move the vcs hook entry points and setup code out of lib
Mercurial hooks are running in a process that already has been initialized, so they invoke the hooks lib directly. Git hooks are binaries and need a lot of initialization before they can do the same. Move this extra setup code elsewhere.
Having this high level code in bin is perhaps also not ideal, but it also doesn't seem that bad: that is where other command line entry points invoke make_app.
(It seems like it could be adventageous to somehow use "real" bin commands for hooks ... but for now we use the home-made templates.)
Note: As a side effect of this change, all git hooks *must* be re-installed when upgrading.
git: detect existing symlink hooks before overwriting - only update plain files
If the existing hook is a symlink, the hook is not what we put in place, and we should stay away - no matter if it points at something that looks like a Kallithea hook.
*If* there should be circular dependencies, importing 'from' another module could fail because the module at that time only was partially imported. That had to be worked around by importing at runtime instead of globally.
Instead, try to always import whole modules. (But we should still try to avoid cycles.)
It might be a good idea, but then we should use it much more consistently ... and it should probably be done differently. Let's keep it simple and be consistent.
lib: move locale.py to locales.py to avoid shadowing of standard module
"Fix" spurious problem, seen for example as:
$ python kallithea/lib/annotate.py Traceback (most recent call last): File ".../lib64/python3.8/site-packages/mercurial/encoding.py", line 107, in <module> encoding = locale.getpreferredencoding().encode('ascii') or b'ascii' AttributeError: module 'locale' has no attribute 'getpreferredencoding'
That happened when something in some other module tried to import stdlib locale ... but somehow would pick up the kallithea locale module and things would fail.
Stay out of that kind of trouble by using a name that doesn't collide.
diffs: remove unused argument enable_comments and class no-comment
enable_comments was only used to set/not-set the 'no-comment' CSS class. While this class was emitted, no CSS rule nor any JavaScript logic was actually using it. Last real usage of that class was removed with commit e87baa8f1c5bd2488aefc23b95c0db3a04bc8431.
Cleanup the code by not emitting 'no-comment' and remove the 'enable_comments' flag.
style: mark failed comment submissions with red panel heading
Make it more obvious to the user that a comment submission failed: mark the panel of the failed comment as "panel-danger" so the color of the comment panel heading changes to red.
Previously, only the user and comment text would fade a bit.