1
0
mirror of https://github.com/Tygs/0bin.git synced 2023-08-10 21:13:00 +03:00
0bin/zerobin/cmd.py
2020-08-12 09:19:38 +02:00

156 lines
3.9 KiB
Python

#!/usr/bin/env python3
"""
Main script including runserver and delete-paste.
"""
import sys
import re
import hashlib
import _thread as thread
from zerobin.utils import (
settings,
SettingsValidationError,
drop_privileges,
ensure_var_env,
hash_password,
)
from zerobin.routes import get_app
from zerobin.paste import Paste
from bottle import run
import clize
def runserver(
*,
host="",
port="",
debug=None,
user="",
group="",
settings_file="",
compressed_static=None,
version=False,
paste_id_length=None,
server="cherrypy",
):
if version:
print("0bin V%s" % settings.VERSION)
sys.exit(0)
settings.HOST = host or settings.HOST
settings.PORT = port or settings.PORT
settings.USER = user or settings.USER
settings.GROUP = group or settings.GROUP
settings.PASTE_ID_LENGTH = paste_id_length or settings.PASTE_ID_LENGTH
settings.DEBUG = bool(debug) if debug is not None else settings.DEBUG
ensure_var_env()
try:
_, app = get_app(debug, settings_file, compressed_static, settings=settings)
except SettingsValidationError as err:
print("Configuration error: %s" % err.message, file=sys.stderr)
sys.exit(1)
thread.start_new_thread(drop_privileges, (settings.USER, settings.GROUP))
if settings.DEBUG:
print(f"Admin URL: http://{settings.HOST}:{settings.PORT}{settings.ADMIN_URL}")
run(
app, host=settings.HOST, port=settings.PORT, reloader=True, server=server,
)
else:
run(app, host=settings.HOST, port=settings.PORT, server=server)
# The regex parse the url and separate the paste's id from the decription key
# After the '/paste/' part, there is several caracters, identified as
# the uuid of the paste. Followed by a '#', the decryption key of the paste.
paste_url = re.compile("/paste/(?P<paste_id>.*)#(?P<key>.*)")
def unpack_paste(paste):
"""Take either the ID or the URL of a paste, and return its ID"""
try_url = paste_url.search(paste)
if try_url:
return try_url.group("paste_id")
return paste
def delete_paste(*pastes, quiet=False):
"""
Remove pastes, given its ID or its URL
quiet: Don't print anything
pastes: List of pastes, given by ID or URL
"""
for paste_uuid in map(unpack_paste, pastes):
try:
Paste.load(paste_uuid).delete()
if not quiet:
print("Paste {} is removed".format(paste_uuid))
except ValueError:
if not quiet:
print("Paste {} doesn't exist".format(paste_uuid))
def print_admin_url():
""" Print the route to the 0bin admin.
The admin route is generated by zerobin so that bots won't easily
bruteforce it. To get the full URL, simply preppend your website domain
name to it.
E.G:
If this command prints:
"/admin/f1cc3972a4b933c734b37906940cf69886161492ee4eb7c1faff5d7b5e92efb8"
Then the admin url is:
"http://yourdomain.com/admin/f1cc3972a4b933c734b37906940cf69886161492ee4eb7c1faff5d7b5e92efb8"
Adapt "http" and "yourdomain.com" to your configuration.
In debug mode, the dev server will print the url when starting.
"""
ensure_var_env()
print(settings.ADMIN_URL)
def set_admin_password(password):
""" Set the password for the admin
It will be stored as a scrypt hash in a file in the var dir.
"""
ensure_var_env()
settings.ADMIN_PASSWORD_FILE.write_bytes(hash_password(password))
def main():
subcommands = [runserver, delete_paste, print_admin_url, set_admin_password]
subcommand_names = [
clize.util.name_py2cli(name)
for name in clize.util.dict_from_names(subcommands).keys()
]
if len(sys.argv) < 2 or sys.argv[1] not in subcommand_names:
sys.argv.insert(1, subcommand_names[0])
clize.run(runserver, delete_paste, print_admin_url, set_admin_password)