diff --git a/src/httpaste/controller/ui/__init__.py b/src/httpaste/controller/ui/__init__.py index c1b52c2..23890e6 100644 --- a/src/httpaste/controller/ui/__init__.py +++ b/src/httpaste/controller/ui/__init__.py @@ -7,7 +7,10 @@ def search(**kwargs): variables = { 'paste_index_url': '/ui/paste', - 'man_page': man_page + 'user_index_url': '/ui/user', + 'man_page': man_page, + 'user': kwargs.get('user'), + 'delete_session_url': '/ui/user/session/delete' } return template.render(**variables), 200 \ No newline at end of file diff --git a/src/httpaste/controller/ui/paste/__init__.py b/src/httpaste/controller/ui/paste/__init__.py index 4d63bfd..e743a4c 100644 --- a/src/httpaste/controller/ui/paste/__init__.py +++ b/src/httpaste/controller/ui/paste/__init__.py @@ -5,6 +5,9 @@ from connexion import request from httpaste.helper.template import views from httpaste.helper.url import url_query_string, url_append_query_param +from httpaste.helper.syntax import syntax_shortnames, format_shortnames +from httpaste.helper.http import mime_types + from httpaste.controller.paste import post as post_raw from httpaste.controller.paste import get as get_raw @@ -54,8 +57,6 @@ def get(**kwargs): template = views.get_template("viewport/ui/paste/get.html") - - base_path = f'paste/public/{kwargs["id"]}' if kwargs.get('user'): @@ -86,7 +87,10 @@ def get(**kwargs): 'syntax': kwargs.get('syntax', ''), 'mime': kwargs.get('mime', ''), 'preview': kwargs.get('preview', True) - } + }, + 'syntax_shortnames': syntax_shortnames(), + 'format_shortnames': format_shortnames(), + 'mime_types': mime_types() } return template.render(**variables) \ No newline at end of file diff --git a/src/httpaste/controller/ui/user/__init__.py b/src/httpaste/controller/ui/user/__init__.py index e69de29..6c6d86a 100644 --- a/src/httpaste/controller/ui/user/__init__.py +++ b/src/httpaste/controller/ui/user/__init__.py @@ -0,0 +1,12 @@ +from httpaste.helper.template import views +from httpaste import __doc__ as man_page + +def search(**kwargs): + + template = views.get_template("viewport/ui/user/search.html") + + variables = { + 'delete_session_url': '/ui/user/session/delete' + } + + return template.render(**variables), 200 \ No newline at end of file diff --git a/src/httpaste/helper/http.py b/src/httpaste/helper/http.py index 050cd00..2e00d6f 100644 --- a/src/httpaste/helper/http.py +++ b/src/httpaste/helper/http.py @@ -1,3 +1,4 @@ +from mimetypes import types_map as mime_types_map class BadRequestError(RuntimeError): def __init__(self, msg=None): @@ -62,3 +63,11 @@ class NotFoundError(RuntimeError): "status": 404, "title": "Not Found", }, 404 + + +def mime_types(): + + types = list(set(mime_types_map.values())) + types.sort() + + return types \ No newline at end of file diff --git a/src/httpaste/helper/syntax.py b/src/httpaste/helper/syntax.py index d1ed048..c939267 100644 --- a/src/httpaste/helper/syntax.py +++ b/src/httpaste/helper/syntax.py @@ -1,5 +1,5 @@ -from pygments.lexers import get_lexer_by_name, find_lexer_class_by_name -from pygments.formatters import find_formatter_class, HtmlFormatter +from pygments.lexers import (get_lexer_by_name, find_lexer_class_by_name, get_all_lexers) +from pygments.formatters import (find_formatter_class, HtmlFormatter, get_all_formatters) def highlight( @@ -18,3 +18,13 @@ def highlight( formatter = find_formatter_class(format_alias)(linenos=linenos) return highlight(data, get_lexer_by_name(lexer_alias), formatter) + + +def syntax_shortnames(): + + return {l[0]:l[1][0] for l in get_all_lexers() if len(l[1]) > 0} + + +def format_shortnames(): + + return [f.aliases[0] for f in get_all_formatters()] \ No newline at end of file diff --git a/src/httpaste/helper/template.py b/src/httpaste/helper/template.py index 446418a..1ae6d0e 100644 --- a/src/httpaste/helper/template.py +++ b/src/httpaste/helper/template.py @@ -1,6 +1,6 @@ from jinja2 import Environment, PackageLoader, select_autoescape views = Environment( - loader=PackageLoader("httpaste", "views"), + loader=PackageLoader("httpaste", "view"), autoescape=select_autoescape() ) \ No newline at end of file diff --git a/src/httpaste/schema/httpaste.openapi.json b/src/httpaste/schema/httpaste.openapi.json index 508fa5e..35ef3ec 100644 --- a/src/httpaste/schema/httpaste.openapi.json +++ b/src/httpaste/schema/httpaste.openapi.json @@ -388,6 +388,9 @@ }, { "$ref": "#/components/parameters/mime" + }, + { + "$ref": "#/components/parameters/ui_preview" } ], "responses": { @@ -422,6 +425,22 @@ } } }, + "/ui/user": { + "get": { + "description": "get a public paste", + "security": [ + {} + ], + "responses": { + "200": { + "description": "paste data. content type may vary.", + "content": { + "text/html": {} + } + } + } + } + }, "/ui/user/session/delete": { "get": { "description": "get a public paste", diff --git a/src/httpaste/view/container/get_paste_form.html b/src/httpaste/view/container/get_paste_form.html new file mode 100644 index 0000000..9d3d8b4 --- /dev/null +++ b/src/httpaste/view/container/get_paste_form.html @@ -0,0 +1,39 @@ +
+
+ + + + + + + language to highlight syntax for +
+
+ + + + + output format of highlighted syntax +
+
+ + + + + content-type Header the server should return +
+ + +
\ No newline at end of file diff --git a/src/httpaste/view/container/post_paste_form.html b/src/httpaste/view/container/post_paste_form.html new file mode 100644 index 0000000..153a06a --- /dev/null +++ b/src/httpaste/view/container/post_paste_form.html @@ -0,0 +1,26 @@ +
+
+ + + + + Either supply a past text, or upload a file. + +
+
+ + + + + Set a paste’s lifetime to make it expire after a specified amount of time. + The lifetime must be provided in minutes and cannot be less than 1 (, unless lesser than 0). + A lifetime of 0 will evaluate to a lifetime 1. A lifetime of less than 0 will make the paste expire after first read. + +
+ +
\ No newline at end of file diff --git a/src/httpaste/view/frame/base.html b/src/httpaste/view/frame/base.html new file mode 100644 index 0000000..4a2060a --- /dev/null +++ b/src/httpaste/view/frame/base.html @@ -0,0 +1,16 @@ + + + + + + + + + +
+ {% block content %}{% endblock %} +
+ + \ No newline at end of file diff --git a/src/httpaste/view/frame/decorated.html b/src/httpaste/view/frame/decorated.html new file mode 100644 index 0000000..d7c6cf7 --- /dev/null +++ b/src/httpaste/view/frame/decorated.html @@ -0,0 +1,29 @@ + + + + + + + + +
+ {% block header %}{% endblock %} +
+
+
+ {% block content %}{% endblock %} +
+ + \ No newline at end of file diff --git a/src/httpaste/view/viewport/ui/paste/get.html b/src/httpaste/view/viewport/ui/paste/get.html new file mode 100644 index 0000000..b9cac69 --- /dev/null +++ b/src/httpaste/view/viewport/ui/paste/get.html @@ -0,0 +1,36 @@ +{% extends 'frame/decorated.html' %} +{% block header %} +

httpaste - Paste - Conditioner

+

+ Preview and conditon an existing paste +

+{% endblock %} +{% block content %} + + {% if query['preview'] %} + Preview + + {% else %} +

Preview is disabled. +
+ This probably happened because the paste is set to expire after read. +
+ You can still proceed to condition the paste URL. +

+ {% endif %} + {% include 'container/get_paste_form.html' %} +
+
+
URLs
+
+
Formatted
+
+ {{paste_url}} +
+
Raw
+
+ {{raw_paste_url}} +
+
+
+{% endblock %} \ No newline at end of file diff --git a/src/httpaste/view/viewport/ui/paste/private/search.html b/src/httpaste/view/viewport/ui/paste/private/search.html new file mode 100644 index 0000000..6d43869 --- /dev/null +++ b/src/httpaste/view/viewport/ui/paste/private/search.html @@ -0,0 +1,14 @@ +{% extends 'frame/decorated.html' %} + +{% block header %} +

httpaste - Paste - Private

+ +

+ Private pastes are authenticated +

+{% endblock %} +{% block content %} +{% include 'container/post_paste_form.html' %} + + +{% endblock %} \ No newline at end of file diff --git a/src/httpaste/view/viewport/ui/paste/public/search.html b/src/httpaste/view/viewport/ui/paste/public/search.html new file mode 100644 index 0000000..5036269 --- /dev/null +++ b/src/httpaste/view/viewport/ui/paste/public/search.html @@ -0,0 +1,14 @@ +{% extends 'frame/decorated.html' %} + +{% block header %} +

httpaste - Paste - Public

+

+ Public pastes are not indexed and can only be accessed by knowing their respective + paste id. +

+{% endblock %} +{% block content %} +{% include 'container/post_paste_form.html' %} + + +{% endblock %} \ No newline at end of file diff --git a/src/httpaste/view/viewport/ui/paste/search.html b/src/httpaste/view/viewport/ui/paste/search.html new file mode 100644 index 0000000..549bc74 --- /dev/null +++ b/src/httpaste/view/viewport/ui/paste/search.html @@ -0,0 +1,36 @@ +{% extends 'frame/decorated.html' %} + +{% block header %} +

httpaste - Paste

+ +

+ 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 a HTTP basic authentication act as the master password. + Paste ids, usernames, and any other identifiable attributes are only stored + inside the storage backend as keyed and salted BLAKE2 hashes. +

+

Note: + The initial creation of a private paste will prompt for login credentials. + If the login credentials are not known, they will be created automatically. + If it is required to authenticate with other credentials, clear your local + HTTP authentication cache. +

+{% endblock %} +{% block content %} +
+
Navigation
+ +
  • + Create a Private Paste +
  • +
  • + Create a Public Paste +
  • +
    +
    + +{% endblock %} \ No newline at end of file diff --git a/src/httpaste/view/viewport/ui/search.html b/src/httpaste/view/viewport/ui/search.html new file mode 100644 index 0000000..c84ce4d --- /dev/null +++ b/src/httpaste/view/viewport/ui/search.html @@ -0,0 +1,41 @@ +{% extends 'frame/decorated.html' %} + +{% block header %} +

    httpaste - versatile HTTP pastebin

    +

    + This is the user interface of the hosted version of httpaste, + a program which 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 aims for a higher degree of privacy control than available commercial pastebin products. +

    +

    + httpaste features include: +

    +

    +

    + A pseudo man page for CLI usage is available via HTTP GET of this host's root document. + (e.g. `$ curl httpaste.it`) +

    +{% endblock %} + +{% block content %} +
    +
    Navigation
    + +
  • + Paste +
  • +
  • + User +
  • +
    +
    +{% endblock %} \ No newline at end of file diff --git a/src/httpaste/view/viewport/ui/user/search.html b/src/httpaste/view/viewport/ui/user/search.html new file mode 100644 index 0000000..0d2df0f --- /dev/null +++ b/src/httpaste/view/viewport/ui/user/search.html @@ -0,0 +1,16 @@ +{% extends 'frame/decorated.html' %} + +{% block header %} +

    httpaste - User

    +{% endblock %} +{% block content %} +
    +
    Navigation
    + +
  • + Clear Local HTTP Authentication Cache +
  • +
    +
    + +{% endblock %} \ No newline at end of file diff --git a/src/httpaste/views/viewport/ui/user/session/search.html b/src/httpaste/view/viewport/ui/user/session/search.html similarity index 100% rename from src/httpaste/views/viewport/ui/user/session/search.html rename to src/httpaste/view/viewport/ui/user/session/search.html diff --git a/src/httpaste/views/container/get_paste_form.html b/src/httpaste/views/container/get_paste_form.html deleted file mode 100644 index d3f658a..0000000 --- a/src/httpaste/views/container/get_paste_form.html +++ /dev/null @@ -1,26 +0,0 @@ -
    -
    - - - - - - Pygments lexer short name (e.g. 'terraform', 'python') -
    -
    - - - - - Pygments formatter short name (e.g. 'html', 'terminal256') -
    -
    - - - - - Content-Type Header the server should return -
    - - -
    \ No newline at end of file diff --git a/src/httpaste/views/container/post_paste_form.html b/src/httpaste/views/container/post_paste_form.html deleted file mode 100644 index 31ed83c..0000000 --- a/src/httpaste/views/container/post_paste_form.html +++ /dev/null @@ -1,21 +0,0 @@ -
    -
    - - -

    - -
    -
    - Either supply a past text, or upload a file. -
    -
    - - - - - Set a paste’s lifetime to make it expire after a specified amount of time.
    - The lifetime must be provided in minutes and cannot be less than 1
    (, unless lesser than 0).
    - A lifetime of 0 will evaluate to a lifetime 1. -
    - -
    \ No newline at end of file diff --git a/src/httpaste/views/frame/base.html b/src/httpaste/views/frame/base.html deleted file mode 100644 index 8d6a422..0000000 --- a/src/httpaste/views/frame/base.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - -
    - {% block content %}{% endblock %} -
    - - \ No newline at end of file diff --git a/src/httpaste/views/frame/decorated.html b/src/httpaste/views/frame/decorated.html deleted file mode 100644 index 7e13b26..0000000 --- a/src/httpaste/views/frame/decorated.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - -
    - {% block content %}{% endblock %} -
    - - \ No newline at end of file diff --git a/src/httpaste/views/viewport/ui/paste/get.html b/src/httpaste/views/viewport/ui/paste/get.html deleted file mode 100644 index 03a1538..0000000 --- a/src/httpaste/views/viewport/ui/paste/get.html +++ /dev/null @@ -1,27 +0,0 @@ -{% extends 'frame/base.html' %} - -{% block content %} - - Return -

    Paste Conditioner

    - {% if query['preview'] %} - Preview - -
    - {% else %} -

    Preview is disabled. -
    - This probably happened because the paste is set to expire after read. -
    - You can still proceed to condition the paste URL. -

    - {% endif %} - {% include 'container/get_paste_form.html' %} -
    -
    -

    Paste URLs

    - Formatted: {{paste_url}} -
    - Raw: {{raw_paste_url}} -
    -{% endblock %} \ No newline at end of file diff --git a/src/httpaste/views/viewport/ui/paste/private/search.html b/src/httpaste/views/viewport/ui/paste/private/search.html deleted file mode 100644 index 08bce72..0000000 --- a/src/httpaste/views/viewport/ui/paste/private/search.html +++ /dev/null @@ -1,5 +0,0 @@ -{% extends 'frame/base.html' %} - -{% block content %} - {% include 'container/post_paste_form.html' %} -{% endblock %} \ No newline at end of file diff --git a/src/httpaste/views/viewport/ui/paste/public/search.html b/src/httpaste/views/viewport/ui/paste/public/search.html deleted file mode 100644 index 08bce72..0000000 --- a/src/httpaste/views/viewport/ui/paste/public/search.html +++ /dev/null @@ -1,5 +0,0 @@ -{% extends 'frame/base.html' %} - -{% block content %} - {% include 'container/post_paste_form.html' %} -{% endblock %} \ No newline at end of file diff --git a/src/httpaste/views/viewport/ui/paste/search.html b/src/httpaste/views/viewport/ui/paste/search.html deleted file mode 100644 index 17cb192..0000000 --- a/src/httpaste/views/viewport/ui/paste/search.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - -

    - Create a Private Paste -

    -

    - Create a Public Paste -

    -

    - - Flush Local HTTP Authentication Cache - -

    - - \ No newline at end of file diff --git a/src/httpaste/views/viewport/ui/search.html b/src/httpaste/views/viewport/ui/search.html deleted file mode 100644 index ddfe158..0000000 --- a/src/httpaste/views/viewport/ui/search.html +++ /dev/null @@ -1,11 +0,0 @@ -{% extends 'frame/decorated.html' %} - -{% block content %} -
    -
    - httpaste - versatile HTTP pastebin (User Interface) - -
    -
    - -{% endblock %} \ No newline at end of file