1
0
mirror of https://github.com/pypiserver/pypiserver synced 2024-11-09 16:45:51 +01:00

Added rudimentary support for uploads

This commit is contained in:
Eric Moritz 2012-04-17 17:46:12 -04:00 committed by Ralf Schmitt
parent 1340b90ac9
commit 4ceb82458c
3 changed files with 70 additions and 7 deletions

@ -4,7 +4,8 @@ version = __version__ = "0.5.2"
def app(root=None,
redirect_to_fallback=True,
fallback_url=None):
fallback_url=None,
password_file=None):
import sys, os
from pypiserver import core
sys.modules.pop("pypiserver._app", None)
@ -20,7 +21,8 @@ def app(root=None,
fallback_url="http://pypi.python.org/simple"
os.listdir(root)
_app.configure(root=root, redirect_to_fallback=redirect_to_fallback, fallback_url=fallback_url)
_app.configure(root=root, redirect_to_fallback=redirect_to_fallback, fallback_url=fallback_url,
password_file=password_file)
_app.app.module = _app
bottle.debug(True)

@ -8,6 +8,7 @@ else:
from bottle import static_file, redirect, request, HTTPError, Bottle
from pypiserver import __version__
from pypiserver.core import is_allowed_path
import md5
packages = None
@ -18,9 +19,27 @@ class configuration(object):
config = configuration()
def read_passwd_file(passwd_file):
users = {}
for line in open(passwd_file):
user, md5_hash = line.strip().split(":")
users[user] = md5_hash
return users
def validate_user(username, password):
if username in config.users:
md5_hash = md5.new(password).hexdigest()
return config.users[username] == md5_hash
else:
return False
def configure(root=None,
redirect_to_fallback=True,
fallback_url=None):
fallback_url=None,
password_file=None):
from pypiserver.core import pkgset
global packages
@ -33,7 +52,12 @@ def configure(root=None,
packages = pkgset(root)
config.redirect_to_fallback = redirect_to_fallback
config.fallback_url = fallback_url
if password_file:
config.users = read_passwd_file(password_file)
else:
# PyPi server is read only without users
config.users = {}
app = Bottle()
@ -69,6 +93,30 @@ easy_install -i %(URL)ssimple/ PACKAGE
</body></html>
""" % dict(URL=request.url, VERSION=__version__, NUMPKGS=numpkgs)
@app.post('/')
def update():
if request.auth and validate_user(*request.auth):
try:
content = request.files['content']
except KeyError:
raise HTTPError(400, output="content file field not found")
try:
action = request.forms[':action']
except KeyError:
raise HTTPError(400, output=":action field not found")
if action != "file_upload":
raise HTTPError(400, output="actions other than file_upload, not supported")
if "/" in content.filename:
raise HTTPError(400, output="bad filename")
packages.store(content.filename, content.value)
return ""
else:
raise HTTPError(401)
@app.route("/simple")
def simpleindex_redirect():

@ -65,7 +65,13 @@ class pkgset(object):
prefixes.add(pkgname)
return prefixes
def store(self, filename, data):
assert "/" not in filename
dest_fn = os.path.join(self.root, filename)
dest_fh = open(dest_fn, "wb")
dest_fh.write(data)
dest_fh.close()
def usage():
@ -84,6 +90,9 @@ pypi-server understands the following options:
-i INTERFACE, --interface INTERFACE
listen on interface INTERFACE (default: 0.0.0.0, any interface)
-P PASSWORD_FILE --passwords PASSWORD_FILE
A file of username:md5(password) lines
--disable-fallback
disable redirect to real PyPI index for packages not found in the
local index
@ -137,13 +146,14 @@ def main(argv=None):
port = 8080
server = None
redirect_to_fallback = True
password_file = None
update_dry_run = True
update_directory = None
update_stable_only = True
try:
opts, roots = getopt.getopt(argv[1:], "i:p:r:d:Uuxh", ["interface=", "port=", "root=", "server=", "disable-fallback", "version", "help"])
opts, roots = getopt.getopt(argv[1:], "i:p:r:d:P:Uuxh", ["interface=", "passwords=", "port=", "root=", "server=", "disable-fallback", "version", "help"])
except getopt.GetoptError:
err = sys.exc_info()[1]
sys.exit("usage error: %s" % (err,))
@ -172,10 +182,13 @@ def main(argv=None):
update_stable_only = False
elif k == "-d":
update_directory = v
elif k in ("-P", "--passwords"):
password_file = v
elif k in ("-h", "--help"):
usage()
sys.exit(0)
if len(roots) == 0:
roots.append(os.path.expanduser("~/packages"))
elif len(roots) > 1:
@ -196,7 +209,7 @@ def main(argv=None):
manage.update(packages, update_directory, update_dry_run, stable_only=update_stable_only)
return
a = app(root=root, redirect_to_fallback=redirect_to_fallback)
a = app(root=root, redirect_to_fallback=redirect_to_fallback, password_file=password_file)
server = server or "auto"
sys.stdout.write("This is pypiserver %s serving %r on %s:%s\n\n" % (__version__, root, host, port))
run(app=a, host=host, port=port, server=server)