From 678935bd0e8b45c528c80a97ddb8551ec3428187 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 2 Apr 2022 19:51:05 +0200 Subject: [PATCH 01/15] fix: catch standalone command exception gevent will not be installed by default, therefore print a message explaining required steps --- src/httpaste/__main__.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/httpaste/__main__.py b/src/httpaste/__main__.py index 399417f..24763f9 100644 --- a/src/httpaste/__main__.py +++ b/src/httpaste/__main__.py @@ -30,7 +30,14 @@ def command_standalone(**kwargs): """ from httpaste import load_config, get_flask_app - from gevent.pywsgi import WSGIServer + + try: + from gevent.pywsgi import WSGIServer + except ImportError as e: + raise ImportError(' '.join(( + 'gevent is currently not installed.', + 'Please install it by running \'python3 -m pip install gevent\'.' + ))) from e config, server_config = load_config(kwargs.get('config_path')) From 50af1a4587d1a6f965e1fbdb60601755857cfebb Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 2 Apr 2022 19:51:52 +0200 Subject: [PATCH 02/15] fix(__main__): require command argument --- src/httpaste/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/httpaste/__main__.py b/src/httpaste/__main__.py index 24763f9..7b6de2f 100644 --- a/src/httpaste/__main__.py +++ b/src/httpaste/__main__.py @@ -103,7 +103,7 @@ def parser(): p = argparse.ArgumentParser(description='Process some integers.') - sp = p.add_subparsers(dest='command') + sp = p.add_subparsers(dest='command', required=True) p_standalone = sp.add_parser('standalone', help=command_standalone.__doc__) p_standalone.add_argument('--config-path', '-c', required=True) From d367d43524c07501dba679fceaebcf38be1da812 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 2 Apr 2022 20:06:44 +0200 Subject: [PATCH 03/15] fix(schema): initialize module chore: upgrade version --- setup.cfg | 2 +- src/httpaste/schema/__init__.py | 0 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 src/httpaste/schema/__init__.py diff --git a/setup.cfg b/setup.cfg index d330606..f081dbf 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = httpaste-victorykit -version = 1.0.1-alpha +version = 1.0.3-alpha author = Tiara Rodney author_email = t.rodney@victoryk.it description = a versatile HTTP pastebin diff --git a/src/httpaste/schema/__init__.py b/src/httpaste/schema/__init__.py new file mode 100644 index 0000000..e69de29 From dfff5f15237e6ffb05941d7a67597714fadf12cb Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 2 Apr 2022 20:20:09 +0200 Subject: [PATCH 04/15] fix(setup.cfg): add schema data path --- setup.cfg | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup.cfg b/setup.cfg index f081dbf..802dfa7 100644 --- a/setup.cfg +++ b/setup.cfg @@ -37,3 +37,6 @@ console_scripts = [options.packages.find] where = src + +[options.package_data] +schema = src/httpaste/schema/httpaste.openapi.json \ No newline at end of file From 6e0229f34f2ac5f035dc3e8e6c9950884c5e32ac Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sun, 3 Apr 2022 01:29:42 +0200 Subject: [PATCH 05/15] fix(schema): add parameters to paste/private route chore: upgrade version resolves: HTTPASTE-32 --- setup.cfg | 4 ++-- src/httpaste/schema/httpaste.openapi.json | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/setup.cfg b/setup.cfg index 802dfa7..8c8ebc5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = httpaste-victorykit -version = 1.0.3-alpha +version = 1.0.4-alpha author = Tiara Rodney author_email = t.rodney@victoryk.it description = a versatile HTTP pastebin @@ -39,4 +39,4 @@ console_scripts = where = src [options.package_data] -schema = src/httpaste/schema/httpaste.openapi.json \ No newline at end of file +schema = src/httpaste/schema/httpaste.openapi.json diff --git a/src/httpaste/schema/httpaste.openapi.json b/src/httpaste/schema/httpaste.openapi.json index 163a57e..8f55586 100644 --- a/src/httpaste/schema/httpaste.openapi.json +++ b/src/httpaste/schema/httpaste.openapi.json @@ -161,6 +161,15 @@ }, { "$ref": "#/components/parameters/syntax" + }, + { + "$ref": "#/components/parameters/format" + }, + { + "$ref": "#/components/parameters/linenos" + }, + { + "$ref": "#/components/parameters/mime" } ], "responses": { From bdefd7e592d9bf7ed44fbbfa73649147ddea5ca8 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sun, 3 Apr 2022 03:48:18 +0200 Subject: [PATCH 06/15] refactor(setuptools): include sql schema fix(backend/sqlite): load files through importlib is required since package will be distributed as python egg chore: upgrade version --- setup.cfg | 5 +++-- src/httpaste/__main__.py | 9 +++++---- src/httpaste/backend/sqlite/paste.py | 3 ++- src/httpaste/backend/sqlite/user.py | 3 ++- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/setup.cfg b/setup.cfg index 8c8ebc5..62ebeae 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = httpaste-victorykit -version = 1.0.4-alpha +version = 1.0.5-alpha author = Tiara Rodney author_email = t.rodney@victoryk.it description = a versatile HTTP pastebin @@ -39,4 +39,5 @@ console_scripts = where = src [options.package_data] -schema = src/httpaste/schema/httpaste.openapi.json +openapi_schema = src/httpaste/schema/httpaste.openapi.json +sql_schema = *.sql diff --git a/src/httpaste/__main__.py b/src/httpaste/__main__.py index 436a46c..ec35404 100644 --- a/src/httpaste/__main__.py +++ b/src/httpaste/__main__.py @@ -2,6 +2,7 @@ """ import argparse import os +from importlib.resources import open_text def _this_dir(basename: str) -> str: @@ -20,7 +21,7 @@ def _path_output(path, echo: bool = False) -> str: return path else: - with open(path, 'r') as fh: + with open_text('httpaste', path) as fh: return fh.read() @@ -51,21 +52,21 @@ def command_wsgi(**kwargs): """get WSGI script """ - print(_path_output(_this_dir('wsgi.py'), kwargs.get('echo'))) + print(_path_output('wsgi.py', kwargs.get('echo'))) def command_cgi(**kwargs): """get CGI script """ - print(_path_output(_this_dir('cgi.py'), kwargs.get('echo'))) + print(_path_output('cgi.py', kwargs.get('echo'))) def command_fcgi(**kwargs): """get FastCGI script """ - print(_path_output(_this_dir('fcgi.py'), kwargs.get('echo'))) + print(_path_output('fcgi.py', kwargs.get('echo'))) def command_default_config(**kwargs): diff --git a/src/httpaste/backend/sqlite/paste.py b/src/httpaste/backend/sqlite/paste.py index bb0eb17..51c9fc6 100644 --- a/src/httpaste/backend/sqlite/paste.py +++ b/src/httpaste/backend/sqlite/paste.py @@ -3,6 +3,7 @@ from os import path from sqlite3 import Connection from time import time +from importlib.resources import open_text def load(proto: object, connection: Connection, model_class: type): @@ -63,7 +64,7 @@ def init(connection: Connection): cur = connection.cursor() - with open(path.join(path.dirname(__file__), 'paste.sql'), 'r') as fh: + with open_text('httpaste.backend.sqlite', 'paste.sql') as fh: cur.execute(fh.read()) diff --git a/src/httpaste/backend/sqlite/user.py b/src/httpaste/backend/sqlite/user.py index 11fc53e..e4f712d 100644 --- a/src/httpaste/backend/sqlite/user.py +++ b/src/httpaste/backend/sqlite/user.py @@ -3,6 +3,7 @@ from os import path from sqlite3 import Connection from httpaste.model import User +from importlib.resources import open_text def load(proto: User, connection: Connection): @@ -48,7 +49,7 @@ def init(connection: Connection): cur = connection.cursor() - with open(path.join(path.dirname(__file__), 'user.sql'), 'r') as fh: + with open_text('httpaste.backend.sqlite', 'user.sql') as fh: cur.execute(fh.read()) From fc367ed4cb25da544ca119509c956f88eb52b8b6 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sun, 3 Apr 2022 04:29:23 +0200 Subject: [PATCH 07/15] fix(wsgi+config): fault environment setup chore: upgrade version --- setup.cfg | 2 +- src/httpaste/__init__.py | 17 +++++++++++++---- src/httpaste/wsgi.py | 2 +- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/setup.cfg b/setup.cfg index 62ebeae..af12e9a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = httpaste-victorykit -version = 1.0.5-alpha +version = 1.0.6-alpha author = Tiara Rodney author_email = t.rodney@victoryk.it description = a versatile HTTP pastebin diff --git a/src/httpaste/__init__.py b/src/httpaste/__init__.py index 6eea5ba..3a4cb21 100755 --- a/src/httpaste/__init__.py +++ b/src/httpaste/__init__.py @@ -143,6 +143,7 @@ from inspect import isclass from configparser import ConfigParser from ast import literal_eval from io import StringIO +from os import environ from connexion import FlaskApp from connexion.resolver import RestyResolver @@ -158,7 +159,7 @@ from httpaste.helper.http import ( UnauthorizedError) -CONFIGPATH_ENVIRON = 'HTTPASTE_CONFIG' +CONFIGPATH_ENVIRON = 'HTTPASTE_CONFIGPATH' def get_sanitized_config_charset(charset: str): @@ -198,17 +199,17 @@ class ServerConfig: bind_address = None -def get_config_path(environ: str = CONFIGPATH_ENVIRON): +def get_config_path(var_name: str = CONFIGPATH_ENVIRON): """ """ try: - return os.environ[environ] + return environ[var_name] except KeyError as e: raise ConfigError( - 'environment variable \'{environ}\' not set.') from e + f'environment variable \'{var_name}\' not set.') from e def load_config(path: str) -> Tuple[Config, ServerConfig]: @@ -322,6 +323,14 @@ def get_flask_app( with application.app.app_context(): application.app.httpaste = config + #add header for browsers to present a sign-in prompt + @application.app.after_request + def rewrite_forbidden_request(response): + + if response.status_code in [401]: + response.headers['WWW-Authenticate'] = 'Basic realm="private"' + return response + return application diff --git a/src/httpaste/wsgi.py b/src/httpaste/wsgi.py index e45f821..9e43ff0 100755 --- a/src/httpaste/wsgi.py +++ b/src/httpaste/wsgi.py @@ -3,6 +3,6 @@ """ from httpaste import load_config, get_flask_app, get_config_path -config, server_config = load_config(get_config_path) +config, server_config = load_config(get_config_path()) application = get_flask_app(config, server_config) From 65f50770959c0d877d8f138d44f10884cc973905 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sun, 3 Apr 2022 16:15:14 +0200 Subject: [PATCH 08/15] fix(init): add importlib context to connexion init connexion openapi spec reference now provided through importlib context manager, since file will exist inside of python egg, therefore not being accesible through package file path chore: upgrade version --- setup.cfg | 2 +- src/httpaste/__init__.py | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/setup.cfg b/setup.cfg index af12e9a..0382db4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = httpaste-victorykit -version = 1.0.6-alpha +version = 1.0.7-alpha author = Tiara Rodney author_email = t.rodney@victoryk.it description = a versatile HTTP pastebin diff --git a/src/httpaste/__init__.py b/src/httpaste/__init__.py index 3a4cb21..ca5aeff 100755 --- a/src/httpaste/__init__.py +++ b/src/httpaste/__init__.py @@ -144,6 +144,7 @@ from configparser import ConfigParser from ast import literal_eval from io import StringIO from os import environ +from importlib.resources import path as pkg_resource_path from connexion import FlaskApp from connexion.resolver import RestyResolver @@ -301,13 +302,15 @@ def get_flask_app( options = {"swagger_ui": server_config.swagger_ui} - application = FlaskApp(__name__, specification_dir='schema/') + #context manager returns a pathlib.Path object + with pkg_resource_path('httpaste.schema', 'httpaste.openapi.json') as path: + application = FlaskApp(__name__, specification_dir=path.parent) - application.add_api( - 'httpaste.openapi.json', - options=options, - resolver=RestyResolver('httpaste.controller') - ) + application.add_api( + path.name, + options=options, + resolver=RestyResolver('httpaste.controller') + ) for err_cls in [ BadRequestError, From e330bbf70a67ee62cfeca77a8d3a77800a2220a1 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sun, 3 Apr 2022 16:47:47 +0200 Subject: [PATCH 09/15] fix(init): add custom context manager for pkg resources chore: upgrade version --- setup.cfg | 2 +- src/httpaste/__init__.py | 6 +++--- src/httpaste/helper/common.py | 32 +++++++++++++++++++++++++++++++- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/setup.cfg b/setup.cfg index 0382db4..d05333e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = httpaste-victorykit -version = 1.0.7-alpha +version = 1.0.8-alpha author = Tiara Rodney author_email = t.rodney@victoryk.it description = a versatile HTTP pastebin diff --git a/src/httpaste/__init__.py b/src/httpaste/__init__.py index ca5aeff..999721b 100755 --- a/src/httpaste/__init__.py +++ b/src/httpaste/__init__.py @@ -144,14 +144,13 @@ from configparser import ConfigParser from ast import literal_eval from io import StringIO from os import environ -from importlib.resources import path as pkg_resource_path from connexion import FlaskApp from connexion.resolver import RestyResolver from httpaste.model import Backend from httpaste.backend import get_backend_map -from httpaste.helper.common import generate_random_string +from httpaste.helper.common import (generate_random_string, tmp_pkg_resource_text_path) from httpaste.helper.http import ( BadRequestError, ForbiddenError, @@ -303,7 +302,8 @@ def get_flask_app( options = {"swagger_ui": server_config.swagger_ui} #context manager returns a pathlib.Path object - with pkg_resource_path('httpaste.schema', 'httpaste.openapi.json') as path: + with tmp_pkg_resource_text_path('httpaste.schema', 'httpaste.openapi.json') as path: + application = FlaskApp(__name__, specification_dir=path.parent) application.add_api( diff --git a/src/httpaste/helper/common.py b/src/httpaste/helper/common.py index 92cc6d7..8edacd1 100644 --- a/src/httpaste/helper/common.py +++ b/src/httpaste/helper/common.py @@ -1,6 +1,11 @@ from random import choice from base64 import b64decode from urllib.parse import urljoin +from importlib.resources import read_text +from tempfile import mkdtemp +from pathlib import Path +from contextlib import contextmanager + class DecodeError(Exception): """ @@ -29,4 +34,29 @@ def decode(data: str, encoding: str) -> bytes: def join_url(base:str, url: str) -> str: - return urljoin(base, url, True) \ No newline at end of file + return urljoin(base, url, True) + + +@contextmanager +def tmp_pkg_resource_text_path(package:str, resource:str) -> Path: + """context manager for accessing package resources from a real path + + this applies to the circumstance of the package living inside of an + egg and therefore is unable to provide real existing paths to any + module that may require it. + + :param package: dot seperated package name + :param resource: basename of resource inside package + + :returns: a Path-like object + """ + data = read_text(package, resource) + tmp_dirname = mkdtemp() + tmp_dirpath = Path(tmp_dirname) + tmp_file = tmp_dirpath.joinpath(resource) + tmp_file.write_text(data) + try: + yield tmp_file + finally: + tmp_file.unlink() + tmp_dirpath.rmdir() \ No newline at end of file From ecd7d03a20e5f9cd9dc57835d053bcaa93b0cd60 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sun, 3 Apr 2022 17:11:15 +0200 Subject: [PATCH 10/15] fix(init): again, distutils... is confusing non-script files should now be, hopefully, included in bdist and sdist chore: upgrade version --- MANIFEST.in | 2 ++ setup.cfg | 5 +---- 2 files changed, 3 insertions(+), 4 deletions(-) create mode 100644 MANIFEST.in diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..75d6607 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,2 @@ +recursive-include src/httpaste/schema *.json +recursive-incude src/httpaste/backend *.sql diff --git a/setup.cfg b/setup.cfg index d05333e..915d670 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = httpaste-victorykit -version = 1.0.8-alpha +version = 1.0.9-alpha author = Tiara Rodney author_email = t.rodney@victoryk.it description = a versatile HTTP pastebin @@ -38,6 +38,3 @@ console_scripts = [options.packages.find] where = src -[options.package_data] -openapi_schema = src/httpaste/schema/httpaste.openapi.json -sql_schema = *.sql From a4116832e7a7819358e05eac3bb71d91fe77c6c9 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 8 Apr 2022 20:49:39 +0200 Subject: [PATCH 11/15] fix(build-toolchain): migrate versioning to setuptools_scm versioning of package now handled through setuptools_scm. Git tag therefore takes precedence and manually setting a version in setup.cfg is redundant. In addition, setuptools_scm handles proper inclusion of sdist non-python files and simplifies bdist packaging. --- .gitignore | 4 +++- MANIFEST.in | 2 -- pyproject.toml | 7 +++++-- setup.cfg | 5 ++++- 4 files changed, 12 insertions(+), 6 deletions(-) delete mode 100644 MANIFEST.in diff --git a/.gitignore b/.gitignore index 0ec6dc9..e2bd56f 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,6 @@ **/__pycache__/ .DS_Store .coverage -/*.md \ No newline at end of file +/*.md +/.eggs/ +/devel/ \ No newline at end of file diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 75d6607..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,2 +0,0 @@ -recursive-include src/httpaste/schema *.json -recursive-incude src/httpaste/backend *.sql diff --git a/pyproject.toml b/pyproject.toml index 9111d02..cb91714 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,8 @@ [build-system] requires = [ "setuptools", - "wheel" + "wheel", + "setuptools-scm[toml]" ] build-backend = "setuptools.build_meta" @@ -9,4 +10,6 @@ build-backend = "setuptools.build_meta" max_line_length = 80 aggressive = 3 recursive = true -in-place = true \ No newline at end of file +in-place = true + +[tool.setuptools_scm] diff --git a/setup.cfg b/setup.cfg index 915d670..465a26b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,5 @@ [metadata] name = httpaste-victorykit -version = 1.0.9-alpha author = Tiara Rodney author_email = t.rodney@victoryk.it description = a versatile HTTP pastebin @@ -38,3 +37,7 @@ console_scripts = [options.packages.find] where = src +[options.package_data] +* = + *.json + *.sql \ No newline at end of file From c8dffbbdf893961a988421bd122089dcae0d1268 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 8 Apr 2022 21:01:33 +0200 Subject: [PATCH 12/15] refactor(__init__): reset context manager for flask app with proper bdist setup, it shouldn't be necessary to wrap path of importlib, since the context manager will handle egg extraction itself. Hopefully... --- src/httpaste/__init__.py | 3 ++- src/httpaste/helper/common.py | 26 -------------------------- 2 files changed, 2 insertions(+), 27 deletions(-) diff --git a/src/httpaste/__init__.py b/src/httpaste/__init__.py index 999721b..92c55a5 100755 --- a/src/httpaste/__init__.py +++ b/src/httpaste/__init__.py @@ -144,6 +144,7 @@ from configparser import ConfigParser from ast import literal_eval from io import StringIO from os import environ +from importlib.resources import path as resource_path from connexion import FlaskApp from connexion.resolver import RestyResolver @@ -302,7 +303,7 @@ def get_flask_app( options = {"swagger_ui": server_config.swagger_ui} #context manager returns a pathlib.Path object - with tmp_pkg_resource_text_path('httpaste.schema', 'httpaste.openapi.json') as path: + with resource_path('httpaste.schema', 'httpaste.openapi.json') as path: application = FlaskApp(__name__, specification_dir=path.parent) diff --git a/src/httpaste/helper/common.py b/src/httpaste/helper/common.py index 8edacd1..2e6d1c7 100644 --- a/src/httpaste/helper/common.py +++ b/src/httpaste/helper/common.py @@ -1,7 +1,6 @@ from random import choice from base64 import b64decode from urllib.parse import urljoin -from importlib.resources import read_text from tempfile import mkdtemp from pathlib import Path from contextlib import contextmanager @@ -35,28 +34,3 @@ def decode(data: str, encoding: str) -> bytes: def join_url(base:str, url: str) -> str: return urljoin(base, url, True) - - -@contextmanager -def tmp_pkg_resource_text_path(package:str, resource:str) -> Path: - """context manager for accessing package resources from a real path - - this applies to the circumstance of the package living inside of an - egg and therefore is unable to provide real existing paths to any - module that may require it. - - :param package: dot seperated package name - :param resource: basename of resource inside package - - :returns: a Path-like object - """ - data = read_text(package, resource) - tmp_dirname = mkdtemp() - tmp_dirpath = Path(tmp_dirname) - tmp_file = tmp_dirpath.joinpath(resource) - tmp_file.write_text(data) - try: - yield tmp_file - finally: - tmp_file.unlink() - tmp_dirpath.rmdir() \ No newline at end of file From 2762d6d67ff8a5984178aafd332f0fb1b369815c Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 8 Apr 2022 21:03:35 +0200 Subject: [PATCH 13/15] docs(guide/getting-started): init --- docs/guide/getting-started.rst | 73 ++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 docs/guide/getting-started.rst diff --git a/docs/guide/getting-started.rst b/docs/guide/getting-started.rst new file mode 100644 index 0000000..431fa2b --- /dev/null +++ b/docs/guide/getting-started.rst @@ -0,0 +1,73 @@ +Getting Started +=============== + +Install +""""""" + +.. code-block:: shell + + $ python3 -m pip install httpaste-victorykit + $ httpaste --help + +.. note:: + httpaste is publicly available at `https://httpaste.it`_, and can be accessed + over the TOR network via `https://pastefao6mwyafs3cznoe2u2a6iizw5laulrznla3dytcnvaizte73yd.onion`_ aswell. Both are hosted on different servers of different service providers. + +Create Configuration +"""""""""""""""""""" + +.. code-block:: shell + + $ httpaste default-config --dump myconfig.ini + +.. note:: + The default configuration creates an in-memory SQLite backend, which is not + suitable for WWW deployments. Visit `backend`, for more + information on configuring the backend. + + +Run a Local Evaluation Server +""""""""""""""""""""""""""""" + +.. code-block:: shell + + $ httpaste standalone --config myconfig.ini --port 8080 + + +Publish a Private Paste +""""""""""""""""""""""" + +.. code-block:: shell + + $ echo 'My first private paste' | curl -F 'data=<-' -u myusername:mypassword http://localhost:8080/paste/private + http://localhost:8080/paste/private/UALUA9 + +.. note:: + If the user does not exist, they will be created upon authentication. + + +Retrieve a Private Paste +"""""""""""""""""""""""" + +.. code-block:: shell + + $ curl -u myusername:mypassword http://localhost:8080/paste/private/UALUA9 + My first private paste + + +Publish a Public Paste +"""""""""""""""""""""" + +.. code-block:: shell + + $ echo 'My first public paste' | curl -F 'data=<-' http://localhost:8080/paste/public + http://localhost:8080/paste/public/X4L39J + + +Retrieve a Public Paste +"""""""""""""""""""""""" + +.. code-block:: shell + + $ curl http://localhost:8080/paste/public/X4L39J + My first public paste \ No newline at end of file From f3a3e9516387fc8f8c23d32c2c29418b341c89a3 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Fri, 8 Apr 2022 21:25:36 +0200 Subject: [PATCH 14/15] fix(init): remove non-existing common import --- src/httpaste/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/httpaste/__init__.py b/src/httpaste/__init__.py index 92c55a5..14f2385 100755 --- a/src/httpaste/__init__.py +++ b/src/httpaste/__init__.py @@ -151,7 +151,7 @@ from connexion.resolver import RestyResolver from httpaste.model import Backend from httpaste.backend import get_backend_map -from httpaste.helper.common import (generate_random_string, tmp_pkg_resource_text_path) +from httpaste.helper.common import generate_random_string from httpaste.helper.http import ( BadRequestError, ForbiddenError, From 89c1a67a47d6d797538abd73774a7e86d7faeb57 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 9 Apr 2022 04:16:52 +0200 Subject: [PATCH 15/15] docs: sound less like a smart-ass sales person --- README.md | 46 +++++++++++++--------- docs/README.rst | 53 ++++++++++++++++--------- docs/guide/get-started.rst | 70 ---------------------------------- docs/guide/getting-started.rst | 3 -- docs/index.rst | 2 +- 5 files changed, 65 insertions(+), 109 deletions(-) delete mode 100644 docs/guide/get-started.rst diff --git a/README.md b/README.md index 030d58b..8be40cf 100644 --- a/README.md +++ b/README.md @@ -2,28 +2,40 @@ ![](docs/_assets/images/favpng_parrot-royalty-free-cartoon.png) -httpaste is a pastebin application for easily pasting and retrieving data over -HTTP from shell environments and web browsers. It is inspired by [sprunge.us](http://sprunge.us) -and [ix.io](http://ix.io/), but focuses on extendability, advanced security, with little to -no trade-off to simplicity. It can be hosted through WSGI, CGI, Fast CGI, or -as a standalone evaluation server. It offers multiple storage backends, such as -a filesystem backend, SQLite backend, MySQL backend, or MongoDB backend. +**NOTE**: httpaste is publicly hosted at [httpaste.it](http://httpaste.it) and as a hidden Tor service ([https://paste77ubkwxy4fqezffsmthxdh3xerwi72tlsw2mch7ecjhw2xn7iyd.onion](https://paste77ubkwxy4fqezffsmthxdh3xerwi72tlsw2mch7ecjhw2xn7iyd.onion)). +Both services are to be considered evaluatory, as long as the source code +is in pre-release. Regarding voidance of pre-release status, see [Open Issues](https://victorykit.atlassian.net/issues/?jql=project%20%3D%20HTTPASTE%20AND%20fixVersion%20in%20(1.1.0-beta%2C%201.2.0-beta%2C%201.3.0)), for more information. -All pastes are being encrypted on the fly and can only be retrieved by an -authorized user, either through knowing the paste id of a public paste, or -having authentication credentials, as well as the paste id of a private paste. -This makes httpaste ideal as a pastebin for sensitive environments such as the -Tor network. Authentication credentials are created on-the-fly and don’t require a sign-up process. +This program offers an HTTP interface for storing public and private data +(a.k.a. pastes), commonly referred to as a pastebin application. It is inspired by [sprunge.us](http://sprunge.us) and [ix.io](http://ix.io/). It can be hosted through WSGI, CGI, Fast +CGI, or as a standalone evaluation server. It offers multiple storage backends, +such as a filesystem backend, SQLite backend, or MySQL backend. -httpaste supports output formatting for syntax highlighting (powered by +Public data can be accessed through an URL, where as private pastes +additionally require HTTP basic authentication. Creation of authentication +credentials happens on the fly, there is no sign-up process. Public pastes can +only be accessed by knowing their paste ids, they are not listed on any index, +since it isn’t technically possible (by design). + +All pastes are symetrically encrypted server-side with an HMAC derived key and +SHA-256 hashing, a server-side salt and a randomly generated password. Public +paste’s passwords are derived from their ids. Private paste’s passwords are +randomly generated and stored inside a symetrically encrypted personal +database, with the encryption key also being derived through the same HMAC +mechanism, where the HTTP basic authentication credentials act as the master +password. + +Paste ids, usernames, and any other identifiable attributes are only stored +inside storage backends as keyed and salted BLAKE2 hashes. + +The program supports output formatting for syntax highlighting (powered by [pygments](https://pygments.org/)), as well as MIME type output manipulation, and input encoding. -Therefore httpaste can server as an anonymous object storage for small data. +The program can therefore serve as a minimalist, anonymous object storage for +small data. -Minute-based and ‘burn-after-read’ paste expiration are supported. +Minute-based and ‘burn-after-read’ paste expiration are also supported. -httpaste focuses on security through cryptography, making it a computationally intensive application. - -# Get Started +# Getting Started ## Install diff --git a/docs/README.rst b/docs/README.rst index 0bf034c..96f45f3 100644 --- a/docs/README.rst +++ b/docs/README.rst @@ -9,28 +9,41 @@ httpaste - versatile HTTP pastebin .. image:: _assets/images/favpng_parrot-royalty-free-cartoon.png -httpaste is a pastebin application for easily pasting and retrieving data over -HTTP from shell environments and web browsers. It is inspired by `sprunge.us`_ -and `ix.io`_, but focuses on extendability, advanced security, with little to -no trade-off to simplicity. It can be hosted through WSGI, CGI, Fast CGI, or -as a standalone evaluation server. It offers multiple storage backends, such as -a filesystem backend, SQLite backend, MySQL backend, or MongoDB backend. +.. note:: + httpaste is publicly hosted at `httpaste.it`_ and as a hidden Tor service (``_). + Both services are to be considered evaluatory, as long as the source code + is in pre-release. Regarding voidance of pre-release status, see `Open Issues`_, for more information. -All pastes are being encrypted on the fly and can only be retrieved by an -authorized user, either through knowing the paste id of a public paste, or -having authentication credentials, as well as the paste id of a private paste. -This makes httpaste ideal as a pastebin for sensitive environments such as the -Tor network. Authentication credentials are created on-the-fly and don't require a sign-up process. +This program offers an HTTP interface for storing public and private data +(a.k.a. pastes), commonly referred to as a pastebin application. It is inspired by `sprunge.us`_ and `ix.io`_. It can be hosted through WSGI, CGI, Fast +CGI, or as a standalone evaluation server. It offers multiple storage backends, +such as a filesystem backend, SQLite backend, or MySQL backend. -httpaste supports output formatting for syntax highlighting (powered by +Public data can be accessed through an URL, where as private pastes +additionally require HTTP basic authentication. Creation of authentication +credentials happens on the fly, there is no sign-up process. Public pastes can +only be accessed by knowing their paste ids, they are not listed on any index, +since it isn't technically possible (by design). + +All pastes are symetrically encrypted server-side with an HMAC derived key and +SHA-256 hashing, a server-side salt and a randomly generated password. Public +paste's passwords are derived from their ids. Private paste's passwords are +randomly generated and stored inside a symetrically encrypted personal +database, with the encryption key also being derived through the same HMAC +mechanism, where the HTTP basic authentication credentials act as the master +password. + +Paste ids, usernames, and any other identifiable attributes are only stored +inside storage backends as keyed and salted BLAKE2 hashes. + +The program supports output formatting for syntax highlighting (powered by `pygments`_), as well as MIME type output manipulation, and input encoding. -Therefore httpaste can server as an anonymous object storage for small data. +The program can therefore serve as a minimalist, anonymous object storage for +small data. -Minute-based and 'burn-after-read' paste expiration are supported. +Minute-based and 'burn-after-read' paste expiration are also supported. -httpaste focuses on security through cryptography, making it a computationally intensive application. - -.. include:: guide/get-started.rst +.. include:: guide/getting-started.rst Documentation ------------- @@ -69,4 +82,8 @@ This program uses licensed third-party software. .. _ix.io: http://ix.io/ .. _sprunge.us: http://sprunge.us .. _pygments: https://pygments.org/ -.. _icon: https://favpng.com/png_view/parrot-parrot-royalty-free-cartoon-png/gps7HM42 \ No newline at end of file +.. _icon: https://favpng.com/png_view/parrot-parrot-royalty-free-cartoon-png/gps7HM42 + +.. _Open Issues: https://victorykit.atlassian.net/issues/?jql=project%20%3D%20HTTPASTE%20AND%20fixVersion%20in%20(1.1.0-beta%2C%201.2.0-beta%2C%201.3.0) + +.. _httpaste.it: http://httpaste.it \ No newline at end of file diff --git a/docs/guide/get-started.rst b/docs/guide/get-started.rst deleted file mode 100644 index 0bbeedc..0000000 --- a/docs/guide/get-started.rst +++ /dev/null @@ -1,70 +0,0 @@ -Get Started -=========== - -Install -""""""" - -.. code-block:: shell - - $ python3 -m pip install httpaste-victorykit - $ httpaste --help - - -Create Configuration -"""""""""""""""""""" - -.. code-block:: shell - - $ httpaste default-config --dump myconfig.ini - -.. note:: - The default configuration creates an in-memory SQLite backend, which is not - suitable for WWW deployments. Visit `backend`, for more - information on configuring the backend. - - -Run a Local Evaluation Server -""""""""""""""""""""""""""""" - -.. code-block:: shell - - $ httpaste standalone --config myconfig.ini --port 8080 - - -Publish a Private Paste -""""""""""""""""""""""" - -.. code-block:: shell - - $ echo 'My first private paste' | curl -F 'data=<-' -u myusername:mypassword http://localhost:8080/paste/private - http://localhost:8080/paste/private/UALUA9 - -.. note:: - If the user does not exist, they will be created upon authentication. - - -Retrieve a Private Paste -"""""""""""""""""""""""" - -.. code-block:: shell - - $ curl -u myusername:mypassword http://localhost:8080/paste/private/UALUA9 - My first private paste - - -Publish a Public Paste -"""""""""""""""""""""" - -.. code-block:: shell - - $ echo 'My first public paste' | curl -F 'data=<-' http://localhost:8080/paste/public - http://localhost:8080/paste/public/X4L39J - - -Retrieve a Public Paste -"""""""""""""""""""""""" - -.. code-block:: shell - - $ curl http://localhost:8080/paste/public/X4L39J - My first public paste \ No newline at end of file diff --git a/docs/guide/getting-started.rst b/docs/guide/getting-started.rst index 431fa2b..048f06a 100644 --- a/docs/guide/getting-started.rst +++ b/docs/guide/getting-started.rst @@ -9,9 +9,6 @@ Install $ python3 -m pip install httpaste-victorykit $ httpaste --help -.. note:: - httpaste is publicly available at `https://httpaste.it`_, and can be accessed - over the TOR network via `https://pastefao6mwyafs3cznoe2u2a6iizw5laulrznla3dytcnvaizte73yd.onion`_ aswell. Both are hosted on different servers of different service providers. Create Configuration """""""""""""""""""" diff --git a/docs/index.rst b/docs/index.rst index bb9e5a0..6b0a60b 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -4,7 +4,7 @@ :maxdepth: 1 :caption: Guides - guide/get-started + guide/getting-started guide/advanced-usage guide/backend guide/cli