acc/vol ideas

This commit is contained in:
ed 2019-05-28 20:49:58 +00:00
parent 75cae0261f
commit 69e83e95ba
6 changed files with 153 additions and 13 deletions

View file

@ -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
View 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,
}
)

View file

@ -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"""

View file

@ -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
View 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

View file

@ -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; }
## ##