Merge pull request #1747 from pbiering/hook-ext-path-upload-file

Hook extension for path of uploaded file
This commit is contained in:
Peter Bieringer 2025-03-27 08:39:45 +01:00 committed by GitHub
commit c91b8e49d5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 24 additions and 8 deletions

View file

@ -4,6 +4,7 @@
* Fix: auth/htpasswd related to detection and use of bcrypt
* Add: option [auth] ldap_ignore_attribute_create_modify_timestamp for support of Authentik LDAP server
* Extend: [storage] hook supports now placeholder for "cwd" and "path" (and catches unsupported placeholders)
## 3.5.0

View file

@ -1334,7 +1334,9 @@ Command that is run after changes to storage. Take a look at the
Default:
Supported placeholders:
- `%(user)`: logged-in user
- `%(user)s`: logged-in user
- `%(cwd)s`: current working directory _(>= 3.5.1)_
- `%(path)s`: full path of item _(>= 3.5.1)_
Command will be executed with base directory defined in `filesystem_folder` (see above)

7
config
View file

@ -223,10 +223,13 @@
# Command that is run after changes to storage, default is emtpy
# Supported placeholders:
# %(user): logged-in user
# %(user)s: logged-in user
# %(cwd)s : current working directory
# %(path)s: full path of item
# Command will be executed with base directory defined in filesystem_folder
# For "git" check DOCUMENTATION.md for bootstrap instructions
# Example: git add -A && (git diff --cached --quiet || git commit -m "Changes by \"%(user)s\"")
# Example(test): echo \"user=%(user)s path=%(path)s cwd=%(cwd)s\"
# Example(git): git add -A && (git diff --cached --quiet || git commit -m "Changes by \"%(user)s\"")
#hook =
# Create predefined user collections

View file

@ -165,7 +165,7 @@ class ApplicationPartPut(ApplicationBase):
bool(rights.intersect(access.permissions, "Ww")),
bool(rights.intersect(access.parent_permissions, "w")))
with self._storage.acquire_lock("w", user):
with self._storage.acquire_lock("w", user, path=path):
item = next(iter(self._storage.discover(path)), None)
parent_item = next(iter(
self._storage.discover(access.parent_path)), None)

View file

@ -1,7 +1,8 @@
# This file is part of Radicale - CalDAV and CardDAV server
# Copyright © 2014 Jean-Marc Martins
# Copyright © 2012-2017 Guillaume Ayoub
# Copyright © 2017-2019 Unrud <unrud@outlook.com>
# Copyright © 2017-2022 Unrud <unrud@outlook.com>
# Copyright © 2023-2025 Peter Bieringer <pb@bieringer.de>
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -58,7 +59,7 @@ class StoragePartLock(StorageBase):
self._hook = configuration.get("storage", "hook")
@types.contextmanager
def acquire_lock(self, mode: str, user: str = "") -> Iterator[None]:
def acquire_lock(self, mode: str, user: str = "", *args, **kwargs) -> Iterator[None]:
with self._lock.acquire(mode):
yield
# execute hook
@ -73,8 +74,17 @@ class StoragePartLock(StorageBase):
else:
# Process group is also used to identify child processes
preexec_fn = os.setpgrp
command = self._hook % {
"user": shlex.quote(user or "Anonymous")}
# optional argument
path = kwargs.get('path', "")
try:
command = self._hook % {
"path": shlex.quote(self._get_collection_root_folder() + path),
"cwd": shlex.quote(self._filesystem_folder),
"user": shlex.quote(user or "Anonymous")}
except KeyError as e:
logger.error("Storage hook contains not supported placeholder %s (skip execution of: %r)" % (e, self._hook))
return
logger.debug("Executing storage hook: '%s'" % command)
try:
p = subprocess.Popen(