1
0
mirror of https://github.com/Tygs/0bin.git synced 2023-08-10 21:13:00 +03:00

Use base64-like (dashes in place of slashes) paste-ids with (configurable) 8-char length limit

This commit is contained in:
Mike Kazantsev 2013-04-30 00:17:37 +06:00 committed by fraggod@sacrilege
parent 353fac415a
commit 6675209e31
4 changed files with 32 additions and 10 deletions

View File

@ -70,3 +70,8 @@ MENU = (
# limit size of pasted text in bytes. Be careful allowing too much size can
# slow down user's browser
MAX_SIZE = 1024 * 500
# length of base64-like paste-id string in the url, int from 4 to 27 (length of sha1 digest)
# total number of unique pastes can be calculated as 2^(6*PASTE_ID_LENGTH)
# for PASTE_ID_LENGTH=8, for example, it's 2^(6*8) = 281 474 976 710 656
PASTE_ID_LENGTH = 8

View File

@ -24,8 +24,8 @@ class Paste(object):
}
def __init__(self, uuid=None, content=None,
expiration=None):
def __init__(self, uuid=None, uuid_length=None,
content=None, expiration=None):
self.content = content
self.expiration = expiration
@ -35,7 +35,11 @@ class Paste(object):
self.expiration = self.get_expiration(expiration)
self.uuid = uuid or hashlib.sha1(self.content).hexdigest()
if not uuid:
uuid = hashlib.sha1(self.content)\
.digest().encode('base64').rstrip('=\n').replace('/', '-')
if uuid_length: uuid = uuid[:uuid_length]
self.uuid = uuid
def get_expiration(self, expiration):
@ -260,4 +264,3 @@ class Paste(object):
Delete the paste file.
"""
os.remove(self.path)

View File

@ -15,7 +15,7 @@ from datetime import datetime, timedelta
# add project dir and libs dir to the PYTHON PATH to ensure they are
# importable
from utils import settings
from utils import settings, SettingsValidationError
import bottle
from bottle import (Bottle, run, static_file, view, request)
@ -70,7 +70,8 @@ def create_paste():
# system. need to be improved
if len(content) < settings.MAX_SIZE:
expiration = body.get('expiration', [u'burn_after_reading'])[0]
paste = Paste(expiration=expiration, content=content)
paste = Paste(expiration=expiration, content=content,
uuid_length=settings.PASTE_ID_LENGTH)
paste.save()
# display counter
@ -141,7 +142,8 @@ def server_static(filename):
return static_file(filename, root=settings.STATIC_FILES_ROOT)
def get_app(debug=None, settings_file='', compressed_static=None):
def get_app(debug=None, settings_file='',
compressed_static=None, settings=settings):
"""
Return a tuple (settings, app) configured using passed
parameters and/or a setting file.
@ -149,6 +151,9 @@ def get_app(debug=None, settings_file='', compressed_static=None):
if settings_file:
settings.update_with_file(os.path.abspath(settings_file))
if settings.PASTE_ID_LENGTH < 4:
raise SettingsValidationError('PASTE_ID_LENGTH cannot be lower than 4')
if compressed_static is not None:
settings.COMPRESSED_STATIC_FILES = compressed_static
@ -167,9 +172,8 @@ def get_app(debug=None, settings_file='', compressed_static=None):
@clize.clize(coerce={'debug': bool, 'compressed_static': bool})
def runserver(host='', port='', debug=None, user='', group='',
settings_file='', compressed_static=None, version=False):
settings, app = get_app(debug, settings_file, compressed_static)
settings_file='', compressed_static=None,
version=False, paste_id_length=None):
if version:
print '0bin V%s' % settings.VERSION
@ -179,6 +183,13 @@ def runserver(host='', port='', debug=None, user='', group='',
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
try:
_, app = get_app(debug, settings_file, compressed_static, settings=settings)
except SettingsValidationError as err:
print >>sys.stderr, 'Configuration error: %s' % err.message
sys.exit(1)
thread.start_new_thread(drop_privileges, (settings.USER, settings.GROUP))

View File

@ -53,6 +53,9 @@ def dmerge(*args):
return dictionary
class SettingsValidationError(Exception): pass
class SettingsContainer(object):
"""
Singleton containing the settings for the whole app