mirror of
https://github.com/9001/copyparty.git
synced 2025-08-16 16:42:13 -06:00
acc/vol ideas
This commit is contained in:
parent
75cae0261f
commit
69e83e95ba
|
@ -52,15 +52,15 @@ def main():
|
|||
epilog=dedent(
|
||||
"""
|
||||
-a takes username:password,
|
||||
-v takes path:permset:permset:... where "permset" is
|
||||
-v takes src:dst:permset:permset:... where "permset" is
|
||||
accesslevel followed by username (no separator)
|
||||
|
||||
example:\033[35m
|
||||
-a ed:hunter2 -v .:r:aed -v ../inc:w:aed \033[36m
|
||||
share current directory with
|
||||
-a ed:hunter2 -v .::r:aed -v ../inc:dump:w:aed \033[36m
|
||||
mount current directory at "/" with
|
||||
* r (read-only) for everyone
|
||||
* a (read+write) for ed
|
||||
share ../inc with
|
||||
mount ../inc at "/dump" with
|
||||
* w (write-only) for everyone
|
||||
* a (read+write) for ed \033[0m
|
||||
|
||||
|
@ -72,14 +72,16 @@ def main():
|
|||
"""
|
||||
),
|
||||
)
|
||||
ap.add_argument("-c", metavar="PATH", type=str, help="config file")
|
||||
ap.add_argument(
|
||||
"-c", metavar="PATH", type=str, action="append", help="add config file"
|
||||
)
|
||||
ap.add_argument("-i", metavar="IP", type=str, default="0.0.0.0", help="ip to bind")
|
||||
ap.add_argument("-p", metavar="PORT", type=int, default=1234, help="port to bind")
|
||||
ap.add_argument("-nc", metavar="NUM", type=int, default=16, help="max num clients")
|
||||
ap.add_argument("-j", metavar="CORES", type=int, help="max num cpu cores")
|
||||
ap.add_argument("-a", metavar="ACCT", type=str, help="add account")
|
||||
ap.add_argument("-v", metavar="VOL", type=str, help="add volume")
|
||||
ap.add_argument("-nw", action="store_true", help="DEBUG: disable writing")
|
||||
ap.add_argument("-a", metavar="ACCT", type=str, action="append", help="add account")
|
||||
ap.add_argument("-v", metavar="VOL", type=str, action="append", help="add volume")
|
||||
ap.add_argument("-nw", action="store_true", help="benchmark: disable writing")
|
||||
al = ap.parse_args()
|
||||
|
||||
tcpsrv = TcpSrv(al)
|
||||
|
|
81
copyparty/authsrv.py
Normal file
81
copyparty/authsrv.py
Normal file
|
@ -0,0 +1,81 @@
|
|||
#!/usr/bin/env python
|
||||
# coding: utf-8
|
||||
from __future__ import print_function
|
||||
|
||||
import pprint
|
||||
import threading
|
||||
|
||||
from .__init__ import *
|
||||
|
||||
|
||||
class AuthSrv(object):
|
||||
"""verifies users against given paths"""
|
||||
|
||||
def __init__(self, args, log_func):
|
||||
self.log_func = log_func
|
||||
self.args = args
|
||||
|
||||
self.mutex = threading.Lock()
|
||||
self.reload()
|
||||
|
||||
def log(self, msg):
|
||||
self.log_func("auth", msg)
|
||||
|
||||
def invert(self, orig):
|
||||
if PY2:
|
||||
return {v: k for k, v in orig.iteritems()}
|
||||
else:
|
||||
return {v: k for k, v in orig.items()}
|
||||
|
||||
def reload(self):
|
||||
user = {} # username:password
|
||||
uread = {} # username:readable-mp
|
||||
uwrite = {} # username:writable-mp
|
||||
mount = {} # dst:src (mountpoint:realpath)
|
||||
|
||||
if self.args.a:
|
||||
# list of username:password
|
||||
for u, p in [x.split(":", 1) for x in self.args.a]:
|
||||
user[u] = p
|
||||
|
||||
if self.args.v:
|
||||
# list of src:dst:permset:permset:...
|
||||
# permset is [rwa]username
|
||||
for src, dst, perms in [x.split(":", 2) for x in self.args.v]:
|
||||
src = os.path.abspath(src)
|
||||
dst = ("/" + dst.strip("/") + "/").replace("//", "/")
|
||||
mount[dst] = src
|
||||
perms = perms.split(":")
|
||||
for (lvl, uname) in [[x[0], x[1:]] for x in perms]:
|
||||
if uname == "":
|
||||
uname = "*"
|
||||
if lvl in "ra":
|
||||
uread[uname] = dst
|
||||
if lvl in "wa":
|
||||
uwrite[uname] = dst
|
||||
|
||||
if self.args.c:
|
||||
for logfile in self.args.c:
|
||||
with open(logfile, "rb") as f:
|
||||
for ln in [x.decode("utf-8").rstrip() for x in f]:
|
||||
# self.log(ln)
|
||||
pass
|
||||
|
||||
with self.mutex:
|
||||
self.user = user
|
||||
self.uread = uread
|
||||
self.uwrite = uwrite
|
||||
self.mount = mount
|
||||
self.iuser = self.invert(user)
|
||||
self.iuread = self.invert(uread)
|
||||
self.iuwrite = self.invert(uwrite)
|
||||
self.imount = self.invert(mount)
|
||||
|
||||
pprint.pprint(
|
||||
{
|
||||
"user": self.user,
|
||||
"uread": self.uread,
|
||||
"uwrite": self.uwrite,
|
||||
"mount": self.mount,
|
||||
}
|
||||
)
|
|
@ -5,6 +5,7 @@ from __future__ import print_function
|
|||
import threading
|
||||
|
||||
from .httpcli import *
|
||||
from .authsrv import *
|
||||
|
||||
|
||||
class HttpSrv(object):
|
||||
|
@ -18,11 +19,12 @@ class HttpSrv(object):
|
|||
self.args = args
|
||||
|
||||
self.disconnect_func = None
|
||||
self.mutex = threading.Lock()
|
||||
|
||||
self.clients = {}
|
||||
self.workload = 0
|
||||
self.workload_thr_alive = False
|
||||
|
||||
self.mutex = threading.Lock()
|
||||
self.auth = AuthSrv(args, log_func)
|
||||
|
||||
def accept(self, sck, addr):
|
||||
"""takes an incoming tcp connection and creates a thread to handle it"""
|
||||
|
|
|
@ -108,10 +108,10 @@ class MpSrv(object):
|
|||
self.args = args
|
||||
|
||||
self.disconnect_func = None
|
||||
self.procs = []
|
||||
|
||||
self.mutex = threading.Lock()
|
||||
|
||||
self.procs = []
|
||||
|
||||
cores = args.j
|
||||
if cores is None:
|
||||
cores = mp.cpu_count()
|
||||
|
|
38
docs/example.conf
Normal file
38
docs/example.conf
Normal file
|
@ -0,0 +1,38 @@
|
|||
# any line with a : creates a user,
|
||||
# username:password
|
||||
# so you can create users anywhere really
|
||||
# but keeping them here is prob a good idea
|
||||
ed:123
|
||||
k:k
|
||||
|
||||
# leave a blank line before each volume
|
||||
|
||||
# this is a volume,
|
||||
# it shares the contents of /home/...
|
||||
# and appears at "/dj" in the web-ui
|
||||
# "r" grants read-access for anyone
|
||||
# "a ed" grants read-write to ed
|
||||
/home/ed/Music/dj
|
||||
/dj
|
||||
r
|
||||
a ed
|
||||
|
||||
# display /home/ed/ocv.me as the webroot
|
||||
# and allow user "k" to see/read it
|
||||
/home/ed/ocv.me
|
||||
/
|
||||
r k
|
||||
|
||||
# this shares the current directory as "/pwd"
|
||||
# but does nothing since there's no permissions
|
||||
.
|
||||
/pwd
|
||||
|
||||
# and a folder where anyone can upload
|
||||
# but nobody can see the contents
|
||||
/home/ed/inc
|
||||
/incoming
|
||||
w
|
||||
|
||||
# you can use relative paths too btw
|
||||
# but they're a pain for testing purpose so I didn't
|
|
@ -1,14 +1,31 @@
|
|||
#!/bin/bash
|
||||
echo not a script
|
||||
exit 1
|
||||
|
||||
|
||||
##
|
||||
## prep debug env (vscode embedded terminal)
|
||||
|
||||
renice 20 -p $$
|
||||
|
||||
|
||||
##
|
||||
## cleanup after a busted shutdown
|
||||
|
||||
ps ax | awk '/python[23]?[ ]-m copyparty/ {print $1}' | tee /dev/stderr | xargs kill
|
||||
|
||||
|
||||
##
|
||||
## create a test payload
|
||||
|
||||
head -c $((2*1024*1024*1024)) /dev/zero | openssl enc -aes-256-ctr -pass pass:hunter2 -nosalt > garbage.file
|
||||
|
||||
|
||||
##
|
||||
## testing multiple parallel uploads
|
||||
## usage: para | tee log
|
||||
|
||||
para() { for s in 1 2 3 4 5 6 7 8 12 16 24 32 48 64; do echo $s; for r in {1..5}; do for ((n=0;n<s;n++)); do curl -sF "f=@Various.zip" http://127.0.0.1:1234/32 2>&1 & done; wait; echo; done; done; }
|
||||
para() { for s in 1 2 3 4 5 6 7 8 12 16 24 32 48 64; do echo $s; for r in {1..4}; do for ((n=0;n<s;n++)); do curl -sF "f=@garbage.file" http://127.0.0.1:1234/32 2>&1 & done; wait; echo; done; done; }
|
||||
|
||||
|
||||
##
|
||||
|
|
Loading…
Reference in a new issue