wopi: collaborate (#1591)

persistent file IDs for real-time collaboration
This commit is contained in:
Danila Kamaev 2026-08-15 17:06:45 +04:00 committed by GitHub
parent 92c3f32e13
commit efcf96e3e3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 6 additions and 3 deletions

View file

@ -1735,7 +1735,7 @@ def add_safety(ap):
ap2.add_argument("--use-bwrap", metavar="TXT", type=u, default="n", help=argparse.SUPPRESS)
def add_salt(ap, fk_salt, dk_salt, ah_salt):
def add_salt(ap, fk_salt, dk_salt, ah_salt, wopi_salt):
ap2 = ap.add_argument_group("salting options")
ap2.add_argument("--ah-alg", metavar="ALG", type=u, default="none", help="account-pw hashing algorithm; one of these, best to worst: \033[32margon2 scrypt sha2 none\033[0m (each optionally followed by alg-specific comma-sep. config)")
ap2.add_argument("--ah-salt", metavar="SALT", type=u, default=ah_salt, help="account-pw salt; ignored if \033[33m--ah-alg\033[0m is none (default)")
@ -1744,6 +1744,7 @@ def add_salt(ap, fk_salt, dk_salt, ah_salt):
ap2.add_argument("--fk-salt", metavar="SALT", type=u, default=fk_salt, help="per-file accesskey salt; used to generate unpredictable URLs for hidden files")
ap2.add_argument("--dk-salt", metavar="SALT", type=u, default=dk_salt, help="per-directory accesskey salt; used to generate unpredictable URLs to share folders with users who only have the 'get' permission")
ap2.add_argument("--warksalt", metavar="SALT", type=u, default="hunter2", help="up2k file-hash salt; serves no purpose, no reason to change this (but delete all databases if you do)")
ap2.add_argument("--wopi-salt", metavar="SALT", type=u, default=wopi_salt, help="WOPI file ID salt; used with \033[33m--wopi\033[0m to generate persistent yet unpredictable WOPI file IDs")
ap2.add_argument("--show-ah-salt", action="store_true", help="on startup, print the effective value of \033[33m--ah-salt\033[0m (the autogenerated value in $XDG_CONFIG_HOME unless otherwise specified)")
ap2.add_argument("--show-fk-salt", action="store_true", help="on startup, print the effective value of \033[33m--fk-salt\033[0m (the autogenerated value in $XDG_CONFIG_HOME unless otherwise specified)")
ap2.add_argument("--show-dk-salt", action="store_true", help="on startup, print the effective value of \033[33m--dk-salt\033[0m (the autogenerated value in $XDG_CONFIG_HOME unless otherwise specified)")
@ -2076,6 +2077,7 @@ def run_argparse(
fk_salt = get_salt("fk", 18)
dk_salt = get_salt("dk", 30)
ah_salt = get_salt("ah", 18)
wopi_salt = get_salt("wopi", 18)
# alpine peaks at 5 threads for some reason,
# all others scale past that (but try to avoid SMT),
@ -2112,7 +2114,7 @@ def run_argparse(
add_opds(ap)
add_wopi(ap)
add_safety(ap)
add_salt(ap, fk_salt, dk_salt, ah_salt)
add_salt(ap, fk_salt, dk_salt, ah_salt, wopi_salt)
add_optouts(ap)
add_shutdown(ap)
add_yolo(ap)

View file

@ -1649,7 +1649,8 @@ class HttpCli(object):
raise Pebkac(500, "too many wopi sessions")
if not found:
atoken = ub64enc(os.urandom(18)).decode("ascii") # 18 = 144b = 24c
file_id = ub64enc(os.urandom(15)).decode("ascii") # 15 = 120b = 20c
zb = (vpath + self.args.wopi_salt).encode("utf-8", "replace")
file_id = ub64enc(hashlib.sha512(zb).digest()[:15]).decode("ascii")
wopi_files[atoken] = session = {
"vp": vpath,
"uname": self.uname,