mirror of
https://github.com/ziirish/burp-ui.git
synced 2026-05-15 14:16:08 -06:00
some cleanup
This commit is contained in:
parent
94e832b56b
commit
c116626e2a
13 changed files with 36 additions and 101 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -8,6 +8,7 @@ devel.sh
|
|||
.tox
|
||||
.coverage
|
||||
.coveragerc
|
||||
.ropeproject
|
||||
.pylintrc
|
||||
dist
|
||||
_build
|
||||
|
|
|
|||
|
|
@ -27,8 +27,6 @@ def to_unicode(input_bytes, encoding='utf-8'):
|
|||
"""Decodes input_bytes to text if needed."""
|
||||
if not isinstance(input_bytes, string_types):
|
||||
input_bytes = input_bytes.decode(encoding)
|
||||
elif re.match(r'\\u[0-9a-f]{4}', input_bytes):
|
||||
input_bytes = input_bytes.decode('unicode-escape')
|
||||
return input_bytes or ''
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ from flask_login import current_user
|
|||
from importlib import import_module
|
||||
from functools import wraps
|
||||
|
||||
from .custom.namespace import Namespace
|
||||
from .._compat import to_bytes
|
||||
from ..desc import __version__, __release__, __url__, __doc__
|
||||
from ..server import BUIServer # noqa
|
||||
|
|
@ -189,15 +188,6 @@ class Api(ApiPlus):
|
|||
return decorated
|
||||
return decorator
|
||||
|
||||
def namespace(self, *args, **kwargs):
|
||||
"""A namespace factory
|
||||
|
||||
:returns Namespace: a new namespace instance
|
||||
"""
|
||||
ns = Namespace(*args, **kwargs)
|
||||
self.add_namespace(ns)
|
||||
return ns
|
||||
|
||||
|
||||
apibp = Blueprint('api', __name__, url_prefix='/api')
|
||||
api = Api(
|
||||
|
|
@ -217,4 +207,5 @@ def handle_bui_server_exception(error):
|
|||
:param error: Custom exception
|
||||
:type error: :class:`burpui.exceptions.BUIserverException`
|
||||
"""
|
||||
bui.logger.error(error)
|
||||
return {'message': error.description}, error.code
|
||||
|
|
|
|||
|
|
@ -478,7 +478,6 @@ class AsyncRunningBackup(RunningBackup):
|
|||
RunningBackup.running_fields,
|
||||
code=200,
|
||||
description='Success',
|
||||
strict=False
|
||||
)
|
||||
def get(self, server=None):
|
||||
"""Tells if a backup is running right now
|
||||
|
|
@ -570,7 +569,6 @@ class AsyncHistory(History):
|
|||
History.history_fields,
|
||||
code=200,
|
||||
description='Success',
|
||||
strict=False,
|
||||
as_list=True
|
||||
)
|
||||
@ns.expect(History.parser)
|
||||
|
|
@ -650,7 +648,6 @@ class AsyncClientsReport(ClientsReport):
|
|||
ClientsReport.report_fields,
|
||||
code=200,
|
||||
description='Success',
|
||||
strict=False
|
||||
)
|
||||
@ns.expect(ClientsReport.parser)
|
||||
@ns.doc(
|
||||
|
|
|
|||
|
|
@ -12,8 +12,7 @@ import re
|
|||
|
||||
from . import api, cache_key, force_refresh
|
||||
from ..server import BUIServer # noqa
|
||||
from .custom import fields, Resource
|
||||
from .custom.inputs import boolean
|
||||
from .custom import fields, Resource, inputs
|
||||
from ..decorators import browser_cache
|
||||
from ..ext.cache import cache
|
||||
from ..exceptions import BUIserverException
|
||||
|
|
@ -141,7 +140,7 @@ class ClientTree(Resource):
|
|||
)
|
||||
parser.add_argument(
|
||||
'recursive',
|
||||
type=boolean,
|
||||
type=inputs.boolean,
|
||||
help='Returns the whole tree instead of just the sub-tree',
|
||||
nullable=True,
|
||||
required=False,
|
||||
|
|
@ -149,7 +148,7 @@ class ClientTree(Resource):
|
|||
)
|
||||
parser.add_argument(
|
||||
'selected',
|
||||
type=boolean,
|
||||
type=inputs.boolean,
|
||||
help='Make the returned path selected at load time. Only works' +
|
||||
' if \'recursive\' is True',
|
||||
nullable=True,
|
||||
|
|
@ -158,7 +157,7 @@ class ClientTree(Resource):
|
|||
)
|
||||
parser.add_argument(
|
||||
'init',
|
||||
type=boolean,
|
||||
type=inputs.boolean,
|
||||
help='First call to load the root of the tree',
|
||||
nullable=True,
|
||||
required=False,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,11 @@
|
|||
|
||||
|
||||
"""
|
||||
import flask_restplus.fields
|
||||
|
||||
from flask_restplus.fields import * # noqa # pylint: disable=locally-disabled, wildcard-import, unused-wildcard-import
|
||||
from .my_fields import DateTime, DateTimeHuman, BackupNumber, SafeString, LocalizedString, Wildcard # noqa
|
||||
from .my_fields2 import Nested # noqa
|
||||
|
||||
__all__ = flask_restplus.fields.__all__ + \
|
||||
(DateTime, DateTimeHuman, BackupNumber, SafeString, LocalizedString, Wildcard)
|
||||
|
|
|
|||
|
|
@ -8,5 +8,10 @@
|
|||
|
||||
|
||||
"""
|
||||
import inspect
|
||||
import flask_restplus.inputs
|
||||
from flask_restplus.inputs import * # noqa # pylint: disable=locally-disabled, wildcard-import, unused-wildcard-import
|
||||
from .my_inputs import boolean # noqa
|
||||
|
||||
ALL = inspect.getmembers(flask_restplus.inputs, inspect.isfunction)
|
||||
__all__ = [x for x, _ in ALL if not x.startswith('_')] + ['boolean']
|
||||
|
|
|
|||
|
|
@ -8,12 +8,14 @@
|
|||
|
||||
|
||||
"""
|
||||
# Monkey patching flask-restplus to handle our own marshalling/wildcard implementation
|
||||
|
||||
from flask_restplus import fields
|
||||
from .my_marshalling import marshal
|
||||
|
||||
|
||||
class Nested(fields.Nested):
|
||||
def output(self, key, obj, ordered=False):
|
||||
def output(self, key, obj, ordered=False, **kwargs):
|
||||
value = fields.get_value(key if self.attribute is None else self.attribute, obj)
|
||||
if value is None:
|
||||
if self.allow_null:
|
||||
|
|
@ -21,4 +23,4 @@ class Nested(fields.Nested):
|
|||
elif self.default is not None:
|
||||
return self.default
|
||||
|
||||
return marshal(value, self.nested, ordered=ordered)
|
||||
return marshal(value, self.nested, skip_none=self.skip_none, ordered=ordered)
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ def boolean(value):
|
|||
"""
|
||||
try:
|
||||
return boolean_ori(value)
|
||||
except ValueError as e:
|
||||
except ValueError as exp:
|
||||
if not value:
|
||||
return False
|
||||
if value.lower() == 'on':
|
||||
if isinstance(value, str) and value.lower() == 'on':
|
||||
return True
|
||||
raise e
|
||||
raise exp
|
||||
|
|
|
|||
|
|
@ -1,64 +0,0 @@
|
|||
# -*- coding: utf8 -*-
|
||||
"""
|
||||
.. module:: burpui.api.custom.namespace
|
||||
:platform: Unix
|
||||
:synopsis: Burp-UI api custom namespace module.
|
||||
|
||||
.. moduleauthor:: Ziirish <hi+burpui@ziirish.me>
|
||||
|
||||
"""
|
||||
# All of this is creepy hacky since Flask-Resplus seem dead...
|
||||
from functools import wraps
|
||||
from werkzeug.wrappers import Response
|
||||
from flask import Response as FlaskResponse, request, current_app, \
|
||||
has_app_context
|
||||
from flask_restplus import Namespace as NamespacePlus
|
||||
from flask_restplus.utils import unpack, merge
|
||||
from flask_restplus.marshalling import marshal_with as marshal_with_plus
|
||||
|
||||
from .my_marshalling import marshal
|
||||
|
||||
|
||||
class marshal_with(marshal_with_plus):
|
||||
"""Subclass default marshal_with to manage custom API responses"""
|
||||
def __init__(self, fields, envelope=None, mask=None, strict=True):
|
||||
super(marshal_with, self).__init__(fields, envelope, mask)
|
||||
self.strict = strict
|
||||
|
||||
def __call__(self, f):
|
||||
@wraps(f)
|
||||
def wrapper(*args, **kwargs):
|
||||
resp = f(*args, **kwargs)
|
||||
if not self.strict and (isinstance(resp, Response) or
|
||||
isinstance(resp, FlaskResponse)):
|
||||
return resp
|
||||
mask = self.mask
|
||||
if has_app_context():
|
||||
mask_header = current_app.config['RESTPLUS_MASK_HEADER']
|
||||
mask = request.headers.get(mask_header) or mask
|
||||
if isinstance(resp, tuple):
|
||||
data, code, headers = unpack(resp)
|
||||
return marshal(data, self.fields, self.envelope, mask), code, headers
|
||||
else:
|
||||
return marshal(resp, self.fields, self.envelope, mask)
|
||||
return wrapper
|
||||
|
||||
|
||||
class Namespace(NamespacePlus):
|
||||
"""Subclass default Namespace to manage custom API responses"""
|
||||
|
||||
def marshal_with(self, fields, as_list=False, code=200, description=None, strict=True, **kwargs):
|
||||
"""If the decorated function returns a :class:`Flask.Response` object,
|
||||
we don't marshal it
|
||||
"""
|
||||
def wrapper(func):
|
||||
doc = {
|
||||
'responses': {
|
||||
code: (description, [fields]) if as_list else (description, fields)
|
||||
},
|
||||
'__mask__': kwargs.get('mask', True), # Mask values can't be determined outside app context
|
||||
}
|
||||
func.__apidoc__ = merge(getattr(func, '__apidoc__', {}), doc)
|
||||
kwargs['strict'] = strict
|
||||
return marshal_with(fields, **kwargs)(func)
|
||||
return wrapper
|
||||
|
|
@ -12,8 +12,7 @@ import struct
|
|||
|
||||
from . import api
|
||||
from ..server import BUIServer # noqa
|
||||
from .custom import fields, Resource
|
||||
from .custom.inputs import boolean
|
||||
from .custom import fields, Resource, inputs
|
||||
from ..exceptions import BUIserverException
|
||||
|
||||
from zlib import adler32
|
||||
|
|
@ -372,7 +371,7 @@ class DoServerRestore(Resource):
|
|||
parser.add_argument('list-sc', required=True, help='List of files/directories to restore', nullable=False)
|
||||
parser.add_argument('strip-sc', type=int, help='Number of elements to strip in the path', default=0, nullable=True)
|
||||
parser.add_argument('prefix-sc', help='Prefix to the restore path', nullable=True)
|
||||
parser.add_argument('force-sc', type=boolean, help='Whether to overwrite existing files', default=False, nullable=True)
|
||||
parser.add_argument('force-sc', type=inputs.boolean, help='Whether to overwrite existing files', default=False, nullable=True)
|
||||
parser.add_argument('restoreto-sc', help='Restore files on an other client', nullable=True)
|
||||
|
||||
@api.disabled_on_demo()
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@
|
|||
from . import api
|
||||
from ..server import BUIServer # noqa
|
||||
from ..ext.cache import cache
|
||||
from .custom import Resource
|
||||
from .custom.inputs import boolean
|
||||
from .custom import Resource, inputs
|
||||
from .._compat import unquote
|
||||
from ..utils import NOTIF_INFO
|
||||
|
||||
|
|
@ -476,14 +475,14 @@ class NewClientSettings(Resource):
|
|||
)
|
||||
class ClientSettings(Resource):
|
||||
parser_delete = ns.parser()
|
||||
parser_delete.add_argument('revoke', type=boolean, help='Whether to revoke the certificate or not', default=False, nullable=True)
|
||||
parser_delete.add_argument('delcert', type=boolean, help='Whether to delete the certificate or not', default=False, nullable=True)
|
||||
parser_delete.add_argument('keepconf', type=boolean, help='Whether to keep the conf or not', default=False, nullable=True)
|
||||
parser_delete.add_argument('template', type=boolean, help='Whether we work on a template or not', default=False, nullable=True)
|
||||
parser_delete.add_argument('revoke', type=inputs.boolean, help='Whether to revoke the certificate or not', default=False, nullable=True)
|
||||
parser_delete.add_argument('delcert', type=inputs.boolean, help='Whether to delete the certificate or not', default=False, nullable=True)
|
||||
parser_delete.add_argument('keepconf', type=inputs.boolean, help='Whether to keep the conf or not', default=False, nullable=True)
|
||||
parser_delete.add_argument('template', type=inputs.boolean, help='Whether we work on a template or not', default=False, nullable=True)
|
||||
parser_post = ns.parser()
|
||||
parser_post.add_argument('template', type=boolean, help='Whether we work on a template or not', default=False, nullable=True)
|
||||
parser_post.add_argument('template', type=inputs.boolean, help='Whether we work on a template or not', default=False, nullable=True)
|
||||
parser_get = ns.parser()
|
||||
parser_get.add_argument('template', type=boolean, help='Whether we work on a template or not', default=False, nullable=True)
|
||||
parser_get.add_argument('template', type=inputs.boolean, help='Whether we work on a template or not', default=False, nullable=True)
|
||||
|
||||
@api.disabled_on_demo()
|
||||
@api.acl_admin_or_moderator_required(message=_('Sorry, you don\'t have rights to access the setting panel'))
|
||||
|
|
|
|||
|
|
@ -213,7 +213,10 @@ class BUIServer(Flask):
|
|||
)
|
||||
self.format_labels = []
|
||||
for format_label in format_labels:
|
||||
search = re.search(r'^s(?P<separator>.)(?P<regex>.*?)(?P=separator)(?P<replace>.*?)(?P=separator)$', format_label)
|
||||
search = re.search(
|
||||
r'^s(?P<separator>.)(?P<regex>.*?)(?P=separator)(?P<replace>.*?)(?P=separator)$',
|
||||
format_label
|
||||
)
|
||||
if search:
|
||||
self.format_labels.append((search.group('regex'), search.group('replace')))
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue