copyparty 1.18.6__tar.gz → 1.18.8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {copyparty-1.18.6 → copyparty-1.18.8}/PKG-INFO +23 -1
- {copyparty-1.18.6 → copyparty-1.18.8}/README.md +22 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/__main__.py +5 -3
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/__version__.py +2 -2
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/authsrv.py +37 -2
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/bos/bos.py +14 -3
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/cfg.py +4 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/ftpd.py +4 -4
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/httpcli.py +71 -53
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/smbd.py +1 -1
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/svchub.py +3 -3
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/tftpd.py +6 -3
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/th_srv.py +2 -2
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/up2k.py +10 -7
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/util.py +60 -22
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/browser.html +2 -2
- copyparty-1.18.8/copyparty/web/browser.js.gz +0 -0
- copyparty-1.18.8/copyparty/web/shares.js.gz +0 -0
- copyparty-1.18.8/copyparty/web/splash.js.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/svcs.html +15 -3
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty.egg-info/PKG-INFO +23 -1
- copyparty-1.18.6/copyparty/web/browser.js.gz +0 -0
- copyparty-1.18.6/copyparty/web/shares.js.gz +0 -0
- copyparty-1.18.6/copyparty/web/splash.js.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/LICENSE +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/__init__.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/bos/__init__.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/bos/path.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/broker_mp.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/broker_mpw.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/broker_thr.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/broker_util.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/cert.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/dxml.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/fsutil.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/httpconn.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/httpsrv.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/ico.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/mdns.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/metrics.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/mtag.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/multicast.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/pwhash.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/res/COPYING.txt +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/res/__init__.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/res/insecure.pem +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/ssdp.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/star.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/stolen/__init__.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/stolen/dnslib/__init__.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/stolen/dnslib/bimap.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/stolen/dnslib/bit.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/stolen/dnslib/buffer.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/stolen/dnslib/dns.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/stolen/dnslib/label.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/stolen/dnslib/lex.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/stolen/dnslib/ranges.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/stolen/ifaddr/__init__.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/stolen/ifaddr/_posix.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/stolen/ifaddr/_shared.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/stolen/ifaddr/_win32.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/stolen/qrcodegen.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/stolen/surrogateescape.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/sutil.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/szip.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/tcpsrv.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/th_cli.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/u2idx.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/a/__init__.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/a/partyfuse.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/a/u2c.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/a/webdav-cfg.bat +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/baguettebox.js.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/browser.css.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/browser2.html +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/cf.html +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/dbg-audio.js.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/dd/2.png +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/dd/3.png +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/dd/4.png +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/dd/5.png +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/dd/__init__.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/deps/__init__.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/deps/busy.mp3.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/deps/easymde.css.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/deps/easymde.js.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/deps/fuse.py +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/deps/marked.js.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/deps/mini-fa.css.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/deps/mini-fa.woff +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/deps/prism.css.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/deps/prism.js.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/deps/prismd.css.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/deps/scp.woff2 +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/deps/sha512.ac.js.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/deps/sha512.hw.js.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/idp.html +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/md.css.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/md.html +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/md.js.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/md2.css.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/md2.js.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/mde.css.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/mde.html +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/mde.js.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/msg.css.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/msg.html +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/rups.css.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/rups.html +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/rups.js.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/shares.css.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/shares.html +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/splash.css.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/splash.html +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/svcs.js.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/ui.css.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/up2k.js.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/util.js.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty/web/w.hash.js.gz +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty.egg-info/SOURCES.txt +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty.egg-info/dependency_links.txt +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty.egg-info/entry_points.txt +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty.egg-info/requires.txt +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/copyparty.egg-info/top_level.txt +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/pyproject.toml +0 -0
- {copyparty-1.18.6 → copyparty-1.18.8}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: copyparty
|
3
|
-
Version: 1.18.
|
3
|
+
Version: 1.18.8
|
4
4
|
Summary: Portable file server with accelerated resumable uploads, deduplication, WebDAV, FTP, zeroconf, media indexer, video thumbnails, audio transcoding, and write-only folders
|
5
5
|
Author-email: ed <copyparty@ocv.me>
|
6
6
|
License: MIT
|
@@ -138,6 +138,7 @@ made in Norway 🇳🇴
|
|
138
138
|
* [periodic rescan](#periodic-rescan) - filesystem monitoring
|
139
139
|
* [upload rules](#upload-rules) - set upload rules using volflags
|
140
140
|
* [compress uploads](#compress-uploads) - files can be autocompressed on upload
|
141
|
+
* [chmod and chown](#chmod-and-chown) - per-volume filesystem-permissions and ownership
|
141
142
|
* [other flags](#other-flags)
|
142
143
|
* [database location](#database-location) - in-volume (`.hist/up2k.db`, default) or somewhere else
|
143
144
|
* [metadata from audio files](#metadata-from-audio-files) - set `-e2t` to index tags on upload
|
@@ -1707,6 +1708,26 @@ some examples,
|
|
1707
1708
|
allows (but does not force) gz compression if client uploads to `/inc?pk` or `/inc?gz` or `/inc?gz=4`
|
1708
1709
|
|
1709
1710
|
|
1711
|
+
## chmod and chown
|
1712
|
+
|
1713
|
+
per-volume filesystem-permissions and ownership
|
1714
|
+
|
1715
|
+
by default:
|
1716
|
+
* all folders are chmod 755
|
1717
|
+
* files are usually chmod 644 (umask-defined)
|
1718
|
+
* user/group is whatever copyparty is running as
|
1719
|
+
|
1720
|
+
this can be configured per-volume:
|
1721
|
+
* volflag `chmod_f` sets file permissions; default=`644` (usually)
|
1722
|
+
* volflag `chmod_d` sets directory permissions; default=`755`
|
1723
|
+
* volflag `uid` sets the owner user-id
|
1724
|
+
* volflag `gid` sets the owner group-id
|
1725
|
+
|
1726
|
+
notes:
|
1727
|
+
* `gid` can only be set to one of the groups which the copyparty process is a member of
|
1728
|
+
* `uid` can only be set if copyparty is running as root (i appreciate your faith)
|
1729
|
+
|
1730
|
+
|
1710
1731
|
## other flags
|
1711
1732
|
|
1712
1733
|
* `:c,magic` enables filetype detection for nameless uploads, same as `--magic`
|
@@ -2284,6 +2305,7 @@ force-enable features with known issues on your OS/env by setting any of the fo
|
|
2284
2305
|
| env-var | what it does |
|
2285
2306
|
| ------------------------ | ------------ |
|
2286
2307
|
| `PRTY_FORCE_MP` | force-enable multiprocessing (real multithreading) on MacOS and other broken platforms |
|
2308
|
+
| `PRTY_FORCE_MAGIC` | use [magic](https://pypi.org/project/python-magic/) on Windows (you will segfault) |
|
2287
2309
|
|
2288
2310
|
|
2289
2311
|
# packages
|
@@ -80,6 +80,7 @@ made in Norway 🇳🇴
|
|
80
80
|
* [periodic rescan](#periodic-rescan) - filesystem monitoring
|
81
81
|
* [upload rules](#upload-rules) - set upload rules using volflags
|
82
82
|
* [compress uploads](#compress-uploads) - files can be autocompressed on upload
|
83
|
+
* [chmod and chown](#chmod-and-chown) - per-volume filesystem-permissions and ownership
|
83
84
|
* [other flags](#other-flags)
|
84
85
|
* [database location](#database-location) - in-volume (`.hist/up2k.db`, default) or somewhere else
|
85
86
|
* [metadata from audio files](#metadata-from-audio-files) - set `-e2t` to index tags on upload
|
@@ -1649,6 +1650,26 @@ some examples,
|
|
1649
1650
|
allows (but does not force) gz compression if client uploads to `/inc?pk` or `/inc?gz` or `/inc?gz=4`
|
1650
1651
|
|
1651
1652
|
|
1653
|
+
## chmod and chown
|
1654
|
+
|
1655
|
+
per-volume filesystem-permissions and ownership
|
1656
|
+
|
1657
|
+
by default:
|
1658
|
+
* all folders are chmod 755
|
1659
|
+
* files are usually chmod 644 (umask-defined)
|
1660
|
+
* user/group is whatever copyparty is running as
|
1661
|
+
|
1662
|
+
this can be configured per-volume:
|
1663
|
+
* volflag `chmod_f` sets file permissions; default=`644` (usually)
|
1664
|
+
* volflag `chmod_d` sets directory permissions; default=`755`
|
1665
|
+
* volflag `uid` sets the owner user-id
|
1666
|
+
* volflag `gid` sets the owner group-id
|
1667
|
+
|
1668
|
+
notes:
|
1669
|
+
* `gid` can only be set to one of the groups which the copyparty process is a member of
|
1670
|
+
* `uid` can only be set if copyparty is running as root (i appreciate your faith)
|
1671
|
+
|
1672
|
+
|
1652
1673
|
## other flags
|
1653
1674
|
|
1654
1675
|
* `:c,magic` enables filetype detection for nameless uploads, same as `--magic`
|
@@ -2226,6 +2247,7 @@ force-enable features with known issues on your OS/env by setting any of the fo
|
|
2226
2247
|
| env-var | what it does |
|
2227
2248
|
| ------------------------ | ------------ |
|
2228
2249
|
| `PRTY_FORCE_MP` | force-enable multiprocessing (real multithreading) on MacOS and other broken platforms |
|
2250
|
+
| `PRTY_FORCE_MAGIC` | use [magic](https://pypi.org/project/python-magic/) on Windows (you will segfault) |
|
2229
2251
|
|
2230
2252
|
|
2231
2253
|
# packages
|
@@ -53,13 +53,13 @@ from .util import (
|
|
53
53
|
PYFTPD_VER,
|
54
54
|
RAM_AVAIL,
|
55
55
|
RAM_TOTAL,
|
56
|
+
RE_ANSI,
|
56
57
|
SQLITE_VER,
|
57
58
|
UNPLICATIONS,
|
58
59
|
URL_BUG,
|
59
60
|
URL_PRJ,
|
60
61
|
Daemon,
|
61
62
|
align_tab,
|
62
|
-
ansi_re,
|
63
63
|
b64enc,
|
64
64
|
dedent,
|
65
65
|
has_resource,
|
@@ -161,7 +161,7 @@ def lprint(*a , **ka ) :
|
|
161
161
|
txt = " ".join(unicode(x) for x in a) + eol
|
162
162
|
printed.append(txt)
|
163
163
|
if not VT100:
|
164
|
-
txt =
|
164
|
+
txt = RE_ANSI.sub("", txt)
|
165
165
|
|
166
166
|
print(txt, end="", **ka)
|
167
167
|
|
@@ -1045,6 +1045,8 @@ def add_upload(ap):
|
|
1045
1045
|
ap2.add_argument("--use-fpool", action="store_true", help="force file-handle pooling, even when it might be dangerous (multiprocessing, filesystems lacking sparse-files support, ...)")
|
1046
1046
|
ap2.add_argument("--chmod-f", metavar="UGO", type=u, default="", help="unix file permissions to use when creating files; default is probably 644 (OS-decided), see --help-chmod. Examples: [\033[32m644\033[0m] = owner-RW + all-R, [\033[32m755\033[0m] = owner-RWX + all-RX, [\033[32m777\033[0m] = full-yolo (volflag=chmod_f)")
|
1047
1047
|
ap2.add_argument("--chmod-d", metavar="UGO", type=u, default="755", help="unix file permissions to use when creating directories; see --help-chmod. Examples: [\033[32m755\033[0m] = owner-RW + all-R, [\033[32m777\033[0m] = full-yolo (volflag=chmod_d)")
|
1048
|
+
ap2.add_argument("--uid", metavar="N", type=int, default=-1, help="unix user-id to chown new files/folders to; default = -1 = do-not-change (volflag=uid)")
|
1049
|
+
ap2.add_argument("--gid", metavar="N", type=int, default=-1, help="unix group-id to chown new files/folders to; default = -1 = do-not-change (volflag=gid)")
|
1048
1050
|
ap2.add_argument("--dedup", action="store_true", help="enable symlink-based upload deduplication (volflag=dedup)")
|
1049
1051
|
ap2.add_argument("--safe-dedup", metavar="N", type=int, default=50, help="how careful to be when deduplicating files; [\033[32m1\033[0m] = just verify the filesize, [\033[32m50\033[0m] = verify file contents have not been altered (volflag=safededup)")
|
1050
1052
|
ap2.add_argument("--hardlink", action="store_true", help="enable hardlink-based dedup; will fallback on symlinks when that is impossible (across filesystems) (volflag=hardlink)")
|
@@ -1547,7 +1549,7 @@ def add_ui(ap, retry):
|
|
1547
1549
|
ap2.add_argument("--hsortn", metavar="N", type=int, default=2, help="number of sorting rules to include in media URLs by default (volflag=hsortn)")
|
1548
1550
|
ap2.add_argument("--see-dots", action="store_true", help="default-enable seeing dotfiles; only takes effect if user has the necessary permissions")
|
1549
1551
|
ap2.add_argument("--qdel", metavar="LVL", type=int, default=2, help="number of confirmations to show when deleting files (2/1/0)")
|
1550
|
-
ap2.add_argument("--unlist", metavar="REGEX", type=u, default="", help="don't show files matching \033[33mREGEX\033[0m in file list. Purely cosmetic! Does not affect API calls, just the browser. Example: [\033[32m\\.(js|css)$\033[0m] (volflag=unlist)")
|
1552
|
+
ap2.add_argument("--unlist", metavar="REGEX", type=u, default="", help="don't show files/folders matching \033[33mREGEX\033[0m in file list. WARNING: Purely cosmetic! Does not affect API calls, just the browser. Example: [\033[32m\\.(js|css)$\033[0m] (volflag=unlist)")
|
1551
1553
|
ap2.add_argument("--favico", metavar="TXT", type=u, default="c 000 none" if retry else "🎉 000 none", help="\033[33mfavicon-text\033[0m [ \033[33mforeground\033[0m [ \033[33mbackground\033[0m ] ], set blank to disable")
|
1552
1554
|
ap2.add_argument("--ext-th", metavar="E=VP", type=u, action="append", help="use thumbnail-image \033[33mVP\033[0m for file-extension \033[33mE\033[0m, example: [\033[32mexe=/.res/exe.png\033[0m] (volflag=ext_th)")
|
1553
1555
|
ap2.add_argument("--mpmc", metavar="URL", type=u, default="", help="change the mediaplayer-toggle mouse cursor; URL to a folder with {2..5}.png inside (or disable with [\033[32m.\033[0m])")
|
@@ -33,6 +33,7 @@ from .util import (
|
|
33
33
|
afsenc,
|
34
34
|
get_df,
|
35
35
|
humansize,
|
36
|
+
json_hesc,
|
36
37
|
min_ex,
|
37
38
|
odfusion,
|
38
39
|
read_utf8,
|
@@ -63,6 +64,25 @@ if PY2:
|
|
63
64
|
|
64
65
|
|
65
66
|
LEELOO_DALLAS = "leeloo_dallas"
|
67
|
+
##
|
68
|
+
## you might be curious what Leeloo Dallas is doing here, so let me explain:
|
69
|
+
##
|
70
|
+
## certain daemonic tasks, namely:
|
71
|
+
## * deletion of expired files, running on a timer
|
72
|
+
## * deletion of sidecar files, initiated by plugins
|
73
|
+
## need to skip the usual permission-checks to do their thing,
|
74
|
+
## so we let Leeloo handle these
|
75
|
+
##
|
76
|
+
## and also, the smb-server has really shitty support for user-accounts
|
77
|
+
## so one popular way to avoid issues is by running copyparty without users;
|
78
|
+
## this makes all smb-clients identify as LD to gain unrestricted access
|
79
|
+
##
|
80
|
+
## Leeloo, being a fictional character from The Fifth Element,
|
81
|
+
## obviously does not exist and will never be able to access any copyparty
|
82
|
+
## instances from the outside (the username is rejected at every entrypoint)
|
83
|
+
##
|
84
|
+
## thanks for coming to my ted talk
|
85
|
+
|
66
86
|
|
67
87
|
SEE_LOG = "see log for details"
|
68
88
|
SEESLOG = " (see serverlog for details)"
|
@@ -114,6 +134,8 @@ class Lim(object):
|
|
114
134
|
self.reg = None # up2k registry
|
115
135
|
|
116
136
|
self.chmod_d = 0o755
|
137
|
+
self.uid = self.gid = -1
|
138
|
+
self.chown = False
|
117
139
|
|
118
140
|
self.nups = {} # num tracker
|
119
141
|
self.bups = {} # byte tracker list
|
@@ -276,6 +298,8 @@ class Lim(object):
|
|
276
298
|
# no branches yet; make one
|
277
299
|
sub = os.path.join(path, "0")
|
278
300
|
bos.mkdir(sub, self.chmod_d)
|
301
|
+
if self.chown:
|
302
|
+
os.chown(sub, self.uid, self.gid)
|
279
303
|
else:
|
280
304
|
# try newest branch only
|
281
305
|
sub = os.path.join(path, str(dirs[-1]))
|
@@ -291,6 +315,8 @@ class Lim(object):
|
|
291
315
|
# make a branch
|
292
316
|
sub = os.path.join(path, str(dirs[-1] + 1))
|
293
317
|
bos.mkdir(sub, self.chmod_d)
|
318
|
+
if self.chown:
|
319
|
+
os.chown(sub, self.uid, self.gid)
|
294
320
|
ret = self.dive(sub, lvs - 1)
|
295
321
|
if ret is None:
|
296
322
|
raise Pebkac(500, "rotation bug")
|
@@ -2153,7 +2179,7 @@ class AuthSrv(object):
|
|
2153
2179
|
if vf not in vol.flags:
|
2154
2180
|
vol.flags[vf] = getattr(self.args, ga)
|
2155
2181
|
|
2156
|
-
zs = "forget_ip nrand tail_who u2abort u2ow ups_who zip_who"
|
2182
|
+
zs = "forget_ip gid nrand tail_who u2abort u2ow uid ups_who zip_who"
|
2157
2183
|
for k in zs.split():
|
2158
2184
|
if k in vol.flags:
|
2159
2185
|
vol.flags[k] = int(vol.flags[k])
|
@@ -2190,8 +2216,17 @@ class AuthSrv(object):
|
|
2190
2216
|
if (is_d and zi != 0o755) or not is_d:
|
2191
2217
|
free_umask = True
|
2192
2218
|
|
2219
|
+
vol.flags.pop("chown", None)
|
2220
|
+
if vol.flags["uid"] != -1 or vol.flags["gid"] != -1:
|
2221
|
+
vol.flags["chown"] = True
|
2222
|
+
vol.flags.pop("fperms", None)
|
2223
|
+
if "chown" in vol.flags or vol.flags.get("chmod_f"):
|
2224
|
+
vol.flags["fperms"] = True
|
2193
2225
|
if vol.lim:
|
2194
2226
|
vol.lim.chmod_d = vol.flags["chmod_d"]
|
2227
|
+
vol.lim.chown = "chown" in vol.flags
|
2228
|
+
vol.lim.uid = vol.flags["uid"]
|
2229
|
+
vol.lim.gid = vol.flags["gid"]
|
2195
2230
|
|
2196
2231
|
if vol.flags.get("og"):
|
2197
2232
|
self.args.uqe = True
|
@@ -2742,7 +2777,7 @@ class AuthSrv(object):
|
|
2742
2777
|
"lifetime": vn.js_ls["lifetime"],
|
2743
2778
|
"u2sort": self.args.u2sort,
|
2744
2779
|
}
|
2745
|
-
vn.js_htm = json.dumps(js_htm)
|
2780
|
+
vn.js_htm = json_hesc(json.dumps(js_htm))
|
2746
2781
|
|
2747
2782
|
vols = list(vfs.all_nodes.values())
|
2748
2783
|
if enshare:
|
@@ -6,8 +6,11 @@ import os
|
|
6
6
|
from ..util import SYMTIME, fsdec, fsenc
|
7
7
|
from . import path as path
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
MKD_755 = {"chmod_d": 0o755}
|
10
|
+
MKD_700 = {"chmod_d": 0o700}
|
11
|
+
|
12
|
+
_ = (path, MKD_755, MKD_700)
|
13
|
+
__all__ = ["path", "MKD_755", "MKD_700"]
|
11
14
|
|
12
15
|
# grep -hRiE '(^|[^a-zA-Z_\.-])os\.' . | gsed -r 's/ /\n/g;s/\(/(\n/g' | grep -hRiE '(^|[^a-zA-Z_\.-])os\.' | sort | uniq -c
|
13
16
|
# printf 'os\.(%s)' "$(grep ^def bos/__init__.py | gsed -r 's/^def //;s/\(.*//' | tr '\n' '|' | gsed -r 's/.$//')"
|
@@ -17,11 +20,15 @@ def chmod(p , mode ) :
|
|
17
20
|
return os.chmod(fsenc(p), mode)
|
18
21
|
|
19
22
|
|
23
|
+
def chown(p , uid , gid ) :
|
24
|
+
return os.chown(fsenc(p), uid, gid)
|
25
|
+
|
26
|
+
|
20
27
|
def listdir(p = ".") :
|
21
28
|
return [fsdec(x) for x in os.listdir(fsenc(p))]
|
22
29
|
|
23
30
|
|
24
|
-
def makedirs(name ,
|
31
|
+
def makedirs(name , vf = MKD_755, exist_ok = True) :
|
25
32
|
# os.makedirs does 777 for all but leaf; this does mode on all
|
26
33
|
todo = []
|
27
34
|
bname = fsenc(name)
|
@@ -34,9 +41,13 @@ def makedirs(name , mode = 0o755, exist_ok = True) :
|
|
34
41
|
if not exist_ok:
|
35
42
|
os.mkdir(bname) # to throw
|
36
43
|
return False
|
44
|
+
mode = vf["chmod_d"]
|
45
|
+
chown = "chown" in vf
|
37
46
|
for zb in todo[::-1]:
|
38
47
|
try:
|
39
48
|
os.mkdir(zb, mode)
|
49
|
+
if chown:
|
50
|
+
os.chown(zb, vf["uid"], vf["gid"])
|
40
51
|
except:
|
41
52
|
if os.path.isdir(zb):
|
42
53
|
continue
|
@@ -114,6 +114,8 @@ def vf_vmap() :
|
|
114
114
|
"unlist",
|
115
115
|
"u2abort",
|
116
116
|
"u2ts",
|
117
|
+
"uid",
|
118
|
+
"gid",
|
117
119
|
"ups_who",
|
118
120
|
"zip_who",
|
119
121
|
"zipmaxn",
|
@@ -175,6 +177,8 @@ flagcats = {
|
|
175
177
|
"nodupe": "rejects existing files (instead of linking/cloning them)",
|
176
178
|
"chmod_d=755": "unix-permission for new dirs/folders",
|
177
179
|
"chmod_f=644": "unix-permission for new files",
|
180
|
+
"uid=573": "change owner of new files/folders to unix-user 573",
|
181
|
+
"gid=999": "change owner of new files/folders to unix-group 999",
|
178
182
|
"sparse": "force use of sparse files, mainly for s3-backed storage",
|
179
183
|
"nosparse": "deny use of sparse files, mainly for slow storage",
|
180
184
|
"daw": "enable full WebDAV write support (dangerous);\nPUT-operations will now \033[1;31mOVERWRITE\033[0;35m existing files",
|
@@ -31,6 +31,7 @@ from .util import (
|
|
31
31
|
relchk,
|
32
32
|
runhook,
|
33
33
|
sanitize_fn,
|
34
|
+
set_fperms,
|
34
35
|
vjoin,
|
35
36
|
wunlink,
|
36
37
|
)
|
@@ -258,8 +259,8 @@ class FtpFs(AbstractedFS):
|
|
258
259
|
wunlink(self.log, ap, VF_CAREFUL)
|
259
260
|
|
260
261
|
ret = open(fsenc(ap), mode, self.args.iobuf)
|
261
|
-
if w and "
|
262
|
-
|
262
|
+
if w and "fperms" in vfs.flags:
|
263
|
+
set_fperms(ret, vfs.flags)
|
263
264
|
|
264
265
|
return ret
|
265
266
|
|
@@ -293,8 +294,7 @@ class FtpFs(AbstractedFS):
|
|
293
294
|
|
294
295
|
def mkdir(self, path ) :
|
295
296
|
ap, vfs, _ = self.rv2a(path, w=True)
|
296
|
-
|
297
|
-
bos.makedirs(ap, chmod) # filezilla expects this
|
297
|
+
bos.makedirs(ap, vf=vfs.flags) # filezilla expects this
|
298
298
|
|
299
299
|
def listdir(self, path ) :
|
300
300
|
vpath = join(self.cwd, path)
|
@@ -33,7 +33,7 @@ except:
|
|
33
33
|
|
34
34
|
from .__init__ import ANYWIN, PY2, RES, TYPE_CHECKING, EnvParams, unicode
|
35
35
|
from .__version__ import S_VERSION
|
36
|
-
from .authsrv import VFS # typechk
|
36
|
+
from .authsrv import LEELOO_DALLAS, VFS # typechk
|
37
37
|
from .bos import bos
|
38
38
|
from .star import StreamTar
|
39
39
|
from .stolen.qrcodegen import QrCode, qr2svg
|
@@ -79,8 +79,10 @@ from .util import (
|
|
79
79
|
hidedir,
|
80
80
|
html_bescape,
|
81
81
|
html_escape,
|
82
|
+
html_sh_esc,
|
82
83
|
humansize,
|
83
84
|
ipnorm,
|
85
|
+
json_hesc,
|
84
86
|
justcopy,
|
85
87
|
load_resource,
|
86
88
|
loadpy,
|
@@ -103,6 +105,7 @@ from .util import (
|
|
103
105
|
sanitize_vpath,
|
104
106
|
sendfile_kern,
|
105
107
|
sendfile_py,
|
108
|
+
set_fperms,
|
106
109
|
stat_resource,
|
107
110
|
ub64dec,
|
108
111
|
ub64enc,
|
@@ -617,6 +620,9 @@ class HttpCli(object):
|
|
617
620
|
) or self.args.idp_h_key in self.headers
|
618
621
|
|
619
622
|
if trusted_key and trusted_xff:
|
623
|
+
if idp_usr.lower() == LEELOO_DALLAS:
|
624
|
+
self.loud_reply("send her back", status=403)
|
625
|
+
return False
|
620
626
|
self.asrv.idp_checkin(self.conn.hsrv.broker, idp_usr, idp_grp)
|
621
627
|
else:
|
622
628
|
if not trusted_key:
|
@@ -1105,15 +1111,18 @@ class HttpCli(object):
|
|
1105
1111
|
else:
|
1106
1112
|
return True
|
1107
1113
|
|
1114
|
+
host = self.host.lower()
|
1115
|
+
if host.startswith("["):
|
1116
|
+
if "]:" in host:
|
1117
|
+
host = host.split("]:")[0] + "]"
|
1118
|
+
else:
|
1119
|
+
host = host.split(":")[0]
|
1120
|
+
|
1108
1121
|
oh = self.out_headers
|
1109
1122
|
origin = origin.lower()
|
1110
|
-
|
1111
|
-
|
1112
|
-
|
1113
|
-
"https" if self.is_https else "http",
|
1114
|
-
self.host.lower().split(":")[0],
|
1115
|
-
)
|
1116
|
-
]
|
1123
|
+
proto = "https" if self.is_https else "http"
|
1124
|
+
good_origins = self.args.acao + ["%s://%s" % (proto, host)]
|
1125
|
+
|
1117
1126
|
if "pw" in ih or re.sub(r"(:[0-9]{1,5})?/?$", "", origin) in good_origins:
|
1118
1127
|
good_origin = True
|
1119
1128
|
bad_hdrs = ("",)
|
@@ -1570,6 +1579,18 @@ class HttpCli(object):
|
|
1570
1579
|
self.log("inaccessible: %r" % ("/" + self.vpath,))
|
1571
1580
|
raise Pebkac(401, "authenticate")
|
1572
1581
|
|
1582
|
+
if "quota-available-bytes" in props and not self.args.nid:
|
1583
|
+
bfree, btot, _ = get_df(vn.realpath, False)
|
1584
|
+
if btot:
|
1585
|
+
df = {
|
1586
|
+
"quota-available-bytes": str(bfree),
|
1587
|
+
"quota-used-bytes": str(btot - bfree),
|
1588
|
+
}
|
1589
|
+
else:
|
1590
|
+
df = {}
|
1591
|
+
else:
|
1592
|
+
df = {}
|
1593
|
+
|
1573
1594
|
fgen = itertools.chain([topdir], fgen)
|
1574
1595
|
vtop = vjoin(self.args.R, vjoin(vn.vpath, rem))
|
1575
1596
|
|
@@ -1612,6 +1633,9 @@ class HttpCli(object):
|
|
1612
1633
|
ap = os.path.join(tap, x["vp"])
|
1613
1634
|
pvs["getcontenttype"] = html_escape(guess_mime(rp, ap))
|
1614
1635
|
pvs["getcontentlength"] = str(st.st_size)
|
1636
|
+
elif df:
|
1637
|
+
pvs.update(df)
|
1638
|
+
df = {}
|
1615
1639
|
|
1616
1640
|
for k, v in pvs.items():
|
1617
1641
|
if k not in props:
|
@@ -2060,7 +2084,7 @@ class HttpCli(object):
|
|
2060
2084
|
fdir, fn = os.path.split(fdir)
|
2061
2085
|
rem, _ = vsplit(rem)
|
2062
2086
|
|
2063
|
-
bos.makedirs(fdir, vfs.flags
|
2087
|
+
bos.makedirs(fdir, vf=vfs.flags)
|
2064
2088
|
|
2065
2089
|
open_ka = {"fun": open}
|
2066
2090
|
open_a = ["wb", self.args.iobuf]
|
@@ -2117,9 +2141,7 @@ class HttpCli(object):
|
|
2117
2141
|
if nameless:
|
2118
2142
|
fn = vfs.flags["put_name2"].format(now=time.time(), cip=self.dip())
|
2119
2143
|
|
2120
|
-
params = {"suffix": suffix, "fdir": fdir}
|
2121
|
-
if "chmod_f" in vfs.flags:
|
2122
|
-
params["chmod"] = vfs.flags["chmod_f"]
|
2144
|
+
params = {"suffix": suffix, "fdir": fdir, "vf": vfs.flags}
|
2123
2145
|
if self.args.nw:
|
2124
2146
|
params = {}
|
2125
2147
|
fn = os.devnull
|
@@ -2167,7 +2189,7 @@ class HttpCli(object):
|
|
2167
2189
|
if self.args.nw:
|
2168
2190
|
fn = os.devnull
|
2169
2191
|
else:
|
2170
|
-
bos.makedirs(fdir, vfs.flags
|
2192
|
+
bos.makedirs(fdir, vf=vfs.flags)
|
2171
2193
|
path = os.path.join(fdir, fn)
|
2172
2194
|
if not nameless:
|
2173
2195
|
self.vpath = vjoin(self.vpath, fn)
|
@@ -2299,7 +2321,7 @@ class HttpCli(object):
|
|
2299
2321
|
if self.args.hook_v:
|
2300
2322
|
log_reloc(self.log, hr["reloc"], x, path, vp, fn, vfs, rem)
|
2301
2323
|
fdir, self.vpath, fn, (vfs, rem) = x
|
2302
|
-
bos.makedirs(fdir, vfs.flags
|
2324
|
+
bos.makedirs(fdir, vf=vfs.flags)
|
2303
2325
|
path2 = os.path.join(fdir, fn)
|
2304
2326
|
atomic_move(self.log, path, path2, vfs.flags)
|
2305
2327
|
path = path2
|
@@ -2584,7 +2606,7 @@ class HttpCli(object):
|
|
2584
2606
|
dst = vfs.canonical(rem)
|
2585
2607
|
try:
|
2586
2608
|
if not bos.path.isdir(dst):
|
2587
|
-
bos.makedirs(dst, vfs.flags
|
2609
|
+
bos.makedirs(dst, vf=vfs.flags)
|
2588
2610
|
except OSError as ex:
|
2589
2611
|
self.log("makedirs failed %r" % (dst,))
|
2590
2612
|
if not bos.path.isdir(dst):
|
@@ -3027,7 +3049,7 @@ class HttpCli(object):
|
|
3027
3049
|
raise Pebkac(405, 'folder "/%s" already exists' % (vpath,))
|
3028
3050
|
|
3029
3051
|
try:
|
3030
|
-
bos.makedirs(fn, vfs.flags
|
3052
|
+
bos.makedirs(fn, vf=vfs.flags)
|
3031
3053
|
except OSError as ex:
|
3032
3054
|
if ex.errno == errno.EACCES:
|
3033
3055
|
raise Pebkac(500, "the server OS denied write-access")
|
@@ -3068,8 +3090,8 @@ class HttpCli(object):
|
|
3068
3090
|
|
3069
3091
|
with open(fsenc(fn), "wb") as f:
|
3070
3092
|
f.write(b"`GRUNNUR`\n")
|
3071
|
-
if "
|
3072
|
-
|
3093
|
+
if "fperms" in vfs.flags:
|
3094
|
+
set_fperms(f, vfs.flags)
|
3073
3095
|
|
3074
3096
|
vpath = "{}/{}".format(self.vpath, sanitized).lstrip("/")
|
3075
3097
|
self.redirect(vpath, "?edit")
|
@@ -3143,7 +3165,7 @@ class HttpCli(object):
|
|
3143
3165
|
)
|
3144
3166
|
upload_vpath = "{}/{}".format(vfs.vpath, rem).strip("/")
|
3145
3167
|
if not nullwrite:
|
3146
|
-
bos.makedirs(fdir_base, vfs.flags
|
3168
|
+
bos.makedirs(fdir_base, vf=vfs.flags)
|
3147
3169
|
|
3148
3170
|
rnd, lifetime, xbu, xau = self.upload_flags(vfs)
|
3149
3171
|
zs = self.uparam.get("want") or self.headers.get("accept") or ""
|
@@ -3176,7 +3198,7 @@ class HttpCli(object):
|
|
3176
3198
|
if rnd:
|
3177
3199
|
fname = rand_name(fdir, fname, rnd)
|
3178
3200
|
|
3179
|
-
open_args = {"fdir": fdir, "suffix": suffix}
|
3201
|
+
open_args = {"fdir": fdir, "suffix": suffix, "vf": vfs.flags}
|
3180
3202
|
|
3181
3203
|
if "replace" in self.uparam:
|
3182
3204
|
if not self.can_delete:
|
@@ -3238,11 +3260,8 @@ class HttpCli(object):
|
|
3238
3260
|
else:
|
3239
3261
|
open_args["fdir"] = fdir
|
3240
3262
|
|
3241
|
-
if "chmod_f" in vfs.flags:
|
3242
|
-
open_args["chmod"] = vfs.flags["chmod_f"]
|
3243
|
-
|
3244
3263
|
if p_file and not nullwrite:
|
3245
|
-
bos.makedirs(fdir, vfs.flags
|
3264
|
+
bos.makedirs(fdir, vf=vfs.flags)
|
3246
3265
|
|
3247
3266
|
# reserve destination filename
|
3248
3267
|
f, fname = ren_open(fname, "wb", fdir=fdir, suffix=suffix)
|
@@ -3346,7 +3365,7 @@ class HttpCli(object):
|
|
3346
3365
|
if nullwrite:
|
3347
3366
|
fdir = ap2 = ""
|
3348
3367
|
else:
|
3349
|
-
bos.makedirs(fdir, vfs.flags
|
3368
|
+
bos.makedirs(fdir, vf=vfs.flags)
|
3350
3369
|
atomic_move(self.log, abspath, ap2, vfs.flags)
|
3351
3370
|
abspath = ap2
|
3352
3371
|
sz = bos.path.getsize(abspath)
|
@@ -3467,8 +3486,8 @@ class HttpCli(object):
|
|
3467
3486
|
ft = "{}:{}".format(self.ip, self.addr[1])
|
3468
3487
|
ft = "{}\n{}\n{}\n".format(ft, msg.rstrip(), errmsg)
|
3469
3488
|
f.write(ft.encode("utf-8"))
|
3470
|
-
if "
|
3471
|
-
|
3489
|
+
if "fperms" in vfs.flags:
|
3490
|
+
set_fperms(f, vfs.flags)
|
3472
3491
|
except Exception as ex:
|
3473
3492
|
suf = "\nfailed to write the upload report: {}".format(ex)
|
3474
3493
|
|
@@ -3518,7 +3537,7 @@ class HttpCli(object):
|
|
3518
3537
|
lim = vfs.get_dbv(rem)[0].lim
|
3519
3538
|
if lim:
|
3520
3539
|
fp, rp = lim.all(self.ip, rp, clen, vfs.realpath, fp, self.conn.hsrv.broker)
|
3521
|
-
bos.makedirs(fp, vfs.flags
|
3540
|
+
bos.makedirs(fp, vf=vfs.flags)
|
3522
3541
|
|
3523
3542
|
fp = os.path.join(fp, fn)
|
3524
3543
|
rem = "{}/{}".format(rp, fn).strip("/")
|
@@ -3586,15 +3605,17 @@ class HttpCli(object):
|
|
3586
3605
|
zs = ub64enc(zb).decode("ascii")[:24].lower()
|
3587
3606
|
dp = "%s/md/%s/%s/%s" % (dbv.histpath, zs[:2], zs[2:4], zs)
|
3588
3607
|
self.log("moving old version to %s/%s" % (dp, mfile2))
|
3589
|
-
if bos.makedirs(dp, vfs.flags
|
3608
|
+
if bos.makedirs(dp, vf=vfs.flags):
|
3590
3609
|
with open(os.path.join(dp, "dir.txt"), "wb") as f:
|
3591
3610
|
f.write(afsenc(vrd))
|
3592
|
-
if "
|
3593
|
-
|
3611
|
+
if "fperms" in vfs.flags:
|
3612
|
+
set_fperms(f, vfs.flags)
|
3594
3613
|
elif hist_cfg == "s":
|
3595
3614
|
dp = os.path.join(mdir, ".hist")
|
3596
3615
|
try:
|
3597
3616
|
bos.mkdir(dp, vfs.flags["chmod_d"])
|
3617
|
+
if "chown" in vfs.flags:
|
3618
|
+
bos.chown(dp, vfs.flags["uid"], vfs.flags["gid"])
|
3598
3619
|
hidedir(dp)
|
3599
3620
|
except:
|
3600
3621
|
pass
|
@@ -3632,8 +3653,8 @@ class HttpCli(object):
|
|
3632
3653
|
wunlink(self.log, fp, vfs.flags)
|
3633
3654
|
|
3634
3655
|
with open(fsenc(fp), "wb", self.args.iobuf) as f:
|
3635
|
-
if "
|
3636
|
-
|
3656
|
+
if "fperms" in vfs.flags:
|
3657
|
+
set_fperms(f, vfs.flags)
|
3637
3658
|
sz, sha512, _ = hashcopy(p_data, f, None, 0, self.args.s_wr_slp)
|
3638
3659
|
|
3639
3660
|
if lim:
|
@@ -4870,11 +4891,8 @@ class HttpCli(object):
|
|
4870
4891
|
else:
|
4871
4892
|
rip = host
|
4872
4893
|
|
4873
|
-
|
4874
|
-
pw =
|
4875
|
-
vp = re.sub(r"[<>&$?`\"']", "_", self.uparam["hc"] or "").lstrip("/")
|
4876
|
-
pw = pw.replace(" ", "%20")
|
4877
|
-
vp = vp.replace(" ", "%20")
|
4894
|
+
vp = (self.uparam["hc"] or "").lstrip("/")
|
4895
|
+
pw = self.pw or "hunter2"
|
4878
4896
|
if pw in self.asrv.sesa:
|
4879
4897
|
pw = "hunter2"
|
4880
4898
|
|
@@ -4883,14 +4901,14 @@ class HttpCli(object):
|
|
4883
4901
|
args=self.args,
|
4884
4902
|
accs=bool(self.asrv.acct),
|
4885
4903
|
s="s" if self.is_https else "",
|
4886
|
-
rip=rip,
|
4887
|
-
ep=ep,
|
4888
|
-
vp=vp,
|
4889
|
-
rvp=vjoin(self.args.R, vp),
|
4890
|
-
host=host,
|
4891
|
-
hport=hport,
|
4904
|
+
rip=html_sh_esc(rip),
|
4905
|
+
ep=html_sh_esc(ep),
|
4906
|
+
vp=html_sh_esc(vp),
|
4907
|
+
rvp=html_sh_esc(vjoin(self.args.R, vp)),
|
4908
|
+
host=html_sh_esc(host),
|
4909
|
+
hport=html_sh_esc(hport),
|
4892
4910
|
aname=aname,
|
4893
|
-
pw=pw,
|
4911
|
+
pw=html_sh_esc(pw),
|
4894
4912
|
)
|
4895
4913
|
self.reply(html.encode("utf-8"))
|
4896
4914
|
return True
|
@@ -5552,7 +5570,7 @@ class HttpCli(object):
|
|
5552
5570
|
self.reply(jtxt.encode("utf-8", "replace"), mime="application/json")
|
5553
5571
|
return True
|
5554
5572
|
|
5555
|
-
html = self.j2s("rups", this=self, v=jtxt)
|
5573
|
+
html = self.j2s("rups", this=self, v=json_hesc(jtxt))
|
5556
5574
|
self.reply(html.encode("utf-8"), status=200)
|
5557
5575
|
return True
|
5558
5576
|
|
@@ -5616,15 +5634,15 @@ class HttpCli(object):
|
|
5616
5634
|
raise Pebkac(500, "sqlite3 not found on server; sharing is disabled")
|
5617
5635
|
raise Pebkac(500, "server busy, cannot create share; please retry in a bit")
|
5618
5636
|
|
5637
|
+
skey = self.uparam.get("skey") or self.vpath.split("/")[-1]
|
5638
|
+
|
5619
5639
|
if self.args.shr_v:
|
5620
|
-
self.log("handle_eshare: " +
|
5640
|
+
self.log("handle_eshare: " + skey)
|
5621
5641
|
|
5622
5642
|
cur = idx.get_shr()
|
5623
5643
|
if not cur:
|
5624
5644
|
raise Pebkac(400, "huh, sharing must be disabled in the server config...")
|
5625
5645
|
|
5626
|
-
skey = self.vpath.split("/")[-1]
|
5627
|
-
|
5628
5646
|
rows = cur.execute("select un, t1 from sh where k = ?", (skey,)).fetchall()
|
5629
5647
|
un = rows[0][0] if rows and rows[0] else ""
|
5630
5648
|
|
@@ -6133,13 +6151,13 @@ class HttpCli(object):
|
|
6133
6151
|
self.log("#wow #whoa")
|
6134
6152
|
|
6135
6153
|
if not self.args.nid:
|
6136
|
-
free, total,
|
6137
|
-
if total
|
6154
|
+
free, total, zs = get_df(abspath, False)
|
6155
|
+
if total:
|
6138
6156
|
h1 = humansize(free or 0)
|
6139
6157
|
h2 = humansize(total)
|
6140
6158
|
srv_info.append("{} free of {}".format(h1, h2))
|
6141
|
-
elif
|
6142
|
-
|
6159
|
+
elif zs:
|
6160
|
+
self.log("diskfree(%r): %s" % (abspath, zs), 3)
|
6143
6161
|
|
6144
6162
|
srv_infot = "</span> // <span>".join(srv_info)
|
6145
6163
|
|