mirror of
https://github.com/9001/copyparty.git
synced 2025-08-17 09:02:15 -06:00
acc/vol ideas
This commit is contained in:
parent
75cae0261f
commit
69e83e95ba
|
@ -52,15 +52,15 @@ def main():
|
||||||
epilog=dedent(
|
epilog=dedent(
|
||||||
"""
|
"""
|
||||||
-a takes username:password,
|
-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)
|
accesslevel followed by username (no separator)
|
||||||
|
|
||||||
example:\033[35m
|
example:\033[35m
|
||||||
-a ed:hunter2 -v .:r:aed -v ../inc:w:aed \033[36m
|
-a ed:hunter2 -v .::r:aed -v ../inc:dump:w:aed \033[36m
|
||||||
share current directory with
|
mount current directory at "/" with
|
||||||
* r (read-only) for everyone
|
* r (read-only) for everyone
|
||||||
* a (read+write) for ed
|
* a (read+write) for ed
|
||||||
share ../inc with
|
mount ../inc at "/dump" with
|
||||||
* w (write-only) for everyone
|
* w (write-only) for everyone
|
||||||
* a (read+write) for ed \033[0m
|
* 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("-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("-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("-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("-j", metavar="CORES", type=int, help="max num cpu cores")
|
||||||
ap.add_argument("-a", metavar="ACCT", type=str, help="add account")
|
ap.add_argument("-a", metavar="ACCT", type=str, action="append", help="add account")
|
||||||
ap.add_argument("-v", metavar="VOL", type=str, help="add volume")
|
ap.add_argument("-v", metavar="VOL", type=str, action="append", help="add volume")
|
||||||
ap.add_argument("-nw", action="store_true", help="DEBUG: disable writing")
|
ap.add_argument("-nw", action="store_true", help="benchmark: disable writing")
|
||||||
al = ap.parse_args()
|
al = ap.parse_args()
|
||||||
|
|
||||||
tcpsrv = TcpSrv(al)
|
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
|
import threading
|
||||||
|
|
||||||
from .httpcli import *
|
from .httpcli import *
|
||||||
|
from .authsrv import *
|
||||||
|
|
||||||
|
|
||||||
class HttpSrv(object):
|
class HttpSrv(object):
|
||||||
|
@ -18,11 +19,12 @@ class HttpSrv(object):
|
||||||
self.args = args
|
self.args = args
|
||||||
|
|
||||||
self.disconnect_func = None
|
self.disconnect_func = None
|
||||||
|
self.mutex = threading.Lock()
|
||||||
|
|
||||||
self.clients = {}
|
self.clients = {}
|
||||||
self.workload = 0
|
self.workload = 0
|
||||||
self.workload_thr_alive = False
|
self.workload_thr_alive = False
|
||||||
|
self.auth = AuthSrv(args, log_func)
|
||||||
self.mutex = threading.Lock()
|
|
||||||
|
|
||||||
def accept(self, sck, addr):
|
def accept(self, sck, addr):
|
||||||
"""takes an incoming tcp connection and creates a thread to handle it"""
|
"""takes an incoming tcp connection and creates a thread to handle it"""
|
||||||
|
|
|
@ -108,10 +108,10 @@ class MpSrv(object):
|
||||||
self.args = args
|
self.args = args
|
||||||
|
|
||||||
self.disconnect_func = None
|
self.disconnect_func = None
|
||||||
self.procs = []
|
|
||||||
|
|
||||||
self.mutex = threading.Lock()
|
self.mutex = threading.Lock()
|
||||||
|
|
||||||
|
self.procs = []
|
||||||
|
|
||||||
cores = args.j
|
cores = args.j
|
||||||
if cores is None:
|
if cores is None:
|
||||||
cores = mp.cpu_count()
|
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)
|
## prep debug env (vscode embedded terminal)
|
||||||
|
|
||||||
renice 20 -p $$
|
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
|
## testing multiple parallel uploads
|
||||||
## usage: para | tee log
|
## 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